1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/service_worker/service_worker_dispatcher.h"
7 #include "base/lazy_instance.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/stl_util.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/threading/thread_local.h"
12 #include "base/trace_event/trace_event.h"
13 #include "content/child/child_thread_impl.h"
14 #include "content/child/service_worker/service_worker_handle_reference.h"
15 #include "content/child/service_worker/service_worker_provider_context.h"
16 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
17 #include "content/child/service_worker/web_service_worker_impl.h"
18 #include "content/child/service_worker/web_service_worker_registration_impl.h"
19 #include "content/child/thread_safe_sender.h"
20 #include "content/child/webmessageportchannel_impl.h"
21 #include "content/common/service_worker/service_worker_messages.h"
22 #include "content/common/service_worker/service_worker_types.h"
23 #include "content/public/common/url_utils.h"
24 #include "third_party/WebKit/public/platform/WebString.h"
25 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerClientsInfo.h"
26 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h"
27 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
29 using blink::WebServiceWorkerError
;
30 using blink::WebServiceWorkerProvider
;
31 using base::ThreadLocalPointer
;
37 base::LazyInstance
<ThreadLocalPointer
<void>>::Leaky g_dispatcher_tls
=
38 LAZY_INSTANCE_INITIALIZER
;
40 void* const kHasBeenDeleted
= reinterpret_cast<void*>(0x1);
42 int CurrentWorkerId() {
43 return WorkerThread::GetCurrentId();
48 ServiceWorkerDispatcher::ServiceWorkerDispatcher(
49 ThreadSafeSender
* thread_safe_sender
,
50 base::SingleThreadTaskRunner
* main_thread_task_runner
)
51 : thread_safe_sender_(thread_safe_sender
),
52 main_thread_task_runner_(main_thread_task_runner
) {
53 g_dispatcher_tls
.Pointer()->Set(static_cast<void*>(this));
56 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
57 g_dispatcher_tls
.Pointer()->Set(kHasBeenDeleted
);
60 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message
& msg
) {
62 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher
, msg
)
63 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistrationWithServiceWorker
,
64 OnAssociateRegistrationWithServiceWorker
)
65 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration
,
66 OnAssociateRegistration
)
67 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DisassociateRegistration
,
68 OnDisassociateRegistration
)
69 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered
, OnRegistered
)
70 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUpdated
, OnUpdated
)
71 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered
,
73 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistration
,
75 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrations
,
76 OnDidGetRegistrations
)
77 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrationForReady
,
78 OnDidGetRegistrationForReady
)
79 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError
,
81 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUpdateError
,
83 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistrationError
,
84 OnUnregistrationError
)
85 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerGetRegistrationError
,
86 OnGetRegistrationError
)
87 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerGetRegistrationsError
,
88 OnGetRegistrationsError
)
89 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged
,
90 OnServiceWorkerStateChanged
)
91 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes
,
92 OnSetVersionAttributes
)
93 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound
,
95 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker
,
96 OnSetControllerServiceWorker
)
97 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument
,
99 IPC_MESSAGE_UNHANDLED(handled
= false)
100 IPC_END_MESSAGE_MAP()
101 DCHECK(handled
) << "Unhandled message:" << msg
.type();
104 bool ServiceWorkerDispatcher::Send(IPC::Message
* msg
) {
105 return thread_safe_sender_
->Send(msg
);
108 void ServiceWorkerDispatcher::RegisterServiceWorker(
111 const GURL
& script_url
,
112 WebServiceWorkerRegistrationCallbacks
* callbacks
) {
115 if (pattern
.possibly_invalid_spec().size() > GetMaxURLChars() ||
116 script_url
.possibly_invalid_spec().size() > GetMaxURLChars()) {
117 scoped_ptr
<WebServiceWorkerRegistrationCallbacks
>
118 owned_callbacks(callbacks
);
119 std::string
error_message(kServiceWorkerRegisterErrorPrefix
);
120 error_message
+= "The provided scriptURL or scope is too long.";
122 WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity
,
123 blink::WebString::fromUTF8(error_message
)));
127 int request_id
= pending_registration_callbacks_
.Add(callbacks
);
128 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
129 "ServiceWorkerDispatcher::RegisterServiceWorker",
131 "Scope", pattern
.spec(),
132 "Script URL", script_url
.spec());
133 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_RegisterServiceWorker(
134 CurrentWorkerId(), request_id
, provider_id
, pattern
, script_url
));
137 void ServiceWorkerDispatcher::UpdateServiceWorker(
139 int64 registration_id
,
140 WebServiceWorkerUpdateCallbacks
* callbacks
) {
142 int request_id
= pending_update_callbacks_
.Add(callbacks
);
143 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_UpdateServiceWorker(
144 CurrentWorkerId(), request_id
, provider_id
, registration_id
));
147 void ServiceWorkerDispatcher::UnregisterServiceWorker(
149 int64 registration_id
,
150 WebServiceWorkerUnregistrationCallbacks
* callbacks
) {
152 int request_id
= pending_unregistration_callbacks_
.Add(callbacks
);
153 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
154 "ServiceWorkerDispatcher::UnregisterServiceWorker",
155 request_id
, "Registration ID", registration_id
);
156 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker(
157 CurrentWorkerId(), request_id
, provider_id
, registration_id
));
160 void ServiceWorkerDispatcher::GetRegistration(
162 const GURL
& document_url
,
163 WebServiceWorkerGetRegistrationCallbacks
* callbacks
) {
166 if (document_url
.possibly_invalid_spec().size() > GetMaxURLChars()) {
167 scoped_ptr
<WebServiceWorkerGetRegistrationCallbacks
> owned_callbacks(
169 std::string
error_message(kServiceWorkerGetRegistrationErrorPrefix
);
170 error_message
+= "The provided documentURL is too long.";
172 WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity
,
173 blink::WebString::fromUTF8(error_message
)));
177 int request_id
= pending_get_registration_callbacks_
.Add(callbacks
);
178 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
179 "ServiceWorkerDispatcher::GetRegistration",
181 "Document URL", document_url
.spec());
182 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_GetRegistration(
183 CurrentWorkerId(), request_id
, provider_id
, document_url
));
186 void ServiceWorkerDispatcher::GetRegistrations(
188 WebServiceWorkerGetRegistrationsCallbacks
* callbacks
) {
191 int request_id
= pending_get_registrations_callbacks_
.Add(callbacks
);
192 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker",
193 "ServiceWorkerDispatcher::GetRegistrations",
195 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_GetRegistrations(
196 CurrentWorkerId(), request_id
, provider_id
));
199 void ServiceWorkerDispatcher::GetRegistrationForReady(
201 WebServiceWorkerGetRegistrationForReadyCallbacks
* callbacks
) {
202 int request_id
= get_for_ready_callbacks_
.Add(callbacks
);
203 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker",
204 "ServiceWorkerDispatcher::GetRegistrationForReady",
206 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_GetRegistrationForReady(
207 CurrentWorkerId(), request_id
, provider_id
));
210 void ServiceWorkerDispatcher::AddProviderContext(
211 ServiceWorkerProviderContext
* provider_context
) {
212 DCHECK(provider_context
);
213 int provider_id
= provider_context
->provider_id();
214 DCHECK(!ContainsKey(provider_contexts_
, provider_id
));
215 provider_contexts_
[provider_id
] = provider_context
;
218 void ServiceWorkerDispatcher::RemoveProviderContext(
219 ServiceWorkerProviderContext
* provider_context
) {
220 DCHECK(provider_context
);
221 DCHECK(ContainsKey(provider_contexts_
, provider_context
->provider_id()));
222 provider_contexts_
.erase(provider_context
->provider_id());
225 void ServiceWorkerDispatcher::AddProviderClient(
227 blink::WebServiceWorkerProviderClient
* client
) {
229 DCHECK(!ContainsKey(provider_clients_
, provider_id
));
230 provider_clients_
[provider_id
] = client
;
233 void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id
) {
234 // This could be possibly called multiple times to ensure termination.
235 if (ContainsKey(provider_clients_
, provider_id
))
236 provider_clients_
.erase(provider_id
);
239 ServiceWorkerDispatcher
*
240 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
241 ThreadSafeSender
* thread_safe_sender
,
242 base::SingleThreadTaskRunner
* main_thread_task_runner
) {
243 if (g_dispatcher_tls
.Pointer()->Get() == kHasBeenDeleted
) {
244 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
245 g_dispatcher_tls
.Pointer()->Set(NULL
);
247 if (g_dispatcher_tls
.Pointer()->Get())
248 return static_cast<ServiceWorkerDispatcher
*>(
249 g_dispatcher_tls
.Pointer()->Get());
251 ServiceWorkerDispatcher
* dispatcher
=
252 new ServiceWorkerDispatcher(thread_safe_sender
, main_thread_task_runner
);
253 if (WorkerThread::GetCurrentId())
254 WorkerThread::AddObserver(dispatcher
);
258 ServiceWorkerDispatcher
* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
259 if (g_dispatcher_tls
.Pointer()->Get() == kHasBeenDeleted
)
261 return static_cast<ServiceWorkerDispatcher
*>(
262 g_dispatcher_tls
.Pointer()->Get());
265 void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() {
269 WebServiceWorkerImpl
* ServiceWorkerDispatcher::GetServiceWorker(
270 const ServiceWorkerObjectInfo
& info
,
272 if (info
.handle_id
== kInvalidServiceWorkerHandleId
)
275 WorkerObjectMap::iterator existing_worker
=
276 service_workers_
.find(info
.handle_id
);
278 if (existing_worker
!= service_workers_
.end()) {
280 // We are instructed to adopt a handle but we already have one, so
281 // adopt and destroy a handle ref.
282 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
284 return existing_worker
->second
;
287 scoped_ptr
<ServiceWorkerHandleReference
> handle_ref
=
289 ? ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get())
290 : ServiceWorkerHandleReference::Create(info
,
291 thread_safe_sender_
.get());
292 // WebServiceWorkerImpl constructor calls AddServiceWorker.
293 return new WebServiceWorkerImpl(handle_ref
.Pass(), thread_safe_sender_
.get());
296 scoped_refptr
<WebServiceWorkerRegistrationImpl
>
297 ServiceWorkerDispatcher::CreateRegistration(
298 const ServiceWorkerRegistrationObjectInfo
& info
,
299 const ServiceWorkerVersionAttributes
& attrs
) {
300 return CreateRegistrationInternal(
301 ServiceWorkerRegistrationHandleReference::Create(
302 info
, thread_safe_sender_
.get()),
303 attrs
, false /* adopt_handle */);
306 scoped_refptr
<WebServiceWorkerRegistrationImpl
>
307 ServiceWorkerDispatcher::AdoptRegistration(
308 const ServiceWorkerRegistrationObjectInfo
& info
,
309 const ServiceWorkerVersionAttributes
& attrs
) {
310 return CreateRegistrationInternal(
311 ServiceWorkerRegistrationHandleReference::Adopt(
312 info
, thread_safe_sender_
.get()),
313 attrs
, true /* adopt_handle */);
316 // We can assume that this message handler is called before the worker context
317 // starts because script loading happens after this association.
318 // TODO(nhiroki): This association information could be pushed into
319 // EmbeddedWorkerMsg_StartWorker message and handed over to the worker thread
320 // without a lock in ServiceWorkerProviderContext.
321 void ServiceWorkerDispatcher::OnAssociateRegistrationWithServiceWorker(
324 const ServiceWorkerRegistrationObjectInfo
& info
,
325 const ServiceWorkerVersionAttributes
& attrs
) {
326 DCHECK_EQ(kDocumentMainThreadId
, thread_id
);
328 ProviderContextMap::iterator context
= provider_contexts_
.find(provider_id
);
329 if (context
== provider_contexts_
.end())
331 context
->second
->OnAssociateRegistration(info
, attrs
);
333 // We don't have to add entries into |worker_to_provider_| because state
334 // change events for the workers will be notified on the worker thread.
337 void ServiceWorkerDispatcher::OnAssociateRegistration(
340 const ServiceWorkerRegistrationObjectInfo
& info
,
341 const ServiceWorkerVersionAttributes
& attrs
) {
342 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
343 if (provider
== provider_contexts_
.end())
345 provider
->second
->OnAssociateRegistration(info
, attrs
);
348 void ServiceWorkerDispatcher::OnDisassociateRegistration(
351 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
352 if (provider
== provider_contexts_
.end())
354 provider
->second
->OnDisassociateRegistration();
357 void ServiceWorkerDispatcher::OnRegistered(
360 const ServiceWorkerRegistrationObjectInfo
& info
,
361 const ServiceWorkerVersionAttributes
& attrs
) {
362 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
363 "ServiceWorkerDispatcher::RegisterServiceWorker",
366 TRACE_EVENT_ASYNC_END0("ServiceWorker",
367 "ServiceWorkerDispatcher::RegisterServiceWorker",
369 WebServiceWorkerRegistrationCallbacks
* callbacks
=
370 pending_registration_callbacks_
.Lookup(request_id
);
375 callbacks
->onSuccess(AdoptRegistration(info
, attrs
)->CreateHandle());
376 pending_registration_callbacks_
.Remove(request_id
);
379 void ServiceWorkerDispatcher::OnUpdated(int thread_id
, int request_id
) {
380 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
381 "ServiceWorkerDispatcher::UpdateServiceWorker",
382 request_id
, "OnUpdated");
383 TRACE_EVENT_ASYNC_END0("ServiceWorker",
384 "ServiceWorkerDispatcher::UpdateServiceWorker",
386 WebServiceWorkerUpdateCallbacks
* callbacks
=
387 pending_update_callbacks_
.Lookup(request_id
);
392 callbacks
->onSuccess();
393 pending_update_callbacks_
.Remove(request_id
);
396 void ServiceWorkerDispatcher::OnUnregistered(int thread_id
,
399 TRACE_EVENT_ASYNC_STEP_INTO0(
401 "ServiceWorkerDispatcher::UnregisterServiceWorker",
404 TRACE_EVENT_ASYNC_END0("ServiceWorker",
405 "ServiceWorkerDispatcher::UnregisterServiceWorker",
407 WebServiceWorkerUnregistrationCallbacks
* callbacks
=
408 pending_unregistration_callbacks_
.Lookup(request_id
);
412 callbacks
->onSuccess(is_success
);
413 pending_unregistration_callbacks_
.Remove(request_id
);
416 void ServiceWorkerDispatcher::OnDidGetRegistration(
419 const ServiceWorkerRegistrationObjectInfo
& info
,
420 const ServiceWorkerVersionAttributes
& attrs
) {
421 TRACE_EVENT_ASYNC_STEP_INTO0(
423 "ServiceWorkerDispatcher::GetRegistration",
425 "OnDidGetRegistration");
426 TRACE_EVENT_ASYNC_END0("ServiceWorker",
427 "ServiceWorkerDispatcher::GetRegistration",
429 WebServiceWorkerGetRegistrationCallbacks
* callbacks
=
430 pending_get_registration_callbacks_
.Lookup(request_id
);
435 scoped_refptr
<WebServiceWorkerRegistrationImpl
> registration
;
436 if (info
.handle_id
!= kInvalidServiceWorkerHandleId
)
437 registration
= AdoptRegistration(info
, attrs
);
439 callbacks
->onSuccess(registration
? registration
->CreateHandle() : nullptr);
440 pending_get_registration_callbacks_
.Remove(request_id
);
443 void ServiceWorkerDispatcher::OnDidGetRegistrations(
446 const std::vector
<ServiceWorkerRegistrationObjectInfo
>& infos
,
447 const std::vector
<ServiceWorkerVersionAttributes
>& attrs
) {
448 TRACE_EVENT_ASYNC_STEP_INTO0(
450 "ServiceWorkerDispatcher::GetRegistrations",
452 "OnDidGetRegistrations");
453 TRACE_EVENT_ASYNC_END0("ServiceWorker",
454 "ServiceWorkerDispatcher::GetRegistrations",
457 WebServiceWorkerGetRegistrationsCallbacks
* callbacks
=
458 pending_get_registrations_callbacks_
.Lookup(request_id
);
463 typedef blink::WebVector
<blink::WebServiceWorkerRegistration::Handle
*>
464 WebServiceWorkerRegistrationArray
;
465 scoped_ptr
<WebServiceWorkerRegistrationArray
> registrations(
466 new WebServiceWorkerRegistrationArray(infos
.size()));
467 for (size_t i
= 0; i
< infos
.size(); ++i
) {
468 if (infos
[i
].handle_id
!= kInvalidServiceWorkerHandleId
) {
469 ServiceWorkerRegistrationObjectInfo
info(infos
[i
]);
470 ServiceWorkerVersionAttributes
attr(attrs
[i
]);
472 // WebServiceWorkerGetRegistrationsCallbacks cannot receive an array of
473 // WebPassOwnPtr<WebServiceWorkerRegistration::Handle>, so create leaky
475 (*registrations
)[i
] = AdoptRegistration(info
, attr
)->CreateLeakyHandle();
479 callbacks
->onSuccess(blink::adoptWebPtr(registrations
.release()));
480 pending_get_registrations_callbacks_
.Remove(request_id
);
483 void ServiceWorkerDispatcher::OnDidGetRegistrationForReady(
486 const ServiceWorkerRegistrationObjectInfo
& info
,
487 const ServiceWorkerVersionAttributes
& attrs
) {
488 TRACE_EVENT_ASYNC_STEP_INTO0(
490 "ServiceWorkerDispatcher::GetRegistrationForReady",
492 "OnDidGetRegistrationForReady");
493 TRACE_EVENT_ASYNC_END0("ServiceWorker",
494 "ServiceWorkerDispatcher::GetRegistrationForReady",
496 WebServiceWorkerGetRegistrationForReadyCallbacks
* callbacks
=
497 get_for_ready_callbacks_
.Lookup(request_id
);
502 callbacks
->onSuccess(AdoptRegistration(info
, attrs
)->CreateHandle());
503 get_for_ready_callbacks_
.Remove(request_id
);
506 void ServiceWorkerDispatcher::OnRegistrationError(
509 WebServiceWorkerError::ErrorType error_type
,
510 const base::string16
& message
) {
511 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
512 "ServiceWorkerDispatcher::RegisterServiceWorker",
514 "OnRegistrationError");
515 TRACE_EVENT_ASYNC_END0("ServiceWorker",
516 "ServiceWorkerDispatcher::RegisterServiceWorker",
518 WebServiceWorkerRegistrationCallbacks
* callbacks
=
519 pending_registration_callbacks_
.Lookup(request_id
);
524 callbacks
->onError(WebServiceWorkerError(error_type
, message
));
525 pending_registration_callbacks_
.Remove(request_id
);
528 void ServiceWorkerDispatcher::OnUpdateError(
531 WebServiceWorkerError::ErrorType error_type
,
532 const base::string16
& message
) {
533 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
534 "ServiceWorkerDispatcher::UpdateServiceWorker",
535 request_id
, "OnUpdateError");
536 TRACE_EVENT_ASYNC_END0("ServiceWorker",
537 "ServiceWorkerDispatcher::UpdateServiceWorker",
539 WebServiceWorkerUpdateCallbacks
* callbacks
=
540 pending_update_callbacks_
.Lookup(request_id
);
545 callbacks
->onError(WebServiceWorkerError(error_type
, message
));
546 pending_update_callbacks_
.Remove(request_id
);
549 void ServiceWorkerDispatcher::OnUnregistrationError(
552 WebServiceWorkerError::ErrorType error_type
,
553 const base::string16
& message
) {
554 TRACE_EVENT_ASYNC_STEP_INTO0(
556 "ServiceWorkerDispatcher::UnregisterServiceWorker",
558 "OnUnregistrationError");
559 TRACE_EVENT_ASYNC_END0("ServiceWorker",
560 "ServiceWorkerDispatcher::UnregisterServiceWorker",
562 WebServiceWorkerUnregistrationCallbacks
* callbacks
=
563 pending_unregistration_callbacks_
.Lookup(request_id
);
568 callbacks
->onError(WebServiceWorkerError(error_type
, message
));
569 pending_unregistration_callbacks_
.Remove(request_id
);
572 void ServiceWorkerDispatcher::OnGetRegistrationError(
575 WebServiceWorkerError::ErrorType error_type
,
576 const base::string16
& message
) {
577 TRACE_EVENT_ASYNC_STEP_INTO0(
579 "ServiceWorkerDispatcher::GetRegistration",
581 "OnGetRegistrationError");
582 TRACE_EVENT_ASYNC_END0("ServiceWorker",
583 "ServiceWorkerDispatcher::GetRegistration",
585 WebServiceWorkerGetRegistrationCallbacks
* callbacks
=
586 pending_get_registration_callbacks_
.Lookup(request_id
);
591 callbacks
->onError(WebServiceWorkerError(error_type
, message
));
592 pending_get_registration_callbacks_
.Remove(request_id
);
595 void ServiceWorkerDispatcher::OnGetRegistrationsError(
598 WebServiceWorkerError::ErrorType error_type
,
599 const base::string16
& message
) {
600 TRACE_EVENT_ASYNC_STEP_INTO0(
602 "ServiceWorkerDispatcher::GetRegistrations",
604 "OnGetRegistrationsError");
605 TRACE_EVENT_ASYNC_END0("ServiceWorker",
606 "ServiceWorkerDispatcher::GetRegistrations",
608 WebServiceWorkerGetRegistrationsCallbacks
* callbacks
=
609 pending_get_registrations_callbacks_
.Lookup(request_id
);
614 callbacks
->onError(WebServiceWorkerError(error_type
, message
));
615 pending_get_registrations_callbacks_
.Remove(request_id
);
618 void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
621 blink::WebServiceWorkerState state
) {
622 TRACE_EVENT2("ServiceWorker",
623 "ServiceWorkerDispatcher::OnServiceWorkerStateChanged",
624 "Thread ID", thread_id
,
626 WorkerObjectMap::iterator worker
= service_workers_
.find(handle_id
);
627 if (worker
!= service_workers_
.end())
628 worker
->second
->OnStateChanged(state
);
631 void ServiceWorkerDispatcher::OnSetVersionAttributes(
634 int registration_handle_id
,
636 const ServiceWorkerVersionAttributes
& attrs
) {
637 TRACE_EVENT1("ServiceWorker",
638 "ServiceWorkerDispatcher::OnSetVersionAttributes",
639 "Thread ID", thread_id
);
641 RegistrationObjectMap::iterator found
=
642 registrations_
.find(registration_handle_id
);
643 if (found
!= registrations_
.end()) {
644 // Populate the version fields (eg. .installing) with new worker objects.
645 ChangedVersionAttributesMask
mask(changed_mask
);
646 if (mask
.installing_changed())
647 found
->second
->SetInstalling(GetServiceWorker(attrs
.installing
, false));
648 if (mask
.waiting_changed())
649 found
->second
->SetWaiting(GetServiceWorker(attrs
.waiting
, false));
650 if (mask
.active_changed())
651 found
->second
->SetActive(GetServiceWorker(attrs
.active
, false));
655 void ServiceWorkerDispatcher::OnUpdateFound(
657 int registration_handle_id
) {
658 TRACE_EVENT0("ServiceWorker",
659 "ServiceWorkerDispatcher::OnUpdateFound");
660 RegistrationObjectMap::iterator found
=
661 registrations_
.find(registration_handle_id
);
662 if (found
!= registrations_
.end())
663 found
->second
->OnUpdateFound();
666 void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
669 const ServiceWorkerObjectInfo
& info
,
670 bool should_notify_controllerchange
) {
671 TRACE_EVENT2("ServiceWorker",
672 "ServiceWorkerDispatcher::OnSetControllerServiceWorker",
673 "Thread ID", thread_id
,
674 "Provider ID", provider_id
);
676 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
677 if (provider
!= provider_contexts_
.end())
678 provider
->second
->OnSetControllerServiceWorker(info
);
680 ProviderClientMap::iterator found
= provider_clients_
.find(provider_id
);
681 if (found
!= provider_clients_
.end()) {
682 // Populate the .controller field with the new worker object.
683 found
->second
->setController(GetServiceWorker(info
, false),
684 should_notify_controllerchange
);
688 void ServiceWorkerDispatcher::OnPostMessage(
689 const ServiceWorkerMsg_MessageToDocument_Params
& params
) {
690 // Make sure we're on the main document thread. (That must be the only
691 // thread we get this message)
692 DCHECK(ChildThreadImpl::current());
693 TRACE_EVENT1("ServiceWorker", "ServiceWorkerDispatcher::OnPostMessage",
694 "Thread ID", params
.thread_id
);
696 ProviderClientMap::iterator found
=
697 provider_clients_
.find(params
.provider_id
);
698 if (found
== provider_clients_
.end()) {
699 // For now we do no queueing for messages sent to nonexistent / unattached
704 blink::WebMessagePortChannelArray ports
=
705 WebMessagePortChannelImpl::CreatePorts(
706 params
.message_ports
, params
.new_routing_ids
,
707 base::ThreadTaskRunnerHandle::Get());
709 found
->second
->dispatchMessageEvent(
710 GetServiceWorker(params
.service_worker_info
, false /* adopt_handle */),
711 params
.message
, ports
);
714 void ServiceWorkerDispatcher::AddServiceWorker(
715 int handle_id
, WebServiceWorkerImpl
* worker
) {
716 DCHECK(!ContainsKey(service_workers_
, handle_id
));
717 service_workers_
[handle_id
] = worker
;
720 void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id
) {
721 DCHECK(ContainsKey(service_workers_
, handle_id
));
722 service_workers_
.erase(handle_id
);
725 void ServiceWorkerDispatcher::AddServiceWorkerRegistration(
726 int registration_handle_id
,
727 WebServiceWorkerRegistrationImpl
* registration
) {
728 DCHECK(!ContainsKey(registrations_
, registration_handle_id
));
729 registrations_
[registration_handle_id
] = registration
;
732 void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
733 int registration_handle_id
) {
734 DCHECK(ContainsKey(registrations_
, registration_handle_id
));
735 registrations_
.erase(registration_handle_id
);
738 scoped_refptr
<WebServiceWorkerRegistrationImpl
>
739 ServiceWorkerDispatcher::CreateRegistrationInternal(
740 scoped_ptr
<ServiceWorkerRegistrationHandleReference
> handle_ref
,
741 const ServiceWorkerVersionAttributes
& attrs
,
743 // WebServiceWorkerRegistrationImpl constructor calls
744 // AddServiceWorkerRegistration.
745 scoped_refptr
<WebServiceWorkerRegistrationImpl
> registration(
746 new WebServiceWorkerRegistrationImpl(handle_ref
.Pass()));
747 registration
->SetInstalling(GetServiceWorker(attrs
.installing
, adopt_handle
));
748 registration
->SetWaiting(GetServiceWorker(attrs
.waiting
, adopt_handle
));
749 registration
->SetActive(GetServiceWorker(attrs
.active
, adopt_handle
));
750 return registration
.Pass();
753 } // namespace content