11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/child/service_worker/service_worker_dispatcher.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/lazy_instance.h"
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/stl_util.h"
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/threading/thread_local.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_thread.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_handle_reference.h"
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_provider_context.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/child/service_worker/service_worker_registration_handle_reference.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/child/service_worker/web_service_worker_impl.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/service_worker/web_service_worker_registration_impl.h"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/child/thread_safe_sender.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/webmessageportchannel_impl.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/service_worker/service_worker_messages.h"
206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "content/public/common/url_utils.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebServiceWorkerError;
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebServiceWorkerProvider;
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using base::ThreadLocalPointer;
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace content {
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::LazyInstance<ThreadLocalPointer<ServiceWorkerDispatcher> >::Leaky
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ServiceWorkerDispatcher* const kHasBeenDeleted =
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    reinterpret_cast<ServiceWorkerDispatcher*>(0x1);
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int CurrentWorkerId() {
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return WorkerTaskRunner::Instance()->CurrentWorkerId();
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ServiceWorkerDispatcher::ServiceWorkerDispatcher(
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ThreadSafeSender* thread_safe_sender)
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : thread_safe_sender_(thread_safe_sender) {
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  g_dispatcher_tls.Pointer()->Set(this);
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool handled = true;
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg)
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnAssociateRegistration)
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DisassociateRegistration,
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnDisassociateRegistration)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered)
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        OnUnregistered)
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistration,
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnDidGetRegistration)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError,
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        OnRegistrationError)
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistrationError,
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnUnregistrationError)
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerGetRegistrationError,
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnGetRegistrationError)
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        OnServiceWorkerStateChanged)
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes,
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        OnSetVersionAttributes)
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound,
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnUpdateFound)
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        OnSetControllerServiceWorker)
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                        OnPostMessage)
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(handled) << "Unhandled message:" << msg.type();
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ServiceWorkerDispatcher::Send(IPC::Message* msg) {
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return thread_safe_sender_->Send(msg);
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ServiceWorkerDispatcher::RegisterServiceWorker(
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int provider_id,
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& pattern,
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& script_url,
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebServiceWorkerRegistrationCallbacks* callbacks) {
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (pattern.possibly_invalid_spec().size() > GetMaxURLChars() ||
996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      script_url.possibly_invalid_spec().size() > GetMaxURLChars()) {
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<WebServiceWorkerRegistrationCallbacks>
1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        owned_callbacks(callbacks);
1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<WebServiceWorkerError> error(new WebServiceWorkerError(
1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        WebServiceWorkerError::ErrorTypeSecurity, "URL too long"));
1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    callbacks->onError(error.release());
1056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
1066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int request_id = pending_registration_callbacks_.Add(callbacks);
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "ServiceWorkerDispatcher::RegisterServiceWorker",
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           request_id,
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "Scope", pattern.spec(),
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "Script URL", script_url.spec());
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  thread_safe_sender_->Send(new ServiceWorkerHostMsg_RegisterServiceWorker(
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      CurrentWorkerId(), request_id, provider_id, pattern, script_url));
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ServiceWorkerDispatcher::UnregisterServiceWorker(
119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int provider_id,
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& pattern,
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebServiceWorkerUnregistrationCallbacks* callbacks) {
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (pattern.possibly_invalid_spec().size() > GetMaxURLChars()) {
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<WebServiceWorkerUnregistrationCallbacks>
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        owned_callbacks(callbacks);
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<WebServiceWorkerError> error(new WebServiceWorkerError(
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        WebServiceWorkerError::ErrorTypeSecurity, "URL too long"));
1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    callbacks->onError(error.release());
1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int request_id = pending_unregistration_callbacks_.Add(callbacks);
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "ServiceWorkerDispatcher::UnregisterServiceWorker",
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           request_id,
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "Scope", pattern.spec());
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker(
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      CurrentWorkerId(), request_id, provider_id, pattern));
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::GetRegistration(
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int provider_id,
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& document_url,
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebServiceWorkerRegistrationCallbacks* callbacks) {
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(callbacks);
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (document_url.possibly_invalid_spec().size() > GetMaxURLChars()) {
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<WebServiceWorkerRegistrationCallbacks>
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        owned_callbacks(callbacks);
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<WebServiceWorkerError> error(new WebServiceWorkerError(
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebServiceWorkerError::ErrorTypeSecurity, "URL too long"));
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callbacks->onError(error.release());
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int request_id = pending_get_registration_callbacks_.Add(callbacks);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "ServiceWorkerDispatcher::GetRegistration",
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           request_id,
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "Document URL", document_url.spec());
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistration(
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CurrentWorkerId(), request_id, provider_id, document_url));
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerDispatcher::AddProviderContext(
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerProviderContext* provider_context) {
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(provider_context);
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int provider_id = provider_context->provider_id();
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(!ContainsKey(provider_contexts_, provider_id));
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  provider_contexts_[provider_id] = provider_context;
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerDispatcher::RemoveProviderContext(
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerProviderContext* provider_context) {
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(provider_context);
177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ContainsKey(provider_contexts_, provider_context->provider_id()));
178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  provider_contexts_.erase(provider_context->provider_id());
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  worker_to_provider_.erase(provider_context->installing_handle_id());
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  worker_to_provider_.erase(provider_context->waiting_handle_id());
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  worker_to_provider_.erase(provider_context->active_handle_id());
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  worker_to_provider_.erase(provider_context->controller_handle_id());
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerDispatcher::AddScriptClient(
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int provider_id,
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebServiceWorkerProviderClient* client) {
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(client);
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!ContainsKey(script_clients_, provider_id));
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  script_clients_[provider_id] = client;
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerDispatcher::RemoveScriptClient(int provider_id) {
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This could be possibly called multiple times to ensure termination.
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (ContainsKey(script_clients_, provider_id))
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    script_clients_.erase(provider_id);
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
199a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochServiceWorkerDispatcher*
200a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ThreadSafeSender* thread_safe_sender) {
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    g_dispatcher_tls.Pointer()->Set(NULL);
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (g_dispatcher_tls.Pointer()->Get())
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return g_dispatcher_tls.Pointer()->Get();
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ServiceWorkerDispatcher* dispatcher =
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new ServiceWorkerDispatcher(thread_safe_sender);
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (WorkerTaskRunner::Instance()->CurrentWorkerId())
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return dispatcher;
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
216a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return NULL;
219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return g_dispatcher_tls.Pointer()->Get();
220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::OnWorkerRunLoopStopped() {
223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  delete this;
224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker(
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const ServiceWorkerObjectInfo& info,
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool adopt_handle) {
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (info.handle_id == kInvalidServiceWorkerHandleId)
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return NULL;
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WorkerObjectMap::iterator existing_worker =
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      service_workers_.find(info.handle_id);
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (existing_worker != service_workers_.end()) {
23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (adopt_handle) {
23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // We are instructed to adopt a handle but we already have one, so
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // adopt and destroy a handle ref.
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return existing_worker->second;
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<ServiceWorkerHandleReference> handle_ref =
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      adopt_handle
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ? ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get())
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          : ServiceWorkerHandleReference::Create(info,
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 thread_safe_sender_.get());
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // WebServiceWorkerImpl constructor calls AddServiceWorker.
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return new WebServiceWorkerImpl(handle_ref.Pass(), thread_safe_sender_.get());
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)WebServiceWorkerRegistrationImpl*
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServiceWorkerDispatcher::FindServiceWorkerRegistration(
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const ServiceWorkerRegistrationObjectInfo& info,
2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    bool adopt_handle) {
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RegistrationObjectMap::iterator registration =
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      registrations_.find(info.handle_id);
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (registration == registrations_.end())
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (adopt_handle) {
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // We are instructed to adopt a handle but we already have one, so
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // adopt and destroy a handle ref.
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServiceWorkerRegistrationHandleReference::Adopt(
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        info, thread_safe_sender_.get());
2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return registration->second;
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebServiceWorkerRegistrationImpl*
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServiceWorkerDispatcher::CreateServiceWorkerRegistration(
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerRegistrationObjectInfo& info,
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool adopt_handle) {
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!FindServiceWorkerRegistration(info, adopt_handle));
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (info.handle_id == kInvalidServiceWorkerRegistrationHandleId)
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
2776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref =
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      adopt_handle ? ServiceWorkerRegistrationHandleReference::Adopt(
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         info, thread_safe_sender_.get())
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   : ServiceWorkerRegistrationHandleReference::Create(
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         info, thread_safe_sender_.get());
2836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // WebServiceWorkerRegistrationImpl constructor calls
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // AddServiceWorkerRegistration.
2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return new WebServiceWorkerRegistrationImpl(handle_ref.Pass());
2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnAssociateRegistration(
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int thread_id,
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int provider_id,
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerRegistrationObjectInfo& info,
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerVersionAttributes& attrs) {
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (provider == provider_contexts_.end())
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  provider->second->OnAssociateRegistration(info, attrs);
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (attrs.installing.handle_id != kInvalidServiceWorkerHandleId)
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    worker_to_provider_[attrs.installing.handle_id] = provider->second;
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (attrs.waiting.handle_id != kInvalidServiceWorkerHandleId)
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    worker_to_provider_[attrs.waiting.handle_id] = provider->second;
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (attrs.active.handle_id != kInvalidServiceWorkerHandleId)
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    worker_to_provider_[attrs.active.handle_id] = provider->second;
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnDisassociateRegistration(
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int thread_id,
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int provider_id) {
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (provider == provider_contexts_.end())
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  provider->second->OnDisassociateRegistration();
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  worker_to_provider_.erase(provider->second->installing_handle_id());
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  worker_to_provider_.erase(provider->second->waiting_handle_id());
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  worker_to_provider_.erase(provider->second->active_handle_id());
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  worker_to_provider_.erase(provider->second->controller_handle_id());
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
319a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::OnRegistered(
320a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int thread_id,
321a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int request_id,
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerRegistrationObjectInfo& info,
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerVersionAttributes& attrs) {
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerDispatcher::RegisterServiceWorker",
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               request_id,
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "OnRegistered");
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerDispatcher::RegisterServiceWorker",
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         request_id);
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebServiceWorkerRegistrationCallbacks* callbacks =
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_registration_callbacks_.Lookup(request_id);
3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!callbacks)
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callbacks->onSuccess(FindOrCreateRegistration(info, attrs));
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_registration_callbacks_.Remove(request_id);
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnUnregistered(int thread_id,
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             int request_id,
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             bool is_success) {
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0(
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorker",
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorkerDispatcher::UnregisterServiceWorker",
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_id,
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "OnUnregistered");
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerDispatcher::UnregisterServiceWorker",
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         request_id);
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebServiceWorkerUnregistrationCallbacks* callbacks =
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_unregistration_callbacks_.Lookup(request_id);
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(callbacks);
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!callbacks)
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callbacks->onSuccess(&is_success);
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_unregistration_callbacks_.Remove(request_id);
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnDidGetRegistration(
362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int thread_id,
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int request_id,
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerRegistrationObjectInfo& info,
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerVersionAttributes& attrs) {
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0(
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorker",
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorkerDispatcher::GetRegistration",
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_id,
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "OnDidGetRegistration");
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerDispatcher::GetRegistration",
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         request_id);
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebServiceWorkerRegistrationCallbacks* callbacks =
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_get_registration_callbacks_.Lookup(request_id);
3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!callbacks)
3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebServiceWorkerRegistrationImpl* registration = NULL;
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (info.handle_id != kInvalidServiceWorkerHandleId)
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration = FindOrCreateRegistration(info, attrs);
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callbacks->onSuccess(registration);
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_get_registration_callbacks_.Remove(request_id);
3861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ServiceWorkerDispatcher::OnRegistrationError(
389a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int thread_id,
390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int request_id,
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WebServiceWorkerError::ErrorType error_type,
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message) {
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerDispatcher::RegisterServiceWorker",
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               request_id,
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "OnRegistrationError");
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerDispatcher::RegisterServiceWorker",
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         request_id);
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebServiceWorkerRegistrationCallbacks* callbacks =
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_registration_callbacks_.Lookup(request_id);
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(callbacks);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!callbacks)
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<WebServiceWorkerError> error(
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new WebServiceWorkerError(error_type, message));
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  callbacks->onError(error.release());
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_registration_callbacks_.Remove(request_id);
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnUnregistrationError(
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int thread_id,
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int request_id,
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebServiceWorkerError::ErrorType error_type,
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::string16& message) {
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0(
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorker",
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorkerDispatcher::UnregisterServiceWorker",
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_id,
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "OnUnregistrationError");
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerDispatcher::UnregisterServiceWorker",
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         request_id);
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebServiceWorkerUnregistrationCallbacks* callbacks =
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_unregistration_callbacks_.Lookup(request_id);
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(callbacks);
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!callbacks)
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<WebServiceWorkerError> error(
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new WebServiceWorkerError(error_type, message));
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callbacks->onError(error.release());
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_unregistration_callbacks_.Remove(request_id);
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnGetRegistrationError(
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int thread_id,
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int request_id,
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebServiceWorkerError::ErrorType error_type,
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::string16& message) {
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0(
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorker",
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorkerDispatcher::GetRegistration",
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_id,
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "OnGetRegistrationError");
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerDispatcher::GetRegistration",
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         request_id);
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebServiceWorkerGetRegistrationCallbacks* callbacks =
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_get_registration_callbacks_.Lookup(request_id);
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(callbacks);
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!callbacks)
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<WebServiceWorkerError> error(
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new WebServiceWorkerError(error_type, message));
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callbacks->onError(error.release());
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_get_registration_callbacks_.Remove(request_id);
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
462a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int thread_id,
464a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int handle_id,
465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    blink::WebServiceWorkerState state) {
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT2("ServiceWorker",
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerDispatcher::OnServiceWorkerStateChanged",
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Thread ID", thread_id,
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "State", state);
470010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WorkerObjectMap::iterator worker = service_workers_.find(handle_id);
471010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (worker != service_workers_.end())
472010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    worker->second->OnStateChanged(state);
473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WorkerToProviderMap::iterator provider = worker_to_provider_.find(handle_id);
475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (provider != worker_to_provider_.end())
476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    provider->second->OnServiceWorkerStateChanged(handle_id, state);
477a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
4796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerDispatcher::OnSetVersionAttributes(
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int thread_id,
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int provider_id,
4826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int registration_handle_id,
4836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int changed_mask,
4846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const ServiceWorkerVersionAttributes& attributes) {
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("ServiceWorker",
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerDispatcher::OnSetVersionAttributes",
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Thread ID", thread_id);
4886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ChangedVersionAttributesMask mask(changed_mask);
4896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (mask.installing_changed()) {
4906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SetInstallingServiceWorker(provider_id,
4916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               registration_handle_id,
4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               attributes.installing);
4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (mask.waiting_changed()) {
4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SetWaitingServiceWorker(provider_id,
4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                            registration_handle_id,
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                            attributes.waiting);
4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
4996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (mask.active_changed()) {
5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SetActiveServiceWorker(provider_id,
5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           registration_handle_id,
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           attributes.active);
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetReadyRegistration(provider_id, registration_handle_id);
5046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
5056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::OnUpdateFound(
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int thread_id,
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerRegistrationObjectInfo& info) {
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerDispatcher::OnUpdateFound");
5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RegistrationObjectMap::iterator found = registrations_.find(info.handle_id);
5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (found != registrations_.end())
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    found->second->OnUpdateFound();
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerDispatcher::SetInstallingServiceWorker(
5186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int provider_id,
5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int registration_handle_id,
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ServiceWorkerObjectInfo& info) {
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (provider != provider_contexts_.end() &&
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      provider->second->registration_handle_id() == registration_handle_id) {
524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int existing_installing_id = provider->second->installing_handle_id();
525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (existing_installing_id != info.handle_id &&
526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        existing_installing_id != kInvalidServiceWorkerHandleId) {
527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      WorkerToProviderMap::iterator associated_provider =
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          worker_to_provider_.find(existing_installing_id);
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(associated_provider != worker_to_provider_.end());
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(associated_provider->second->provider_id() == provider_id);
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      worker_to_provider_.erase(associated_provider);
532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    provider->second->OnSetInstallingServiceWorker(
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        registration_handle_id, info);
535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (info.handle_id != kInvalidServiceWorkerHandleId)
536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      worker_to_provider_[info.handle_id] = provider->second;
537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RegistrationObjectMap::iterator found =
5406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      registrations_.find(registration_handle_id);
5416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (found != registrations_.end()) {
54203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Populate the .installing field with the new worker object.
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    found->second->SetInstalling(GetServiceWorker(info, false));
5446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
545116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerDispatcher::SetWaitingServiceWorker(
548f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int provider_id,
5496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int registration_handle_id,
550f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ServiceWorkerObjectInfo& info) {
551f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (provider != provider_contexts_.end() &&
5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      provider->second->registration_handle_id() == registration_handle_id) {
554f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int existing_waiting_id = provider->second->waiting_handle_id();
555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (existing_waiting_id != info.handle_id &&
556f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        existing_waiting_id != kInvalidServiceWorkerHandleId) {
557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WorkerToProviderMap::iterator associated_provider =
558f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          worker_to_provider_.find(existing_waiting_id);
559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK(associated_provider != worker_to_provider_.end());
560f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK(associated_provider->second->provider_id() == provider_id);
561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      worker_to_provider_.erase(associated_provider);
562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    provider->second->OnSetWaitingServiceWorker(registration_handle_id, info);
564f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (info.handle_id != kInvalidServiceWorkerHandleId)
565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      worker_to_provider_[info.handle_id] = provider->second;
566f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
567f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RegistrationObjectMap::iterator found =
5696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      registrations_.find(registration_handle_id);
57003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (found != registrations_.end()) {
57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Populate the .waiting field with the new worker object.
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    found->second->SetWaiting(GetServiceWorker(info, false));
57303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerDispatcher::SetActiveServiceWorker(
577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int provider_id,
5786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int registration_handle_id,
579116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ServiceWorkerObjectInfo& info) {
580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (provider != provider_contexts_.end() &&
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      provider->second->registration_handle_id() == registration_handle_id) {
583116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int existing_active_id = provider->second->active_handle_id();
584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (existing_active_id != info.handle_id &&
585116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        existing_active_id != kInvalidServiceWorkerHandleId) {
586116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      WorkerToProviderMap::iterator associated_provider =
587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          worker_to_provider_.find(existing_active_id);
588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(associated_provider != worker_to_provider_.end());
589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(associated_provider->second->provider_id() == provider_id);
590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      worker_to_provider_.erase(associated_provider);
591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    provider->second->OnSetActiveServiceWorker(registration_handle_id, info);
593116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (info.handle_id != kInvalidServiceWorkerHandleId)
594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      worker_to_provider_[info.handle_id] = provider->second;
595116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
596116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RegistrationObjectMap::iterator found =
5986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      registrations_.find(registration_handle_id);
59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (found != registrations_.end()) {
60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Populate the .active field with the new worker object.
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    found->second->SetActive(GetServiceWorker(info, false));
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerDispatcher::SetReadyRegistration(
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int provider_id,
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int registration_handle_id) {
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (provider == provider_contexts_.end() ||
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      provider->second->registration_handle_id() != registration_handle_id ||
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      provider->second->active_handle_id() == kInvalidServiceWorkerHandleId) {
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScriptClientMap::iterator client = script_clients_.find(provider_id);
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (client == script_clients_.end())
6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ServiceWorkerRegistrationObjectInfo info =
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      provider->second->registration()->info();
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebServiceWorkerRegistrationImpl* registration =
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FindServiceWorkerRegistration(info, false);
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!registration) {
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration = CreateServiceWorkerRegistration(info, false);
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServiceWorkerVersionAttributes attrs =
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        provider->second->GetVersionAttributes();
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetInstalling(GetServiceWorker(attrs.installing, false));
6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetWaiting(GetServiceWorker(attrs.waiting, false));
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetActive(GetServiceWorker(attrs.active, false));
63003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Resolve the .ready promise with the registration object.
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client->second->setReadyRegistration(registration);
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
636116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerDispatcher::OnSetControllerServiceWorker(
6370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int thread_id,
6380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int provider_id,
6390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerObjectInfo& info) {
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT2("ServiceWorker",
6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerDispatcher::OnSetControllerServiceWorker",
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Thread ID", thread_id,
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Provider ID", provider_id);
644010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
645010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (provider != provider_contexts_.end()) {
6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    provider->second->OnSetControllerServiceWorker(
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        provider->second->registration_handle_id(), info);
648010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    worker_to_provider_[info.handle_id] = provider->second;
649010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
650010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
651010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ScriptClientMap::iterator found = script_clients_.find(provider_id);
652010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (found != script_clients_.end()) {
653f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Populate the .controller field with the new worker object.
654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    found->second->setController(GetServiceWorker(info, false));
655010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
656010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
657010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
658010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerDispatcher::OnPostMessage(
659010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int thread_id,
660010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int provider_id,
661010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::string16& message,
662010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int>& sent_message_port_ids,
663010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int>& new_routing_ids) {
664010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Make sure we're on the main document thread. (That must be the only
665010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // thread we get this message)
666010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ChildThread::current());
6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("ServiceWorker",
6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerDispatcher::OnPostMessage",
6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Thread ID", thread_id);
670010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
6710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScriptClientMap::iterator found = script_clients_.find(provider_id);
6720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == script_clients_.end()) {
673010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // For now we do no queueing for messages sent to nonexistent / unattached
674010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // client.
6750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
6760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
677010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
678010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<WebMessagePortChannelImpl*> ports;
679010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!sent_message_port_ids.empty()) {
680010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ports.resize(sent_message_port_ids.size());
681010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
682010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ports[i] = new WebMessagePortChannelImpl(
683010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          new_routing_ids[i], sent_message_port_ids[i],
684010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::MessageLoopProxy::current());
685010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
686010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
687010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
688010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  found->second->dispatchMessageEvent(message, ports);
6890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
691a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::AddServiceWorker(
692a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int handle_id, WebServiceWorkerImpl* worker) {
693a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!ContainsKey(service_workers_, handle_id));
694a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  service_workers_[handle_id] = worker;
695a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
696a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
697a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) {
698a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(ContainsKey(service_workers_, handle_id));
699a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  service_workers_.erase(handle_id);
700a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerDispatcher::AddServiceWorkerRegistration(
7036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int registration_handle_id,
7046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    WebServiceWorkerRegistrationImpl* registration) {
7056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!ContainsKey(registrations_, registration_handle_id));
7066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registrations_[registration_handle_id] = registration;
7076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
7086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
7106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int registration_handle_id) {
7116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(ContainsKey(registrations_, registration_handle_id));
7126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registrations_.erase(registration_handle_id);
7136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
7146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebServiceWorkerRegistrationImpl*
7161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServiceWorkerDispatcher::FindOrCreateRegistration(
7171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerRegistrationObjectInfo& info,
7181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ServiceWorkerVersionAttributes& attrs) {
7191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebServiceWorkerRegistrationImpl* registration =
7201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FindServiceWorkerRegistration(info, true);
7211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!registration) {
7221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration = CreateServiceWorkerRegistration(info, true);
7231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetInstalling(GetServiceWorker(attrs.installing, true));
7241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetWaiting(GetServiceWorker(attrs.waiting, true));
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetActive(GetServiceWorker(attrs.active, true));
7261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
7271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // |registration| must already have version attributes, so adopt and destroy
7281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // handle refs for them.
7291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServiceWorkerHandleReference::Adopt(
7301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        attrs.installing, thread_safe_sender_.get());
7311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServiceWorkerHandleReference::Adopt(
7321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        attrs.waiting, thread_safe_sender_.get());
7331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServiceWorkerHandleReference::Adopt(
7341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        attrs.active, thread_safe_sender_.get());
7351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
7361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return registration;
7371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
7381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
7391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace content
740