Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / content / child / service_worker / service_worker_dispatcher.cc
blobfbf1e310b61eab2100b59839b9abaa2949c295f4
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;
33 namespace content {
35 namespace {
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();
46 } // namespace
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) {
61 bool handled = true;
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,
72 OnUnregistered)
73 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistration,
74 OnDidGetRegistration)
75 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrations,
76 OnDidGetRegistrations)
77 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrationForReady,
78 OnDidGetRegistrationForReady)
79 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError,
80 OnRegistrationError)
81 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUpdateError,
82 OnUpdateError)
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,
94 OnUpdateFound)
95 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
96 OnSetControllerServiceWorker)
97 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
98 OnPostMessage)
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(
109 int provider_id,
110 const GURL& pattern,
111 const GURL& script_url,
112 WebServiceWorkerRegistrationCallbacks* callbacks) {
113 DCHECK(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.";
121 callbacks->onError(
122 WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity,
123 blink::WebString::fromUTF8(error_message)));
124 return;
127 int request_id = pending_registration_callbacks_.Add(callbacks);
128 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
129 "ServiceWorkerDispatcher::RegisterServiceWorker",
130 request_id,
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(
138 int provider_id,
139 int64 registration_id,
140 WebServiceWorkerUpdateCallbacks* callbacks) {
141 DCHECK(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(
148 int provider_id,
149 int64 registration_id,
150 WebServiceWorkerUnregistrationCallbacks* callbacks) {
151 DCHECK(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(
161 int provider_id,
162 const GURL& document_url,
163 WebServiceWorkerGetRegistrationCallbacks* callbacks) {
164 DCHECK(callbacks);
166 if (document_url.possibly_invalid_spec().size() > GetMaxURLChars()) {
167 scoped_ptr<WebServiceWorkerGetRegistrationCallbacks> owned_callbacks(
168 callbacks);
169 std::string error_message(kServiceWorkerGetRegistrationErrorPrefix);
170 error_message += "The provided documentURL is too long.";
171 callbacks->onError(
172 WebServiceWorkerError(WebServiceWorkerError::ErrorTypeSecurity,
173 blink::WebString::fromUTF8(error_message)));
174 return;
177 int request_id = pending_get_registration_callbacks_.Add(callbacks);
178 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
179 "ServiceWorkerDispatcher::GetRegistration",
180 request_id,
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(
187 int provider_id,
188 WebServiceWorkerGetRegistrationsCallbacks* callbacks) {
189 DCHECK(callbacks);
191 int request_id = pending_get_registrations_callbacks_.Add(callbacks);
192 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker",
193 "ServiceWorkerDispatcher::GetRegistrations",
194 request_id);
195 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistrations(
196 CurrentWorkerId(), request_id, provider_id));
199 void ServiceWorkerDispatcher::GetRegistrationForReady(
200 int provider_id,
201 WebServiceWorkerGetRegistrationForReadyCallbacks* callbacks) {
202 int request_id = get_for_ready_callbacks_.Add(callbacks);
203 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker",
204 "ServiceWorkerDispatcher::GetRegistrationForReady",
205 request_id);
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(
226 int provider_id,
227 blink::WebServiceWorkerProviderClient* client) {
228 DCHECK(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);
255 return dispatcher;
258 ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
259 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
260 return NULL;
261 return static_cast<ServiceWorkerDispatcher*>(
262 g_dispatcher_tls.Pointer()->Get());
265 void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() {
266 delete this;
269 WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker(
270 const ServiceWorkerObjectInfo& info,
271 bool adopt_handle) {
272 if (info.handle_id == kInvalidServiceWorkerHandleId)
273 return NULL;
275 WorkerObjectMap::iterator existing_worker =
276 service_workers_.find(info.handle_id);
278 if (existing_worker != service_workers_.end()) {
279 if (adopt_handle) {
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 =
288 adopt_handle
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(
322 int thread_id,
323 int provider_id,
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())
330 return;
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(
338 int thread_id,
339 int provider_id,
340 const ServiceWorkerRegistrationObjectInfo& info,
341 const ServiceWorkerVersionAttributes& attrs) {
342 ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
343 if (provider == provider_contexts_.end())
344 return;
345 provider->second->OnAssociateRegistration(info, attrs);
348 void ServiceWorkerDispatcher::OnDisassociateRegistration(
349 int thread_id,
350 int provider_id) {
351 ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
352 if (provider == provider_contexts_.end())
353 return;
354 provider->second->OnDisassociateRegistration();
357 void ServiceWorkerDispatcher::OnRegistered(
358 int thread_id,
359 int request_id,
360 const ServiceWorkerRegistrationObjectInfo& info,
361 const ServiceWorkerVersionAttributes& attrs) {
362 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
363 "ServiceWorkerDispatcher::RegisterServiceWorker",
364 request_id,
365 "OnRegistered");
366 TRACE_EVENT_ASYNC_END0("ServiceWorker",
367 "ServiceWorkerDispatcher::RegisterServiceWorker",
368 request_id);
369 WebServiceWorkerRegistrationCallbacks* callbacks =
370 pending_registration_callbacks_.Lookup(request_id);
371 DCHECK(callbacks);
372 if (!callbacks)
373 return;
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",
385 request_id);
386 WebServiceWorkerUpdateCallbacks* callbacks =
387 pending_update_callbacks_.Lookup(request_id);
388 DCHECK(callbacks);
389 if (!callbacks)
390 return;
392 callbacks->onSuccess();
393 pending_update_callbacks_.Remove(request_id);
396 void ServiceWorkerDispatcher::OnUnregistered(int thread_id,
397 int request_id,
398 bool is_success) {
399 TRACE_EVENT_ASYNC_STEP_INTO0(
400 "ServiceWorker",
401 "ServiceWorkerDispatcher::UnregisterServiceWorker",
402 request_id,
403 "OnUnregistered");
404 TRACE_EVENT_ASYNC_END0("ServiceWorker",
405 "ServiceWorkerDispatcher::UnregisterServiceWorker",
406 request_id);
407 WebServiceWorkerUnregistrationCallbacks* callbacks =
408 pending_unregistration_callbacks_.Lookup(request_id);
409 DCHECK(callbacks);
410 if (!callbacks)
411 return;
412 callbacks->onSuccess(is_success);
413 pending_unregistration_callbacks_.Remove(request_id);
416 void ServiceWorkerDispatcher::OnDidGetRegistration(
417 int thread_id,
418 int request_id,
419 const ServiceWorkerRegistrationObjectInfo& info,
420 const ServiceWorkerVersionAttributes& attrs) {
421 TRACE_EVENT_ASYNC_STEP_INTO0(
422 "ServiceWorker",
423 "ServiceWorkerDispatcher::GetRegistration",
424 request_id,
425 "OnDidGetRegistration");
426 TRACE_EVENT_ASYNC_END0("ServiceWorker",
427 "ServiceWorkerDispatcher::GetRegistration",
428 request_id);
429 WebServiceWorkerGetRegistrationCallbacks* callbacks =
430 pending_get_registration_callbacks_.Lookup(request_id);
431 DCHECK(callbacks);
432 if (!callbacks)
433 return;
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(
444 int thread_id,
445 int request_id,
446 const std::vector<ServiceWorkerRegistrationObjectInfo>& infos,
447 const std::vector<ServiceWorkerVersionAttributes>& attrs) {
448 TRACE_EVENT_ASYNC_STEP_INTO0(
449 "ServiceWorker",
450 "ServiceWorkerDispatcher::GetRegistrations",
451 request_id,
452 "OnDidGetRegistrations");
453 TRACE_EVENT_ASYNC_END0("ServiceWorker",
454 "ServiceWorkerDispatcher::GetRegistrations",
455 request_id);
457 WebServiceWorkerGetRegistrationsCallbacks* callbacks =
458 pending_get_registrations_callbacks_.Lookup(request_id);
459 DCHECK(callbacks);
460 if (!callbacks)
461 return;
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
474 // handles instead.
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(
484 int thread_id,
485 int request_id,
486 const ServiceWorkerRegistrationObjectInfo& info,
487 const ServiceWorkerVersionAttributes& attrs) {
488 TRACE_EVENT_ASYNC_STEP_INTO0(
489 "ServiceWorker",
490 "ServiceWorkerDispatcher::GetRegistrationForReady",
491 request_id,
492 "OnDidGetRegistrationForReady");
493 TRACE_EVENT_ASYNC_END0("ServiceWorker",
494 "ServiceWorkerDispatcher::GetRegistrationForReady",
495 request_id);
496 WebServiceWorkerGetRegistrationForReadyCallbacks* callbacks =
497 get_for_ready_callbacks_.Lookup(request_id);
498 DCHECK(callbacks);
499 if (!callbacks)
500 return;
502 callbacks->onSuccess(AdoptRegistration(info, attrs)->CreateHandle());
503 get_for_ready_callbacks_.Remove(request_id);
506 void ServiceWorkerDispatcher::OnRegistrationError(
507 int thread_id,
508 int request_id,
509 WebServiceWorkerError::ErrorType error_type,
510 const base::string16& message) {
511 TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
512 "ServiceWorkerDispatcher::RegisterServiceWorker",
513 request_id,
514 "OnRegistrationError");
515 TRACE_EVENT_ASYNC_END0("ServiceWorker",
516 "ServiceWorkerDispatcher::RegisterServiceWorker",
517 request_id);
518 WebServiceWorkerRegistrationCallbacks* callbacks =
519 pending_registration_callbacks_.Lookup(request_id);
520 DCHECK(callbacks);
521 if (!callbacks)
522 return;
524 callbacks->onError(WebServiceWorkerError(error_type, message));
525 pending_registration_callbacks_.Remove(request_id);
528 void ServiceWorkerDispatcher::OnUpdateError(
529 int thread_id,
530 int request_id,
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",
538 request_id);
539 WebServiceWorkerUpdateCallbacks* callbacks =
540 pending_update_callbacks_.Lookup(request_id);
541 DCHECK(callbacks);
542 if (!callbacks)
543 return;
545 callbacks->onError(WebServiceWorkerError(error_type, message));
546 pending_update_callbacks_.Remove(request_id);
549 void ServiceWorkerDispatcher::OnUnregistrationError(
550 int thread_id,
551 int request_id,
552 WebServiceWorkerError::ErrorType error_type,
553 const base::string16& message) {
554 TRACE_EVENT_ASYNC_STEP_INTO0(
555 "ServiceWorker",
556 "ServiceWorkerDispatcher::UnregisterServiceWorker",
557 request_id,
558 "OnUnregistrationError");
559 TRACE_EVENT_ASYNC_END0("ServiceWorker",
560 "ServiceWorkerDispatcher::UnregisterServiceWorker",
561 request_id);
562 WebServiceWorkerUnregistrationCallbacks* callbacks =
563 pending_unregistration_callbacks_.Lookup(request_id);
564 DCHECK(callbacks);
565 if (!callbacks)
566 return;
568 callbacks->onError(WebServiceWorkerError(error_type, message));
569 pending_unregistration_callbacks_.Remove(request_id);
572 void ServiceWorkerDispatcher::OnGetRegistrationError(
573 int thread_id,
574 int request_id,
575 WebServiceWorkerError::ErrorType error_type,
576 const base::string16& message) {
577 TRACE_EVENT_ASYNC_STEP_INTO0(
578 "ServiceWorker",
579 "ServiceWorkerDispatcher::GetRegistration",
580 request_id,
581 "OnGetRegistrationError");
582 TRACE_EVENT_ASYNC_END0("ServiceWorker",
583 "ServiceWorkerDispatcher::GetRegistration",
584 request_id);
585 WebServiceWorkerGetRegistrationCallbacks* callbacks =
586 pending_get_registration_callbacks_.Lookup(request_id);
587 DCHECK(callbacks);
588 if (!callbacks)
589 return;
591 callbacks->onError(WebServiceWorkerError(error_type, message));
592 pending_get_registration_callbacks_.Remove(request_id);
595 void ServiceWorkerDispatcher::OnGetRegistrationsError(
596 int thread_id,
597 int request_id,
598 WebServiceWorkerError::ErrorType error_type,
599 const base::string16& message) {
600 TRACE_EVENT_ASYNC_STEP_INTO0(
601 "ServiceWorker",
602 "ServiceWorkerDispatcher::GetRegistrations",
603 request_id,
604 "OnGetRegistrationsError");
605 TRACE_EVENT_ASYNC_END0("ServiceWorker",
606 "ServiceWorkerDispatcher::GetRegistrations",
607 request_id);
608 WebServiceWorkerGetRegistrationsCallbacks* callbacks =
609 pending_get_registrations_callbacks_.Lookup(request_id);
610 DCHECK(callbacks);
611 if (!callbacks)
612 return;
614 callbacks->onError(WebServiceWorkerError(error_type, message));
615 pending_get_registrations_callbacks_.Remove(request_id);
618 void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
619 int thread_id,
620 int handle_id,
621 blink::WebServiceWorkerState state) {
622 TRACE_EVENT2("ServiceWorker",
623 "ServiceWorkerDispatcher::OnServiceWorkerStateChanged",
624 "Thread ID", thread_id,
625 "State", state);
626 WorkerObjectMap::iterator worker = service_workers_.find(handle_id);
627 if (worker != service_workers_.end())
628 worker->second->OnStateChanged(state);
631 void ServiceWorkerDispatcher::OnSetVersionAttributes(
632 int thread_id,
633 int provider_id,
634 int registration_handle_id,
635 int changed_mask,
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(
656 int thread_id,
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(
667 int thread_id,
668 int provider_id,
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
700 // client.
701 return;
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,
742 bool adopt_handle) {
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