cc: Make picture pile base thread safe.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_dispatcher_host.cc
blob802ea30c83ba4dc27301cd75e9dd7945346223aa
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/browser/service_worker/service_worker_dispatcher_host.h"
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/message_port_message_filter.h"
11 #include "content/browser/message_port_service.h"
12 #include "content/browser/service_worker/embedded_worker_registry.h"
13 #include "content/browser/service_worker/service_worker_context_core.h"
14 #include "content/browser/service_worker/service_worker_context_wrapper.h"
15 #include "content/browser/service_worker/service_worker_handle.h"
16 #include "content/browser/service_worker/service_worker_registration.h"
17 #include "content/browser/service_worker/service_worker_registration_handle.h"
18 #include "content/browser/service_worker/service_worker_utils.h"
19 #include "content/common/service_worker/embedded_worker_messages.h"
20 #include "content/common/service_worker/service_worker_messages.h"
21 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/common/content_client.h"
23 #include "ipc/ipc_message_macros.h"
24 #include "net/base/net_util.h"
25 #include "third_party/WebKit/public/platform/WebServiceWorkerError.h"
26 #include "url/gurl.h"
28 using blink::WebServiceWorkerError;
30 namespace content {
32 namespace {
34 const char kShutdownErrorMessage[] =
35 "The Service Worker system has shutdown.";
36 const char kDisabledErrorMessage[] = "The browser has disabled Service Worker.";
38 const uint32 kFilteredMessageClasses[] = {
39 ServiceWorkerMsgStart,
40 EmbeddedWorkerMsgStart,
43 bool AllOriginsMatch(const GURL& url_a, const GURL& url_b, const GURL& url_c) {
44 return url_a.GetOrigin() == url_b.GetOrigin() &&
45 url_a.GetOrigin() == url_c.GetOrigin();
48 // TODO(dominicc): When crbug.com/362214 is fixed use that to be
49 // consistent with Blink's
50 // SecurityOrigin::canAccessFeatureRequiringSecureOrigin.
51 bool OriginCanAccessServiceWorkers(const GURL& url) {
52 return url.SchemeIsSecure() || net::IsLocalhost(url.host());
55 bool CanRegisterServiceWorker(const GURL& document_url,
56 const GURL& pattern,
57 const GURL& script_url) {
58 return AllOriginsMatch(document_url, pattern, script_url) &&
59 OriginCanAccessServiceWorkers(document_url);
62 bool CanUnregisterServiceWorker(const GURL& document_url,
63 const GURL& pattern) {
64 return document_url.GetOrigin() == pattern.GetOrigin() &&
65 OriginCanAccessServiceWorkers(document_url);
68 bool CanGetRegistration(const GURL& document_url,
69 const GURL& given_document_url) {
70 return document_url.GetOrigin() == given_document_url.GetOrigin() &&
71 OriginCanAccessServiceWorkers(document_url);
74 } // namespace
76 ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
77 int render_process_id,
78 MessagePortMessageFilter* message_port_message_filter,
79 ResourceContext* resource_context)
80 : BrowserMessageFilter(kFilteredMessageClasses,
81 arraysize(kFilteredMessageClasses)),
82 render_process_id_(render_process_id),
83 message_port_message_filter_(message_port_message_filter),
84 resource_context_(resource_context),
85 channel_ready_(false) {
88 ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
89 if (GetContext()) {
90 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_);
91 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
92 render_process_id_);
96 void ServiceWorkerDispatcherHost::Init(
97 ServiceWorkerContextWrapper* context_wrapper) {
98 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
99 BrowserThread::PostTask(
100 BrowserThread::IO, FROM_HERE,
101 base::Bind(&ServiceWorkerDispatcherHost::Init,
102 this, make_scoped_refptr(context_wrapper)));
103 return;
105 context_wrapper_ = context_wrapper;
106 GetContext()->embedded_worker_registry()->AddChildProcessSender(
107 render_process_id_, this);
110 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender* sender) {
111 TRACE_EVENT0("ServiceWorker",
112 "ServiceWorkerDispatcherHost::OnFilterAdded");
113 BrowserMessageFilter::OnFilterAdded(sender);
114 channel_ready_ = true;
115 std::vector<IPC::Message*> messages;
116 pending_messages_.release(&messages);
117 for (size_t i = 0; i < messages.size(); ++i) {
118 BrowserMessageFilter::Send(messages[i]);
122 void ServiceWorkerDispatcherHost::OnDestruct() const {
123 BrowserThread::DeleteOnIOThread::Destruct(this);
126 bool ServiceWorkerDispatcherHost::OnMessageReceived(
127 const IPC::Message& message) {
128 bool handled = true;
129 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost, message)
130 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker,
131 OnRegisterServiceWorker)
132 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker,
133 OnUnregisterServiceWorker)
134 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration,
135 OnGetRegistration)
136 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated,
137 OnProviderCreated)
138 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
139 OnProviderDestroyed)
140 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId,
141 OnSetHostedVersionId)
142 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
143 OnPostMessageToWorker)
144 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection,
145 OnWorkerReadyForInspection)
146 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
147 OnWorkerScriptLoaded)
148 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
149 OnWorkerScriptLoadFailed)
150 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
151 OnWorkerStarted)
152 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
153 OnWorkerStopped)
154 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload,
155 OnPausedAfterDownload)
156 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException,
157 OnReportException)
158 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage,
159 OnReportConsoleMessage)
160 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
161 OnIncrementServiceWorkerRefCount)
162 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
163 OnDecrementServiceWorkerRefCount)
164 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount,
165 OnIncrementRegistrationRefCount)
166 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount,
167 OnDecrementRegistrationRefCount)
168 IPC_MESSAGE_UNHANDLED(handled = false)
169 IPC_END_MESSAGE_MAP()
171 if (!handled && GetContext()) {
172 handled =
173 GetContext()->embedded_worker_registry()->OnMessageReceived(message);
174 if (!handled)
175 BadMessageReceived();
178 return handled;
181 bool ServiceWorkerDispatcherHost::Send(IPC::Message* message) {
182 if (channel_ready_) {
183 BrowserMessageFilter::Send(message);
184 // Don't bother passing through Send()'s result: it's not reliable.
185 return true;
188 pending_messages_.push_back(message);
189 return true;
192 ServiceWorkerRegistrationHandle*
193 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
194 int provider_id,
195 ServiceWorkerRegistration* registration) {
196 ServiceWorkerRegistrationHandle* handle =
197 FindRegistrationHandle(provider_id, registration->id());
198 if (handle) {
199 handle->IncrementRefCount();
200 return handle;
203 scoped_ptr<ServiceWorkerRegistrationHandle> new_handle(
204 new ServiceWorkerRegistrationHandle(
205 GetContext()->AsWeakPtr(), this, provider_id, registration));
206 handle = new_handle.get();
207 RegisterServiceWorkerRegistrationHandle(new_handle.Pass());
208 return handle;
211 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
212 scoped_ptr<ServiceWorkerHandle> handle) {
213 int handle_id = handle->handle_id();
214 handles_.AddWithID(handle.release(), handle_id);
217 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
218 scoped_ptr<ServiceWorkerRegistrationHandle> handle) {
219 int handle_id = handle->handle_id();
220 registration_handles_.AddWithID(handle.release(), handle_id);
223 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
224 int thread_id,
225 int request_id,
226 int provider_id,
227 const GURL& pattern,
228 const GURL& script_url) {
229 TRACE_EVENT0("ServiceWorker",
230 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
231 if (!GetContext()) {
232 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
233 thread_id,
234 request_id,
235 WebServiceWorkerError::ErrorTypeAbort,
236 base::ASCIIToUTF16(kShutdownErrorMessage)));
237 return;
240 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
241 render_process_id_, provider_id);
242 if (!provider_host) {
243 BadMessageReceived();
244 return;
246 if (!provider_host->IsContextAlive()) {
247 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
248 thread_id,
249 request_id,
250 WebServiceWorkerError::ErrorTypeAbort,
251 base::ASCIIToUTF16(kShutdownErrorMessage)));
252 return;
255 if (!CanRegisterServiceWorker(
256 provider_host->document_url(), pattern, script_url)) {
257 BadMessageReceived();
258 return;
261 if (!GetContentClient()->browser()->AllowServiceWorker(
262 pattern, provider_host->topmost_frame_url(), resource_context_)) {
263 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
264 thread_id,
265 request_id,
266 WebServiceWorkerError::ErrorTypeDisabled,
267 base::ASCIIToUTF16(kDisabledErrorMessage)));
268 return;
271 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
272 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
273 request_id,
274 "Pattern", pattern.spec(),
275 "Script URL", script_url.spec());
276 GetContext()->RegisterServiceWorker(
277 pattern,
278 script_url,
279 provider_host,
280 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete,
281 this,
282 thread_id,
283 provider_id,
284 request_id));
287 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
288 int thread_id,
289 int request_id,
290 int provider_id,
291 const GURL& pattern) {
292 TRACE_EVENT0("ServiceWorker",
293 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
294 if (!GetContext()) {
295 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
296 thread_id,
297 request_id,
298 blink::WebServiceWorkerError::ErrorTypeAbort,
299 base::ASCIIToUTF16(kShutdownErrorMessage)));
300 return;
303 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
304 render_process_id_, provider_id);
305 if (!provider_host) {
306 BadMessageReceived();
307 return;
309 if (!provider_host->IsContextAlive()) {
310 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
311 thread_id,
312 request_id,
313 blink::WebServiceWorkerError::ErrorTypeAbort,
314 base::ASCIIToUTF16(kShutdownErrorMessage)));
315 return;
318 if (!CanUnregisterServiceWorker(provider_host->document_url(), pattern)) {
319 BadMessageReceived();
320 return;
323 if (!GetContentClient()->browser()->AllowServiceWorker(
324 pattern, provider_host->topmost_frame_url(), resource_context_)) {
325 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
326 thread_id,
327 request_id,
328 WebServiceWorkerError::ErrorTypeDisabled,
329 base::ASCIIToUTF16(kDisabledErrorMessage)));
330 return;
333 TRACE_EVENT_ASYNC_BEGIN1(
334 "ServiceWorker",
335 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
336 request_id,
337 "Pattern", pattern.spec());
338 GetContext()->UnregisterServiceWorker(
339 pattern,
340 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete,
341 this,
342 thread_id,
343 request_id));
346 void ServiceWorkerDispatcherHost::OnGetRegistration(
347 int thread_id,
348 int request_id,
349 int provider_id,
350 const GURL& document_url) {
351 TRACE_EVENT0("ServiceWorker",
352 "ServiceWorkerDispatcherHost::OnGetRegistration");
353 if (!GetContext()) {
354 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
355 thread_id,
356 request_id,
357 blink::WebServiceWorkerError::ErrorTypeAbort,
358 base::ASCIIToUTF16(kShutdownErrorMessage)));
359 return;
362 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
363 render_process_id_, provider_id);
364 if (!provider_host) {
365 BadMessageReceived();
366 return;
368 if (!provider_host->IsContextAlive()) {
369 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
370 thread_id,
371 request_id,
372 blink::WebServiceWorkerError::ErrorTypeAbort,
373 base::ASCIIToUTF16(kShutdownErrorMessage)));
374 return;
377 if (!CanGetRegistration(provider_host->document_url(), document_url)) {
378 BadMessageReceived();
379 return;
382 if (!GetContentClient()->browser()->AllowServiceWorker(
383 provider_host->document_url(),
384 provider_host->topmost_frame_url(),
385 resource_context_)) {
386 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
387 thread_id,
388 request_id,
389 WebServiceWorkerError::ErrorTypeDisabled,
390 base::ASCIIToUTF16(kDisabledErrorMessage)));
391 return;
394 DCHECK_CURRENTLY_ON(BrowserThread::IO);
395 if (GetContext()->storage()->IsDisabled()) {
396 SendGetRegistrationError(thread_id, request_id, SERVICE_WORKER_ERROR_ABORT);
397 return;
400 TRACE_EVENT_ASYNC_BEGIN1(
401 "ServiceWorker",
402 "ServiceWorkerDispatcherHost::GetRegistration",
403 request_id,
404 "Document URL", document_url.spec());
406 GetContext()->storage()->FindRegistrationForDocument(
407 document_url,
408 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete,
409 this,
410 thread_id,
411 provider_id,
412 request_id));
415 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
416 int handle_id,
417 const base::string16& message,
418 const std::vector<int>& sent_message_port_ids) {
419 TRACE_EVENT0("ServiceWorker",
420 "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
421 if (!GetContext())
422 return;
424 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
425 if (!handle) {
426 BadMessageReceived();
427 return;
430 std::vector<int> new_routing_ids;
431 message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
432 sent_message_port_ids, &new_routing_ids);
433 handle->version()->SendMessage(
434 ServiceWorkerMsg_MessageToWorker(message,
435 sent_message_port_ids,
436 new_routing_ids),
437 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
440 void ServiceWorkerDispatcherHost::OnProviderCreated(int provider_id) {
441 TRACE_EVENT0("ServiceWorker",
442 "ServiceWorkerDispatcherHost::OnProviderCreated");
443 if (!GetContext())
444 return;
445 if (GetContext()->GetProviderHost(render_process_id_, provider_id)) {
446 BadMessageReceived();
447 return;
449 scoped_ptr<ServiceWorkerProviderHost> provider_host(
450 new ServiceWorkerProviderHost(
451 render_process_id_, provider_id, GetContext()->AsWeakPtr(), this));
452 GetContext()->AddProviderHost(provider_host.Pass());
455 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
456 TRACE_EVENT0("ServiceWorker",
457 "ServiceWorkerDispatcherHost::OnProviderDestroyed");
458 if (!GetContext())
459 return;
460 if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) {
461 BadMessageReceived();
462 return;
464 GetContext()->RemoveProviderHost(render_process_id_, provider_id);
467 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
468 int provider_id, int64 version_id) {
469 TRACE_EVENT0("ServiceWorker",
470 "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
471 if (!GetContext())
472 return;
473 ServiceWorkerProviderHost* provider_host =
474 GetContext()->GetProviderHost(render_process_id_, provider_id);
475 if (!provider_host) {
476 BadMessageReceived();
477 return;
479 if (!provider_host->IsContextAlive())
480 return;
481 if (!provider_host->SetHostedVersionId(version_id))
482 BadMessageReceived();
485 ServiceWorkerRegistrationHandle*
486 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
487 int64 registration_id) {
488 for (IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer>::iterator
489 iter(&registration_handles_);
490 !iter.IsAtEnd();
491 iter.Advance()) {
492 ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
493 DCHECK(handle);
494 if (handle->provider_id() == provider_id && handle->registration() &&
495 handle->registration()->id() == registration_id) {
496 return handle;
499 return NULL;
502 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
503 int provider_id,
504 ServiceWorkerRegistration* registration,
505 ServiceWorkerRegistrationObjectInfo* info,
506 ServiceWorkerVersionAttributes* attrs) {
507 ServiceWorkerRegistrationHandle* handle =
508 GetOrCreateRegistrationHandle(provider_id, registration);
509 *info = handle->GetObjectInfo();
511 attrs->installing = handle->CreateServiceWorkerHandleAndPass(
512 registration->installing_version());
513 attrs->waiting = handle->CreateServiceWorkerHandleAndPass(
514 registration->waiting_version());
515 attrs->active = handle->CreateServiceWorkerHandleAndPass(
516 registration->active_version());
519 void ServiceWorkerDispatcherHost::RegistrationComplete(
520 int thread_id,
521 int provider_id,
522 int request_id,
523 ServiceWorkerStatusCode status,
524 int64 registration_id) {
525 if (!GetContext())
526 return;
528 if (status != SERVICE_WORKER_OK) {
529 SendRegistrationError(thread_id, request_id, status);
530 return;
533 ServiceWorkerRegistration* registration =
534 GetContext()->GetLiveRegistration(registration_id);
535 DCHECK(registration);
537 ServiceWorkerRegistrationObjectInfo info;
538 ServiceWorkerVersionAttributes attrs;
539 GetRegistrationObjectInfoAndVersionAttributes(
540 provider_id, registration, &info, &attrs);
542 Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
543 thread_id, request_id, info, attrs));
544 TRACE_EVENT_ASYNC_END1("ServiceWorker",
545 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
546 request_id,
547 "Registration ID",
548 registration_id);
551 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
552 int embedded_worker_id) {
553 TRACE_EVENT0("ServiceWorker",
554 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
555 if (!GetContext())
556 return;
557 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
558 if (!registry->CanHandle(embedded_worker_id))
559 return;
560 registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id);
563 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
564 int embedded_worker_id,
565 int thread_id) {
566 TRACE_EVENT0("ServiceWorker",
567 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
568 if (!GetContext())
569 return;
570 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
571 if (!registry->CanHandle(embedded_worker_id))
572 return;
573 registry->OnWorkerScriptLoaded(
574 render_process_id_, thread_id, embedded_worker_id);
577 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
578 int embedded_worker_id) {
579 TRACE_EVENT0("ServiceWorker",
580 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
581 if (!GetContext())
582 return;
583 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
584 if (!registry->CanHandle(embedded_worker_id))
585 return;
586 registry->OnWorkerScriptLoadFailed(render_process_id_, embedded_worker_id);
589 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id) {
590 TRACE_EVENT0("ServiceWorker",
591 "ServiceWorkerDispatcherHost::OnWorkerStarted");
592 if (!GetContext())
593 return;
594 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
595 if (!registry->CanHandle(embedded_worker_id))
596 return;
597 registry->OnWorkerStarted(render_process_id_, embedded_worker_id);
600 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id) {
601 TRACE_EVENT0("ServiceWorker",
602 "ServiceWorkerDispatcherHost::OnWorkerStopped");
603 if (!GetContext())
604 return;
605 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
606 if (!registry->CanHandle(embedded_worker_id))
607 return;
608 registry->OnWorkerStopped(render_process_id_, embedded_worker_id);
611 void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
612 int embedded_worker_id) {
613 TRACE_EVENT0("ServiceWorker",
614 "ServiceWorkerDispatcherHost::OnPausedAfterDownload");
615 if (!GetContext())
616 return;
617 GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
618 render_process_id_, embedded_worker_id);
621 void ServiceWorkerDispatcherHost::OnReportException(
622 int embedded_worker_id,
623 const base::string16& error_message,
624 int line_number,
625 int column_number,
626 const GURL& source_url) {
627 TRACE_EVENT0("ServiceWorker",
628 "ServiceWorkerDispatcherHost::OnReportException");
629 if (!GetContext())
630 return;
631 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
632 if (!registry->CanHandle(embedded_worker_id))
633 return;
634 registry->OnReportException(embedded_worker_id,
635 error_message,
636 line_number,
637 column_number,
638 source_url);
641 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
642 int embedded_worker_id,
643 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params& params) {
644 TRACE_EVENT0("ServiceWorker",
645 "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
646 if (!GetContext())
647 return;
648 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
649 if (!registry->CanHandle(embedded_worker_id))
650 return;
651 registry->OnReportConsoleMessage(embedded_worker_id,
652 params.source_identifier,
653 params.message_level,
654 params.message,
655 params.line_number,
656 params.source_url);
659 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
660 int handle_id) {
661 TRACE_EVENT0("ServiceWorker",
662 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
663 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
664 if (!handle) {
665 BadMessageReceived();
666 return;
668 handle->IncrementRefCount();
671 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
672 int handle_id) {
673 TRACE_EVENT0("ServiceWorker",
674 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
675 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
676 if (!handle) {
677 BadMessageReceived();
678 return;
680 handle->DecrementRefCount();
681 if (handle->HasNoRefCount())
682 handles_.Remove(handle_id);
685 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
686 int registration_handle_id) {
687 TRACE_EVENT0("ServiceWorker",
688 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
689 ServiceWorkerRegistrationHandle* handle =
690 registration_handles_.Lookup(registration_handle_id);
691 if (!handle) {
692 BadMessageReceived();
693 return;
695 handle->IncrementRefCount();
698 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
699 int registration_handle_id) {
700 TRACE_EVENT0("ServiceWorker",
701 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
702 ServiceWorkerRegistrationHandle* handle =
703 registration_handles_.Lookup(registration_handle_id);
704 if (!handle) {
705 BadMessageReceived();
706 return;
708 handle->DecrementRefCount();
709 if (handle->HasNoRefCount())
710 registration_handles_.Remove(registration_handle_id);
713 void ServiceWorkerDispatcherHost::UnregistrationComplete(
714 int thread_id,
715 int request_id,
716 ServiceWorkerStatusCode status) {
717 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
718 SendUnregistrationError(thread_id, request_id, status);
719 return;
721 const bool is_success = (status == SERVICE_WORKER_OK);
722 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id,
723 request_id,
724 is_success));
725 TRACE_EVENT_ASYNC_END1(
726 "ServiceWorker",
727 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
728 request_id,
729 "Status", status);
732 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
733 int thread_id,
734 int provider_id,
735 int request_id,
736 ServiceWorkerStatusCode status,
737 const scoped_refptr<ServiceWorkerRegistration>& registration) {
738 TRACE_EVENT_ASYNC_END1("ServiceWorker",
739 "ServiceWorkerDispatcherHost::GetRegistration",
740 request_id,
741 "Registration ID",
742 registration.get() ? registration->id()
743 : kInvalidServiceWorkerRegistrationId);
744 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
745 SendGetRegistrationError(thread_id, request_id, status);
746 return;
749 ServiceWorkerRegistrationObjectInfo info;
750 ServiceWorkerVersionAttributes attrs;
751 if (status == SERVICE_WORKER_OK) {
752 DCHECK(registration.get());
753 if (!registration->is_uninstalling()) {
754 GetRegistrationObjectInfoAndVersionAttributes(
755 provider_id, registration.get(), &info, &attrs);
759 Send(new ServiceWorkerMsg_DidGetRegistration(
760 thread_id, request_id, info, attrs));
763 void ServiceWorkerDispatcherHost::SendRegistrationError(
764 int thread_id,
765 int request_id,
766 ServiceWorkerStatusCode status) {
767 base::string16 error_message;
768 blink::WebServiceWorkerError::ErrorType error_type;
769 GetServiceWorkerRegistrationStatusResponse(
770 status, &error_type, &error_message);
771 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
772 thread_id, request_id, error_type, error_message));
775 void ServiceWorkerDispatcherHost::SendUnregistrationError(
776 int thread_id,
777 int request_id,
778 ServiceWorkerStatusCode status) {
779 base::string16 error_message;
780 blink::WebServiceWorkerError::ErrorType error_type;
781 GetServiceWorkerRegistrationStatusResponse(
782 status, &error_type, &error_message);
783 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
784 thread_id, request_id, error_type, error_message));
787 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
788 int thread_id,
789 int request_id,
790 ServiceWorkerStatusCode status) {
791 base::string16 error_message;
792 blink::WebServiceWorkerError::ErrorType error_type;
793 GetServiceWorkerRegistrationStatusResponse(
794 status, &error_type, &error_message);
795 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
796 thread_id, request_id, error_type, error_message));
799 ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
800 return context_wrapper_->context();
803 } // namespace content