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 21using blink::WebURL; 22 23namespace content { 24 25WebServiceWorkerProviderImpl::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 33WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() { 34 // Make sure the script client is removed. 35 RemoveScriptClient(); 36} 37 38void 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 82void 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 90void WebServiceWorkerProviderImpl::unregisterServiceWorker( 91 const WebURL& pattern, 92 WebServiceWorkerUnregistrationCallbacks* callbacks) { 93 GetDispatcher()->UnregisterServiceWorker( 94 provider_id_, pattern, callbacks); 95} 96 97void WebServiceWorkerProviderImpl::getRegistration( 98 const blink::WebURL& document_url, 99 WebServiceWorkerRegistrationCallbacks* callbacks) { 100 GetDispatcher()->GetRegistration(provider_id_, document_url, callbacks); 101} 102 103void 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 112ServiceWorkerDispatcher* WebServiceWorkerProviderImpl::GetDispatcher() { 113 return ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( 114 thread_safe_sender_.get()); 115} 116 117} // namespace content 118