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/stl_util.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/threading/thread_local.h"
11 #include "base/trace_event/trace_event.h"
12 #include "content/child/child_thread_impl.h"
13 #include "content/child/service_worker/service_worker_handle_reference.h"
14 #include "content/child/service_worker/service_worker_provider_context.h"
15 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
16 #include "content/child/service_worker/web_service_worker_impl.h"
17 #include "content/child/service_worker/web_service_worker_registration_impl.h"
18 #include "content/child/thread_safe_sender.h"
19 #include "content/child/webmessageportchannel_impl.h"
20 #include "content/common/service_worker/service_worker_messages.h"
21 #include "content/common/service_worker/service_worker_types.h"
22 #include "content/public/common/url_utils.h"
23 #include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h"
24 #include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
25 #include "third_party/WebKit/public/platform/WebString.h"
26 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
28 using blink::WebServiceWorkerError
;
29 using blink::WebServiceWorkerProvider
;
30 using base::ThreadLocalPointer
;
36 base::LazyInstance
<ThreadLocalPointer
<ServiceWorkerDispatcher
> >::Leaky
37 g_dispatcher_tls
= LAZY_INSTANCE_INITIALIZER
;
39 ServiceWorkerDispatcher
* const kHasBeenDeleted
=
40 reinterpret_cast<ServiceWorkerDispatcher
*>(0x1);
42 int CurrentWorkerId() {
43 return WorkerTaskRunner::Instance()->CurrentWorkerId();
48 ServiceWorkerDispatcher::ServiceWorkerDispatcher(
49 ThreadSafeSender
* thread_safe_sender
)
50 : thread_safe_sender_(thread_safe_sender
) {
51 g_dispatcher_tls
.Pointer()->Set(this);
54 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
55 g_dispatcher_tls
.Pointer()->Set(kHasBeenDeleted
);
58 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message
& msg
) {
60 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher
, msg
)
61 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistrationWithServiceWorker
,
62 OnAssociateRegistrationWithServiceWorker
)
63 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration
,
64 OnAssociateRegistration
)
65 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DisassociateRegistration
,
66 OnDisassociateRegistration
)
67 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered
, OnRegistered
)
68 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered
,
70 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistration
,
72 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrationForReady
,
73 OnDidGetRegistrationForReady
)
74 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError
,
76 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistrationError
,
77 OnUnregistrationError
)
78 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerGetRegistrationError
,
79 OnGetRegistrationError
)
80 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged
,
81 OnServiceWorkerStateChanged
)
82 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes
,
83 OnSetVersionAttributes
)
84 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_UpdateFound
,
86 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker
,
87 OnSetControllerServiceWorker
)
88 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument
,
90 IPC_MESSAGE_UNHANDLED(handled
= false)
92 DCHECK(handled
) << "Unhandled message:" << msg
.type();
95 bool ServiceWorkerDispatcher::Send(IPC::Message
* msg
) {
96 return thread_safe_sender_
->Send(msg
);
99 void ServiceWorkerDispatcher::RegisterServiceWorker(
102 const GURL
& script_url
,
103 WebServiceWorkerRegistrationCallbacks
* callbacks
) {
106 if (pattern
.possibly_invalid_spec().size() > GetMaxURLChars() ||
107 script_url
.possibly_invalid_spec().size() > GetMaxURLChars()) {
108 scoped_ptr
<WebServiceWorkerRegistrationCallbacks
>
109 owned_callbacks(callbacks
);
110 std::string
error_message(kServiceWorkerRegisterErrorPrefix
);
111 error_message
+= "The provided scriptURL or scope is too long.";
112 scoped_ptr
<WebServiceWorkerError
> error(
113 new WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity
,
114 blink::WebString::fromUTF8(error_message
)));
115 callbacks
->onError(error
.release());
119 int request_id
= pending_registration_callbacks_
.Add(callbacks
);
120 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
121 "ServiceWorkerDispatcher::RegisterServiceWorker",
123 "Scope", pattern
.spec(),
124 "Script URL", script_url
.spec());
125 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_RegisterServiceWorker(
126 CurrentWorkerId(), request_id
, provider_id
, pattern
, script_url
));
129 void ServiceWorkerDispatcher::UnregisterServiceWorker(
132 WebServiceWorkerUnregistrationCallbacks
* callbacks
) {
135 if (pattern
.possibly_invalid_spec().size() > GetMaxURLChars()) {
136 scoped_ptr
<WebServiceWorkerUnregistrationCallbacks
>
137 owned_callbacks(callbacks
);
138 std::string
error_message(kServiceWorkerUnregisterErrorPrefix
);
139 error_message
+= "The provided scope is too long.";
140 scoped_ptr
<WebServiceWorkerError
> error(
141 new WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity
,
142 blink::WebString::fromUTF8(error_message
)));
143 callbacks
->onError(error
.release());
147 int request_id
= pending_unregistration_callbacks_
.Add(callbacks
);
148 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
149 "ServiceWorkerDispatcher::UnregisterServiceWorker",
151 "Scope", pattern
.spec());
152 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker(
153 CurrentWorkerId(), request_id
, provider_id
, pattern
));
156 void ServiceWorkerDispatcher::GetRegistration(
158 const GURL
& document_url
,
159 WebServiceWorkerRegistrationCallbacks
* callbacks
) {
162 if (document_url
.possibly_invalid_spec().size() > GetMaxURLChars()) {
163 scoped_ptr
<WebServiceWorkerRegistrationCallbacks
>
164 owned_callbacks(callbacks
);
165 std::string
error_message(kServiceWorkerGetRegistrationErrorPrefix
);
166 error_message
+= "The provided documentURL is too long.";
167 scoped_ptr
<WebServiceWorkerError
> error(
168 new WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity
,
169 blink::WebString::fromUTF8(error_message
)));
170 callbacks
->onError(error
.release());
174 int request_id
= pending_get_registration_callbacks_
.Add(callbacks
);
175 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
176 "ServiceWorkerDispatcher::GetRegistration",
178 "Document URL", document_url
.spec());
179 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_GetRegistration(
180 CurrentWorkerId(), request_id
, provider_id
, document_url
));
183 void ServiceWorkerDispatcher::GetRegistrationForReady(
185 WebServiceWorkerGetRegistrationForReadyCallbacks
* callbacks
) {
186 int request_id
= get_for_ready_callbacks_
.Add(callbacks
);
187 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker",
188 "ServiceWorkerDispatcher::GetRegistrationForReady",
190 thread_safe_sender_
->Send(new ServiceWorkerHostMsg_GetRegistrationForReady(
191 CurrentWorkerId(), request_id
, provider_id
));
194 void ServiceWorkerDispatcher::AddProviderContext(
195 ServiceWorkerProviderContext
* provider_context
) {
196 DCHECK(provider_context
);
197 int provider_id
= provider_context
->provider_id();
198 DCHECK(!ContainsKey(provider_contexts_
, provider_id
));
199 provider_contexts_
[provider_id
] = provider_context
;
202 void ServiceWorkerDispatcher::RemoveProviderContext(
203 ServiceWorkerProviderContext
* provider_context
) {
204 DCHECK(provider_context
);
205 DCHECK(ContainsKey(provider_contexts_
, provider_context
->provider_id()));
206 provider_contexts_
.erase(provider_context
->provider_id());
207 worker_to_provider_
.erase(provider_context
->installing_handle_id());
208 worker_to_provider_
.erase(provider_context
->waiting_handle_id());
209 worker_to_provider_
.erase(provider_context
->active_handle_id());
210 worker_to_provider_
.erase(provider_context
->controller_handle_id());
213 void ServiceWorkerDispatcher::AddProviderClient(
215 blink::WebServiceWorkerProviderClient
* client
) {
217 DCHECK(!ContainsKey(provider_clients_
, provider_id
));
218 provider_clients_
[provider_id
] = client
;
221 void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id
) {
222 // This could be possibly called multiple times to ensure termination.
223 if (ContainsKey(provider_clients_
, provider_id
))
224 provider_clients_
.erase(provider_id
);
227 ServiceWorkerDispatcher
*
228 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
229 ThreadSafeSender
* thread_safe_sender
) {
230 if (g_dispatcher_tls
.Pointer()->Get() == kHasBeenDeleted
) {
231 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
232 g_dispatcher_tls
.Pointer()->Set(NULL
);
234 if (g_dispatcher_tls
.Pointer()->Get())
235 return g_dispatcher_tls
.Pointer()->Get();
237 ServiceWorkerDispatcher
* dispatcher
=
238 new ServiceWorkerDispatcher(thread_safe_sender
);
239 if (WorkerTaskRunner::Instance()->CurrentWorkerId())
240 WorkerTaskRunner::Instance()->AddStopObserver(dispatcher
);
244 ServiceWorkerDispatcher
* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
245 if (g_dispatcher_tls
.Pointer()->Get() == kHasBeenDeleted
)
247 return g_dispatcher_tls
.Pointer()->Get();
250 void ServiceWorkerDispatcher::OnWorkerRunLoopStopped() {
254 WebServiceWorkerImpl
* ServiceWorkerDispatcher::GetServiceWorker(
255 const ServiceWorkerObjectInfo
& info
,
257 if (info
.handle_id
== kInvalidServiceWorkerHandleId
)
260 WorkerObjectMap::iterator existing_worker
=
261 service_workers_
.find(info
.handle_id
);
263 if (existing_worker
!= service_workers_
.end()) {
265 // We are instructed to adopt a handle but we already have one, so
266 // adopt and destroy a handle ref.
267 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
269 return existing_worker
->second
;
272 scoped_ptr
<ServiceWorkerHandleReference
> handle_ref
=
274 ? ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get())
275 : ServiceWorkerHandleReference::Create(info
,
276 thread_safe_sender_
.get());
277 // WebServiceWorkerImpl constructor calls AddServiceWorker.
278 return new WebServiceWorkerImpl(handle_ref
.Pass(), thread_safe_sender_
.get());
281 WebServiceWorkerRegistrationImpl
*
282 ServiceWorkerDispatcher::CreateServiceWorkerRegistration(
283 const ServiceWorkerRegistrationObjectInfo
& info
,
285 DCHECK(!ContainsKey(registrations_
, info
.handle_id
));
286 if (info
.handle_id
== kInvalidServiceWorkerRegistrationHandleId
)
289 scoped_ptr
<ServiceWorkerRegistrationHandleReference
> handle_ref
=
290 adopt_handle
? ServiceWorkerRegistrationHandleReference::Adopt(
291 info
, thread_safe_sender_
.get())
292 : ServiceWorkerRegistrationHandleReference::Create(
293 info
, thread_safe_sender_
.get());
295 // WebServiceWorkerRegistrationImpl constructor calls
296 // AddServiceWorkerRegistration.
297 return new WebServiceWorkerRegistrationImpl(handle_ref
.Pass());
300 // We can assume that this message handler is called before the worker context
301 // starts because script loading happens after this association.
302 // TODO(nhiroki): This association information could be pushed into
303 // EmbeddedWorkerMsg_StartWorker message and handed over to the worker thread
304 // without a lock in ServiceWorkerProviderContext.
305 void ServiceWorkerDispatcher::OnAssociateRegistrationWithServiceWorker(
308 const ServiceWorkerRegistrationObjectInfo
& info
,
309 const ServiceWorkerVersionAttributes
& attrs
) {
310 DCHECK_EQ(kDocumentMainThreadId
, thread_id
);
312 ProviderContextMap::iterator context
= provider_contexts_
.find(provider_id
);
313 if (context
== provider_contexts_
.end())
315 context
->second
->OnAssociateRegistration(info
, attrs
);
317 // We don't have to add entries into |worker_to_provider_| because state
318 // change events for the workers will be notified on the worker thread.
321 void ServiceWorkerDispatcher::OnAssociateRegistration(
324 const ServiceWorkerRegistrationObjectInfo
& info
,
325 const ServiceWorkerVersionAttributes
& attrs
) {
326 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
327 if (provider
== provider_contexts_
.end())
329 provider
->second
->OnAssociateRegistration(info
, attrs
);
330 if (attrs
.installing
.handle_id
!= kInvalidServiceWorkerHandleId
)
331 worker_to_provider_
[attrs
.installing
.handle_id
] = provider
->second
;
332 if (attrs
.waiting
.handle_id
!= kInvalidServiceWorkerHandleId
)
333 worker_to_provider_
[attrs
.waiting
.handle_id
] = provider
->second
;
334 if (attrs
.active
.handle_id
!= kInvalidServiceWorkerHandleId
)
335 worker_to_provider_
[attrs
.active
.handle_id
] = provider
->second
;
338 void ServiceWorkerDispatcher::OnDisassociateRegistration(
341 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
342 if (provider
== provider_contexts_
.end())
344 worker_to_provider_
.erase(provider
->second
->installing_handle_id());
345 worker_to_provider_
.erase(provider
->second
->waiting_handle_id());
346 worker_to_provider_
.erase(provider
->second
->active_handle_id());
347 worker_to_provider_
.erase(provider
->second
->controller_handle_id());
348 provider
->second
->OnDisassociateRegistration();
351 void ServiceWorkerDispatcher::OnRegistered(
354 const ServiceWorkerRegistrationObjectInfo
& info
,
355 const ServiceWorkerVersionAttributes
& attrs
) {
356 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
357 "ServiceWorkerDispatcher::RegisterServiceWorker",
360 TRACE_EVENT_ASYNC_END0("ServiceWorker",
361 "ServiceWorkerDispatcher::RegisterServiceWorker",
363 WebServiceWorkerRegistrationCallbacks
* callbacks
=
364 pending_registration_callbacks_
.Lookup(request_id
);
369 callbacks
->onSuccess(FindOrCreateRegistration(info
, attrs
));
370 pending_registration_callbacks_
.Remove(request_id
);
373 void ServiceWorkerDispatcher::OnUnregistered(int thread_id
,
376 TRACE_EVENT_ASYNC_STEP_INTO0(
378 "ServiceWorkerDispatcher::UnregisterServiceWorker",
381 TRACE_EVENT_ASYNC_END0("ServiceWorker",
382 "ServiceWorkerDispatcher::UnregisterServiceWorker",
384 WebServiceWorkerUnregistrationCallbacks
* callbacks
=
385 pending_unregistration_callbacks_
.Lookup(request_id
);
389 callbacks
->onSuccess(&is_success
);
390 pending_unregistration_callbacks_
.Remove(request_id
);
393 void ServiceWorkerDispatcher::OnDidGetRegistration(
396 const ServiceWorkerRegistrationObjectInfo
& info
,
397 const ServiceWorkerVersionAttributes
& attrs
) {
398 TRACE_EVENT_ASYNC_STEP_INTO0(
400 "ServiceWorkerDispatcher::GetRegistration",
402 "OnDidGetRegistration");
403 TRACE_EVENT_ASYNC_END0("ServiceWorker",
404 "ServiceWorkerDispatcher::GetRegistration",
406 WebServiceWorkerRegistrationCallbacks
* callbacks
=
407 pending_get_registration_callbacks_
.Lookup(request_id
);
412 WebServiceWorkerRegistrationImpl
* registration
= NULL
;
413 if (info
.handle_id
!= kInvalidServiceWorkerHandleId
)
414 registration
= FindOrCreateRegistration(info
, attrs
);
416 callbacks
->onSuccess(registration
);
417 pending_get_registration_callbacks_
.Remove(request_id
);
420 void ServiceWorkerDispatcher::OnDidGetRegistrationForReady(
423 const ServiceWorkerRegistrationObjectInfo
& info
,
424 const ServiceWorkerVersionAttributes
& attrs
) {
425 TRACE_EVENT_ASYNC_STEP_INTO0(
427 "ServiceWorkerDispatcher::GetRegistrationForReady",
429 "OnDidGetRegistrationForReady");
430 TRACE_EVENT_ASYNC_END0("ServiceWorker",
431 "ServiceWorkerDispatcher::GetRegistrationForReady",
433 WebServiceWorkerGetRegistrationForReadyCallbacks
* callbacks
=
434 get_for_ready_callbacks_
.Lookup(request_id
);
439 WebServiceWorkerRegistrationImpl
* registration
= NULL
;
440 DCHECK(info
.handle_id
!= kInvalidServiceWorkerHandleId
);
441 registration
= FindOrCreateRegistration(info
, attrs
);
442 callbacks
->onSuccess(registration
);
443 get_for_ready_callbacks_
.Remove(request_id
);
446 void ServiceWorkerDispatcher::OnRegistrationError(
449 WebServiceWorkerError::ErrorType error_type
,
450 const base::string16
& message
) {
451 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
452 "ServiceWorkerDispatcher::RegisterServiceWorker",
454 "OnRegistrationError");
455 TRACE_EVENT_ASYNC_END0("ServiceWorker",
456 "ServiceWorkerDispatcher::RegisterServiceWorker",
458 WebServiceWorkerRegistrationCallbacks
* callbacks
=
459 pending_registration_callbacks_
.Lookup(request_id
);
464 scoped_ptr
<WebServiceWorkerError
> error(
465 new WebServiceWorkerError(error_type
, message
));
466 callbacks
->onError(error
.release());
467 pending_registration_callbacks_
.Remove(request_id
);
470 void ServiceWorkerDispatcher::OnUnregistrationError(
473 WebServiceWorkerError::ErrorType error_type
,
474 const base::string16
& message
) {
475 TRACE_EVENT_ASYNC_STEP_INTO0(
477 "ServiceWorkerDispatcher::UnregisterServiceWorker",
479 "OnUnregistrationError");
480 TRACE_EVENT_ASYNC_END0("ServiceWorker",
481 "ServiceWorkerDispatcher::UnregisterServiceWorker",
483 WebServiceWorkerUnregistrationCallbacks
* callbacks
=
484 pending_unregistration_callbacks_
.Lookup(request_id
);
489 scoped_ptr
<WebServiceWorkerError
> error(
490 new WebServiceWorkerError(error_type
, message
));
491 callbacks
->onError(error
.release());
492 pending_unregistration_callbacks_
.Remove(request_id
);
495 void ServiceWorkerDispatcher::OnGetRegistrationError(
498 WebServiceWorkerError::ErrorType error_type
,
499 const base::string16
& message
) {
500 TRACE_EVENT_ASYNC_STEP_INTO0(
502 "ServiceWorkerDispatcher::GetRegistration",
504 "OnGetRegistrationError");
505 TRACE_EVENT_ASYNC_END0("ServiceWorker",
506 "ServiceWorkerDispatcher::GetRegistration",
508 WebServiceWorkerGetRegistrationCallbacks
* callbacks
=
509 pending_get_registration_callbacks_
.Lookup(request_id
);
514 scoped_ptr
<WebServiceWorkerError
> error(
515 new WebServiceWorkerError(error_type
, message
));
516 callbacks
->onError(error
.release());
517 pending_get_registration_callbacks_
.Remove(request_id
);
520 void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
523 blink::WebServiceWorkerState state
) {
524 TRACE_EVENT2("ServiceWorker",
525 "ServiceWorkerDispatcher::OnServiceWorkerStateChanged",
526 "Thread ID", thread_id
,
528 WorkerObjectMap::iterator worker
= service_workers_
.find(handle_id
);
529 if (worker
!= service_workers_
.end())
530 worker
->second
->OnStateChanged(state
);
532 WorkerToProviderMap::iterator provider
= worker_to_provider_
.find(handle_id
);
533 if (provider
!= worker_to_provider_
.end())
534 provider
->second
->OnServiceWorkerStateChanged(handle_id
, state
);
537 void ServiceWorkerDispatcher::OnSetVersionAttributes(
540 int registration_handle_id
,
542 const ServiceWorkerVersionAttributes
& attrs
) {
543 TRACE_EVENT1("ServiceWorker",
544 "ServiceWorkerDispatcher::OnSetVersionAttributes",
545 "Thread ID", thread_id
);
547 ChangedVersionAttributesMask
mask(changed_mask
);
548 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
549 if (provider
!= provider_contexts_
.end() &&
550 provider
->second
->registration_handle_id() == registration_handle_id
) {
551 if (mask
.installing_changed()) {
552 worker_to_provider_
.erase(provider
->second
->installing_handle_id());
553 if (attrs
.installing
.handle_id
!= kInvalidServiceWorkerHandleId
)
554 worker_to_provider_
[attrs
.installing
.handle_id
] = provider
->second
;
556 if (mask
.waiting_changed()) {
557 worker_to_provider_
.erase(provider
->second
->waiting_handle_id());
558 if (attrs
.waiting
.handle_id
!= kInvalidServiceWorkerHandleId
)
559 worker_to_provider_
[attrs
.waiting
.handle_id
] = provider
->second
;
561 if (mask
.active_changed()) {
562 worker_to_provider_
.erase(provider
->second
->active_handle_id());
563 if (attrs
.active
.handle_id
!= kInvalidServiceWorkerHandleId
)
564 worker_to_provider_
[attrs
.active
.handle_id
] = provider
->second
;
566 provider
->second
->SetVersionAttributes(mask
, attrs
);
569 RegistrationObjectMap::iterator found
=
570 registrations_
.find(registration_handle_id
);
571 if (found
!= registrations_
.end()) {
572 // Populate the version fields (eg. .installing) with new worker objects.
573 if (mask
.installing_changed())
574 found
->second
->SetInstalling(GetServiceWorker(attrs
.installing
, false));
575 if (mask
.waiting_changed())
576 found
->second
->SetWaiting(GetServiceWorker(attrs
.waiting
, false));
577 if (mask
.active_changed())
578 found
->second
->SetActive(GetServiceWorker(attrs
.active
, false));
582 void ServiceWorkerDispatcher::OnUpdateFound(
584 int registration_handle_id
) {
585 TRACE_EVENT0("ServiceWorker",
586 "ServiceWorkerDispatcher::OnUpdateFound");
587 RegistrationObjectMap::iterator found
=
588 registrations_
.find(registration_handle_id
);
589 if (found
!= registrations_
.end())
590 found
->second
->OnUpdateFound();
593 void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
596 const ServiceWorkerObjectInfo
& info
,
597 bool should_notify_controllerchange
) {
598 TRACE_EVENT2("ServiceWorker",
599 "ServiceWorkerDispatcher::OnSetControllerServiceWorker",
600 "Thread ID", thread_id
,
601 "Provider ID", provider_id
);
603 ProviderContextMap::iterator provider
= provider_contexts_
.find(provider_id
);
604 if (provider
!= provider_contexts_
.end()) {
605 worker_to_provider_
.erase(provider
->second
->controller_handle_id());
606 if (info
.handle_id
!= kInvalidServiceWorkerHandleId
)
607 worker_to_provider_
[info
.handle_id
] = provider
->second
;
608 provider
->second
->OnSetControllerServiceWorker(info
);
611 ProviderClientMap::iterator found
= provider_clients_
.find(provider_id
);
612 if (found
!= provider_clients_
.end()) {
613 // Populate the .controller field with the new worker object.
614 found
->second
->setController(GetServiceWorker(info
, false),
615 should_notify_controllerchange
);
619 void ServiceWorkerDispatcher::OnPostMessage(
622 const base::string16
& message
,
623 const std::vector
<TransferredMessagePort
>& sent_message_ports
,
624 const std::vector
<int>& new_routing_ids
) {
625 // Make sure we're on the main document thread. (That must be the only
626 // thread we get this message)
627 DCHECK(ChildThreadImpl::current());
628 TRACE_EVENT1("ServiceWorker",
629 "ServiceWorkerDispatcher::OnPostMessage",
630 "Thread ID", thread_id
);
632 ProviderClientMap::iterator found
= provider_clients_
.find(provider_id
);
633 if (found
== provider_clients_
.end()) {
634 // For now we do no queueing for messages sent to nonexistent / unattached
639 blink::WebMessagePortChannelArray ports
=
640 WebMessagePortChannelImpl::CreatePorts(
641 sent_message_ports
, new_routing_ids
,
642 base::ThreadTaskRunnerHandle::Get());
644 found
->second
->dispatchMessageEvent(message
, ports
);
647 void ServiceWorkerDispatcher::AddServiceWorker(
648 int handle_id
, WebServiceWorkerImpl
* worker
) {
649 DCHECK(!ContainsKey(service_workers_
, handle_id
));
650 service_workers_
[handle_id
] = worker
;
653 void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id
) {
654 DCHECK(ContainsKey(service_workers_
, handle_id
));
655 service_workers_
.erase(handle_id
);
658 void ServiceWorkerDispatcher::AddServiceWorkerRegistration(
659 int registration_handle_id
,
660 WebServiceWorkerRegistrationImpl
* registration
) {
661 DCHECK(!ContainsKey(registrations_
, registration_handle_id
));
662 registrations_
[registration_handle_id
] = registration
;
665 void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
666 int registration_handle_id
) {
667 DCHECK(ContainsKey(registrations_
, registration_handle_id
));
668 registrations_
.erase(registration_handle_id
);
671 WebServiceWorkerRegistrationImpl
*
672 ServiceWorkerDispatcher::FindOrCreateRegistration(
673 const ServiceWorkerRegistrationObjectInfo
& info
,
674 const ServiceWorkerVersionAttributes
& attrs
) {
675 RegistrationObjectMap::iterator found
= registrations_
.find(info
.handle_id
);
676 if (found
!= registrations_
.end()) {
677 ServiceWorkerRegistrationHandleReference::Adopt(info
,
678 thread_safe_sender_
.get());
679 ServiceWorkerHandleReference::Adopt(attrs
.installing
,
680 thread_safe_sender_
.get());
681 ServiceWorkerHandleReference::Adopt(attrs
.waiting
,
682 thread_safe_sender_
.get());
683 ServiceWorkerHandleReference::Adopt(attrs
.active
,
684 thread_safe_sender_
.get());
685 return found
->second
;
688 bool adopt_handle
= true;
689 WebServiceWorkerRegistrationImpl
* registration
=
690 CreateServiceWorkerRegistration(info
, adopt_handle
);
691 registration
->SetInstalling(GetServiceWorker(attrs
.installing
, adopt_handle
));
692 registration
->SetWaiting(GetServiceWorker(attrs
.waiting
, adopt_handle
));
693 registration
->SetActive(GetServiceWorker(attrs
.active
, adopt_handle
));
697 } // namespace content