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