Home | History | Annotate | Download | only in service_worker
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/child/service_worker/web_service_worker_provider_impl.h"
      6 
      7 #include "base/atomic_sequence_num.h"
      8 #include "base/logging.h"
      9 #include "content/child/child_thread.h"
     10 #include "content/child/service_worker/service_worker_dispatcher.h"
     11 #include "content/child/service_worker/service_worker_handle_reference.h"
     12 #include "content/child/service_worker/service_worker_provider_context.h"
     13 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
     14 #include "content/child/service_worker/web_service_worker_impl.h"
     15 #include "content/child/service_worker/web_service_worker_registration_impl.h"
     16 #include "content/child/thread_safe_sender.h"
     17 #include "content/common/service_worker/service_worker_messages.h"
     18 #include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
     19 #include "third_party/WebKit/public/platform/WebURL.h"
     20 
     21 using blink::WebURL;
     22 
     23 namespace content {
     24 
     25 WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl(
     26     ThreadSafeSender* thread_safe_sender,
     27     ServiceWorkerProviderContext* context)
     28     : thread_safe_sender_(thread_safe_sender),
     29       context_(context),
     30       provider_id_(context->provider_id()) {
     31 }
     32 
     33 WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() {
     34   // Make sure the script client is removed.
     35   RemoveScriptClient();
     36 }
     37 
     38 void WebServiceWorkerProviderImpl::setClient(
     39     blink::WebServiceWorkerProviderClient* client) {
     40   if (!client) {
     41     RemoveScriptClient();
     42     return;
     43   }
     44 
     45   // TODO(kinuko): Here we could also register the current thread ID
     46   // on the provider context so that multiple WebServiceWorkerProviderImpl
     47   // (e.g. on document and on dedicated workers) can properly share
     48   // the single provider context across threads. (http://crbug.com/366538
     49   // for more context)
     50   GetDispatcher()->AddScriptClient(provider_id_, client);
     51 
     52   if (!context_->registration()) {
     53     // This provider is not associated with any registration.
     54     return;
     55   }
     56 
     57   // Set .ready if the associated registration has the active service worker.
     58   if (context_->active_handle_id() != kInvalidServiceWorkerHandleId) {
     59     WebServiceWorkerRegistrationImpl* registration =
     60         GetDispatcher()->FindServiceWorkerRegistration(
     61             context_->registration()->info(), false);
     62     if (!registration) {
     63       registration = GetDispatcher()->CreateServiceWorkerRegistration(
     64           context_->registration()->info(), false);
     65       ServiceWorkerVersionAttributes attrs = context_->GetVersionAttributes();
     66       registration->SetInstalling(
     67           GetDispatcher()->GetServiceWorker(attrs.installing, false));
     68       registration->SetWaiting(
     69           GetDispatcher()->GetServiceWorker(attrs.waiting, false));
     70       registration->SetActive(
     71           GetDispatcher()->GetServiceWorker(attrs.active, false));
     72     }
     73     client->setReadyRegistration(registration);
     74   }
     75 
     76   if (context_->controller_handle_id() != kInvalidServiceWorkerHandleId) {
     77     client->setController(GetDispatcher()->GetServiceWorker(
     78         context_->controller()->info(), false));
     79   }
     80 }
     81 
     82 void WebServiceWorkerProviderImpl::registerServiceWorker(
     83     const WebURL& pattern,
     84     const WebURL& script_url,
     85     WebServiceWorkerRegistrationCallbacks* callbacks) {
     86   GetDispatcher()->RegisterServiceWorker(
     87       provider_id_, pattern, script_url, callbacks);
     88 }
     89 
     90 void WebServiceWorkerProviderImpl::unregisterServiceWorker(
     91     const WebURL& pattern,
     92     WebServiceWorkerUnregistrationCallbacks* callbacks) {
     93   GetDispatcher()->UnregisterServiceWorker(
     94       provider_id_, pattern, callbacks);
     95 }
     96 
     97 void WebServiceWorkerProviderImpl::getRegistration(
     98     const blink::WebURL& document_url,
     99     WebServiceWorkerRegistrationCallbacks* callbacks) {
    100   GetDispatcher()->GetRegistration(provider_id_, document_url, callbacks);
    101 }
    102 
    103 void WebServiceWorkerProviderImpl::RemoveScriptClient() {
    104   // Remove the script client, but only if the dispatcher is still there.
    105   // (For cleanup path we don't need to bother creating a new dispatcher)
    106   ServiceWorkerDispatcher* dispatcher =
    107       ServiceWorkerDispatcher::GetThreadSpecificInstance();
    108   if (dispatcher)
    109     dispatcher->RemoveScriptClient(provider_id_);
    110 }
    111 
    112 ServiceWorkerDispatcher* WebServiceWorkerProviderImpl::GetDispatcher() {
    113   return ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
    114       thread_safe_sender_.get());
    115 }
    116 
    117 }  // namespace content
    118