service_worker_dispatcher.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/lazy_instance.h"
8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/stl_util.h"
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/threading/thread_local.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_thread.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_handle_reference.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/service_worker/service_worker_provider_context.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/child/service_worker/web_service_worker_impl.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/child/thread_safe_sender.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/webmessageportchannel_impl.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/service_worker/service_worker_messages.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebServiceWorkerError;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebServiceWorkerProvider;
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using base::ThreadLocalPointer;
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace content {
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::LazyInstance<ThreadLocalPointer<ServiceWorkerDispatcher> >::Leaky
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ServiceWorkerDispatcher* const kHasBeenDeleted =
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    reinterpret_cast<ServiceWorkerDispatcher*>(0x1);
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int CurrentWorkerId() {
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return WorkerTaskRunner::Instance()->CurrentWorkerId();
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ServiceWorkerDispatcher::ServiceWorkerDispatcher(
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ThreadSafeSender* thread_safe_sender)
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : thread_safe_sender_(thread_safe_sender) {
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  g_dispatcher_tls.Pointer()->Set(this);
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool handled = true;
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered)
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered,
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        OnUnregistered)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError,
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        OnRegistrationError)
58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        OnServiceWorkerStateChanged)
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetWaitingServiceWorker,
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        OnSetWaitingServiceWorker)
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                        OnSetCurrentServiceWorker)
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                        OnPostMessage)
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(handled) << "Unhandled message:" << msg.type();
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ServiceWorkerDispatcher::Send(IPC::Message* msg) {
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return thread_safe_sender_->Send(msg);
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ServiceWorkerDispatcher::RegisterServiceWorker(
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int provider_id,
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& pattern,
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& script_url,
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks) {
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int request_id = pending_callbacks_.Add(callbacks);
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  thread_safe_sender_->Send(new ServiceWorkerHostMsg_RegisterServiceWorker(
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      CurrentWorkerId(), request_id, provider_id, pattern, script_url));
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ServiceWorkerDispatcher::UnregisterServiceWorker(
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int provider_id,
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& pattern,
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks) {
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int request_id = pending_callbacks_.Add(callbacks);
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker(
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      CurrentWorkerId(), request_id, provider_id, pattern));
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerDispatcher::AddProviderContext(
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerProviderContext* provider_context) {
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(provider_context);
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int provider_id = provider_context->provider_id();
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(!ContainsKey(provider_contexts_, provider_id));
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  provider_contexts_[provider_id] = provider_context;
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerDispatcher::RemoveProviderContext(
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerProviderContext* provider_context) {
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(provider_context);
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ContainsKey(provider_contexts_, provider_context->provider_id()));
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  provider_contexts_.erase(provider_context->provider_id());
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  worker_to_provider_.erase(provider_context->waiting_handle_id());
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  worker_to_provider_.erase(provider_context->current_handle_id());
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerDispatcher::AddScriptClient(
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int provider_id,
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebServiceWorkerProviderClient* client) {
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(client);
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!ContainsKey(script_clients_, provider_id));
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  script_clients_[provider_id] = client;
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerDispatcher::RemoveScriptClient(int provider_id) {
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This could be possibly called multiple times to ensure termination.
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (ContainsKey(script_clients_, provider_id))
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    script_clients_.erase(provider_id);
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
127a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochServiceWorkerDispatcher*
128a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ThreadSafeSender* thread_safe_sender) {
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    g_dispatcher_tls.Pointer()->Set(NULL);
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (g_dispatcher_tls.Pointer()->Get())
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return g_dispatcher_tls.Pointer()->Get();
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ServiceWorkerDispatcher* dispatcher =
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new ServiceWorkerDispatcher(thread_safe_sender);
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (WorkerTaskRunner::Instance()->CurrentWorkerId())
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return dispatcher;
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
144a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return NULL;
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return g_dispatcher_tls.Pointer()->Get();
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::OnWorkerRunLoopStopped() {
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  delete this;
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker(
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const ServiceWorkerObjectInfo& info,
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool adopt_handle) {
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (info.handle_id == kInvalidServiceWorkerHandleId)
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return NULL;
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WorkerObjectMap::iterator existing_worker =
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      service_workers_.find(info.handle_id);
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (existing_worker != service_workers_.end()) {
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (adopt_handle) {
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // We are instructed to adopt a handle but we already have one, so
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // adopt and destroy a handle ref.
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return existing_worker->second;
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<ServiceWorkerHandleReference> handle_ref =
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      adopt_handle
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          ? ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_)
17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          : ServiceWorkerHandleReference::Create(info, thread_safe_sender_);
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // WebServiceWorkerImpl constructor calls AddServiceWorker.
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return new WebServiceWorkerImpl(handle_ref.Pass(), thread_safe_sender_);
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::OnRegistered(
181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int thread_id,
182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int request_id,
183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const ServiceWorkerObjectInfo& info) {
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks =
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_callbacks_.Lookup(request_id);
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!callbacks)
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  callbacks->onSuccess(GetServiceWorker(info, true));
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_callbacks_.Remove(request_id);
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ServiceWorkerDispatcher::OnUnregistered(
195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int thread_id,
196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int request_id) {
1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks =
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_callbacks_.Lookup(request_id);
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(callbacks);
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!callbacks)
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  callbacks->onSuccess(NULL);
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_callbacks_.Remove(request_id);
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ServiceWorkerDispatcher::OnRegistrationError(
208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int thread_id,
209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int request_id,
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WebServiceWorkerError::ErrorType error_type,
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message) {
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks =
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      pending_callbacks_.Lookup(request_id);
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(callbacks);
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!callbacks)
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WebServiceWorkerError>  error(
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new WebServiceWorkerError(error_type, message));
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  callbacks->onError(error.release());
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pending_callbacks_.Remove(request_id);
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int thread_id,
226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int handle_id,
227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    blink::WebServiceWorkerState state) {
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WorkerObjectMap::iterator worker = service_workers_.find(handle_id);
229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (worker != service_workers_.end())
230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    worker->second->OnStateChanged(state);
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  WorkerToProviderMap::iterator provider = worker_to_provider_.find(handle_id);
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (provider != worker_to_provider_.end())
234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    provider->second->OnServiceWorkerStateChanged(handle_id, state);
235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
236a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ServiceWorkerDispatcher::OnSetWaitingServiceWorker(
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int thread_id,
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int provider_id,
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ServiceWorkerObjectInfo& info) {
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (provider != provider_contexts_.end()) {
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int existing_waiting_id = provider->second->waiting_handle_id();
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (existing_waiting_id != info.handle_id &&
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        existing_waiting_id != kInvalidServiceWorkerHandleId) {
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      WorkerToProviderMap::iterator associated_provider =
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          worker_to_provider_.find(existing_waiting_id);
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK(associated_provider != worker_to_provider_.end());
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK(associated_provider->second->provider_id() == provider_id);
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      worker_to_provider_.erase(associated_provider);
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    provider->second->OnSetWaitingServiceWorker(provider_id, info);
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (info.handle_id != kInvalidServiceWorkerHandleId)
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      worker_to_provider_[info.handle_id] = provider->second;
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ScriptClientMap::iterator found = script_clients_.find(provider_id);
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (found != script_clients_.end()) {
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Populate the .waiting field with the new worker object.
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    found->second->setWaiting(GetServiceWorker(info, false));
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerDispatcher::OnSetCurrentServiceWorker(
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int thread_id,
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int provider_id,
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerObjectInfo& info) {
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (provider != provider_contexts_.end()) {
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    provider->second->OnSetCurrentServiceWorker(provider_id, info);
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    worker_to_provider_[info.handle_id] = provider->second;
272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ScriptClientMap::iterator found = script_clients_.find(provider_id);
275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (found != script_clients_.end()) {
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Populate the .controller field with the new worker object.
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    found->second->setController(GetServiceWorker(info, false));
278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerDispatcher::OnPostMessage(
282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int thread_id,
283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int provider_id,
284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::string16& message,
285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int>& sent_message_port_ids,
286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int>& new_routing_ids) {
287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Make sure we're on the main document thread. (That must be the only
288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // thread we get this message)
289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(ChildThread::current());
290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScriptClientMap::iterator found = script_clients_.find(provider_id);
2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == script_clients_.end()) {
293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // For now we do no queueing for messages sent to nonexistent / unattached
294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // client.
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<WebMessagePortChannelImpl*> ports;
299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!sent_message_port_ids.empty()) {
300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ports.resize(sent_message_port_ids.size());
301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ports[i] = new WebMessagePortChannelImpl(
303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          new_routing_ids[i], sent_message_port_ids[i],
304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          base::MessageLoopProxy::current());
305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  found->second->dispatchMessageEvent(message, ports);
3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
311a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::AddServiceWorker(
312a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int handle_id, WebServiceWorkerImpl* worker) {
313a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!ContainsKey(service_workers_, handle_id));
314a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  service_workers_[handle_id] = worker;
315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
316a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
317a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) {
318a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(ContainsKey(service_workers_, handle_id));
319a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  service_workers_.erase(handle_id);
320a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace content
323