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/logging.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/trace_event/trace_event.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/common/service_worker/service_worker_types.h"
22 #include "content/public/browser/content_browser_client.h"
23 #include "content/public/common/content_client.h"
24 #include "ipc/ipc_message_macros.h"
25 #include "net/base/net_util.h"
26 #include "third_party/WebKit/public/platform/WebServiceWorkerError.h"
29 using blink::WebServiceWorkerError
;
35 const char kNoDocumentURLErrorMessage
[] =
36 "No URL is associated with the caller's document.";
37 const char kShutdownErrorMessage
[] =
38 "The Service Worker system has shutdown.";
39 const char kUserDeniedPermissionMessage
[] =
40 "The user denied permission to use Service Worker.";
42 const uint32 kFilteredMessageClasses
[] = {
43 ServiceWorkerMsgStart
,
44 EmbeddedWorkerMsgStart
,
47 bool AllOriginsMatch(const GURL
& url_a
, const GURL
& url_b
, const GURL
& url_c
) {
48 return url_a
.GetOrigin() == url_b
.GetOrigin() &&
49 url_a
.GetOrigin() == url_c
.GetOrigin();
52 // TODO(dominicc): When crbug.com/362214 is fixed use that to be
53 // consistent with Blink's
54 // SecurityOrigin::canAccessFeatureRequiringSecureOrigin.
55 bool OriginCanAccessServiceWorkers(const GURL
& url
) {
56 return url
.SchemeIsHTTPOrHTTPS() &&
57 (url
.SchemeIsSecure() || net::IsLocalhost(url
.host()));
60 bool CanRegisterServiceWorker(const GURL
& document_url
,
62 const GURL
& script_url
) {
63 DCHECK(document_url
.is_valid());
64 DCHECK(pattern
.is_valid());
65 DCHECK(script_url
.is_valid());
66 return AllOriginsMatch(document_url
, pattern
, script_url
) &&
67 OriginCanAccessServiceWorkers(document_url
) &&
68 OriginCanAccessServiceWorkers(pattern
) &&
69 OriginCanAccessServiceWorkers(script_url
);
72 bool CanUnregisterServiceWorker(const GURL
& document_url
,
73 const GURL
& pattern
) {
74 DCHECK(document_url
.is_valid());
75 DCHECK(pattern
.is_valid());
76 return document_url
.GetOrigin() == pattern
.GetOrigin() &&
77 OriginCanAccessServiceWorkers(document_url
) &&
78 OriginCanAccessServiceWorkers(pattern
);
81 bool CanGetRegistration(const GURL
& document_url
,
82 const GURL
& given_document_url
) {
83 DCHECK(document_url
.is_valid());
84 DCHECK(given_document_url
.is_valid());
85 return document_url
.GetOrigin() == given_document_url
.GetOrigin() &&
86 OriginCanAccessServiceWorkers(document_url
) &&
87 OriginCanAccessServiceWorkers(given_document_url
);
92 ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
93 int render_process_id
,
94 MessagePortMessageFilter
* message_port_message_filter
,
95 ResourceContext
* resource_context
)
96 : BrowserMessageFilter(kFilteredMessageClasses
,
97 arraysize(kFilteredMessageClasses
)),
98 render_process_id_(render_process_id
),
99 message_port_message_filter_(message_port_message_filter
),
100 resource_context_(resource_context
),
101 channel_ready_(false) {
104 ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
106 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_
);
107 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
112 void ServiceWorkerDispatcherHost::Init(
113 ServiceWorkerContextWrapper
* context_wrapper
) {
114 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
115 BrowserThread::PostTask(
116 BrowserThread::IO
, FROM_HERE
,
117 base::Bind(&ServiceWorkerDispatcherHost::Init
,
118 this, make_scoped_refptr(context_wrapper
)));
122 context_wrapper_
= context_wrapper
;
125 GetContext()->embedded_worker_registry()->AddChildProcessSender(
126 render_process_id_
, this, message_port_message_filter_
);
129 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender
* sender
) {
130 TRACE_EVENT0("ServiceWorker",
131 "ServiceWorkerDispatcherHost::OnFilterAdded");
132 channel_ready_
= true;
133 std::vector
<IPC::Message
*> messages
;
134 pending_messages_
.release(&messages
);
135 for (size_t i
= 0; i
< messages
.size(); ++i
) {
136 BrowserMessageFilter::Send(messages
[i
]);
140 void ServiceWorkerDispatcherHost::OnFilterRemoved() {
141 // Don't wait until the destructor to teardown since a new dispatcher host
142 // for this process might be created before then.
144 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_
);
145 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
148 context_wrapper_
= nullptr;
149 channel_ready_
= false;
152 void ServiceWorkerDispatcherHost::OnDestruct() const {
153 BrowserThread::DeleteOnIOThread::Destruct(this);
156 bool ServiceWorkerDispatcherHost::OnMessageReceived(
157 const IPC::Message
& message
) {
159 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost
, message
)
160 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker
,
161 OnRegisterServiceWorker
)
162 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker
,
163 OnUnregisterServiceWorker
)
164 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration
,
166 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated
,
168 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed
,
170 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId
,
171 OnSetHostedVersionId
)
172 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker
,
173 OnPostMessageToWorker
)
174 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection
,
175 OnWorkerReadyForInspection
)
176 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded
,
177 OnWorkerScriptLoaded
)
178 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed
,
179 OnWorkerScriptLoadFailed
)
180 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptEvaluated
,
181 OnWorkerScriptEvaluated
)
182 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted
,
184 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped
,
186 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload
,
187 OnPausedAfterDownload
)
188 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException
,
190 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage
,
191 OnReportConsoleMessage
)
192 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount
,
193 OnIncrementServiceWorkerRefCount
)
194 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount
,
195 OnDecrementServiceWorkerRefCount
)
196 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount
,
197 OnIncrementRegistrationRefCount
)
198 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount
,
199 OnDecrementRegistrationRefCount
)
200 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker
, OnTerminateWorker
)
201 IPC_MESSAGE_UNHANDLED(handled
= false)
202 IPC_END_MESSAGE_MAP()
204 if (!handled
&& GetContext()) {
205 handled
= GetContext()->embedded_worker_registry()->OnMessageReceived(
206 message
, render_process_id_
);
208 BadMessageReceived();
214 bool ServiceWorkerDispatcherHost::Send(IPC::Message
* message
) {
215 if (channel_ready_
) {
216 BrowserMessageFilter::Send(message
);
217 // Don't bother passing through Send()'s result: it's not reliable.
221 pending_messages_
.push_back(message
);
225 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
226 scoped_ptr
<ServiceWorkerHandle
> handle
) {
227 int handle_id
= handle
->handle_id();
228 handles_
.AddWithID(handle
.release(), handle_id
);
231 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
232 scoped_ptr
<ServiceWorkerRegistrationHandle
> handle
) {
233 int handle_id
= handle
->handle_id();
234 registration_handles_
.AddWithID(handle
.release(), handle_id
);
237 ServiceWorkerRegistrationHandle
*
238 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
239 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
,
240 ServiceWorkerRegistration
* registration
) {
241 DCHECK(provider_host
);
242 ServiceWorkerRegistrationHandle
* handle
=
243 FindRegistrationHandle(provider_host
->provider_id(), registration
->id());
245 handle
->IncrementRefCount();
249 scoped_ptr
<ServiceWorkerRegistrationHandle
> new_handle(
250 new ServiceWorkerRegistrationHandle(
251 GetContext()->AsWeakPtr(), provider_host
, registration
));
252 handle
= new_handle
.get();
253 RegisterServiceWorkerRegistrationHandle(new_handle
.Pass());
257 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
262 const GURL
& script_url
) {
263 TRACE_EVENT0("ServiceWorker",
264 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
266 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
267 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeAbort
,
268 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
269 base::ASCIIToUTF16(kShutdownErrorMessage
)));
272 if (!pattern
.is_valid() || !script_url
.is_valid()) {
273 BadMessageReceived();
277 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
278 render_process_id_
, provider_id
);
279 if (!provider_host
) {
280 BadMessageReceived();
283 if (!provider_host
->IsContextAlive()) {
284 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
285 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeAbort
,
286 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
287 base::ASCIIToUTF16(kShutdownErrorMessage
)));
291 // TODO(ksakamoto): Currently, document_url is empty if the document is in an
292 // IFRAME using frame.contentDocument.write(...). We can remove this check
293 // once crbug.com/439697 is fixed.
294 if (provider_host
->document_url().is_empty()) {
295 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
296 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeSecurity
,
297 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
298 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
302 if (!CanRegisterServiceWorker(
303 provider_host
->document_url(), pattern
, script_url
)) {
304 BadMessageReceived();
308 std::string error_message
;
309 if (ServiceWorkerUtils::ContainsDisallowedCharacter(pattern
, script_url
,
311 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
312 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeSecurity
,
313 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
314 base::UTF8ToUTF16(error_message
)));
318 if (!GetContentClient()->browser()->AllowServiceWorker(
319 pattern
, provider_host
->topmost_frame_url(), resource_context_
)) {
320 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
321 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeUnknown
,
322 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
323 base::ASCIIToUTF16(kUserDeniedPermissionMessage
)));
327 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
328 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
330 "Pattern", pattern
.spec(),
331 "Script URL", script_url
.spec());
332 GetContext()->RegisterServiceWorker(
336 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete
,
343 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
347 const GURL
& pattern
) {
348 TRACE_EVENT0("ServiceWorker",
349 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
351 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
354 blink::WebServiceWorkerError::ErrorTypeAbort
,
355 base::ASCIIToUTF16(kShutdownErrorMessage
)));
358 if (!pattern
.is_valid()) {
359 BadMessageReceived();
363 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
364 render_process_id_
, provider_id
);
365 if (!provider_host
) {
366 BadMessageReceived();
369 if (!provider_host
->IsContextAlive()) {
370 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
373 blink::WebServiceWorkerError::ErrorTypeAbort
,
374 base::ASCIIToUTF16(kShutdownErrorMessage
)));
378 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
379 if (provider_host
->document_url().is_empty()) {
380 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
383 WebServiceWorkerError::ErrorTypeSecurity
,
384 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
388 if (!CanUnregisterServiceWorker(provider_host
->document_url(), pattern
)) {
389 BadMessageReceived();
393 if (!GetContentClient()->browser()->AllowServiceWorker(
394 pattern
, provider_host
->topmost_frame_url(), resource_context_
)) {
395 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
398 WebServiceWorkerError::ErrorTypeUnknown
,
399 base::ASCIIToUTF16(kUserDeniedPermissionMessage
)));
403 TRACE_EVENT_ASYNC_BEGIN1(
405 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
407 "Pattern", pattern
.spec());
408 GetContext()->UnregisterServiceWorker(
410 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete
,
416 void ServiceWorkerDispatcherHost::OnGetRegistration(
420 const GURL
& document_url
) {
421 TRACE_EVENT0("ServiceWorker",
422 "ServiceWorkerDispatcherHost::OnGetRegistration");
424 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
425 thread_id
, request_id
, blink::WebServiceWorkerError::ErrorTypeAbort
,
426 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
427 base::ASCIIToUTF16(kShutdownErrorMessage
)));
430 if (!document_url
.is_valid()) {
431 BadMessageReceived();
435 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
436 render_process_id_
, provider_id
);
437 if (!provider_host
) {
438 BadMessageReceived();
441 if (!provider_host
->IsContextAlive()) {
442 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
443 thread_id
, request_id
, blink::WebServiceWorkerError::ErrorTypeAbort
,
444 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
445 base::ASCIIToUTF16(kShutdownErrorMessage
)));
449 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
450 if (provider_host
->document_url().is_empty()) {
451 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
452 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeSecurity
,
453 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
454 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
458 if (!CanGetRegistration(provider_host
->document_url(), document_url
)) {
459 BadMessageReceived();
463 if (!GetContentClient()->browser()->AllowServiceWorker(
464 provider_host
->document_url(),
465 provider_host
->topmost_frame_url(),
466 resource_context_
)) {
467 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
468 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeUnknown
,
469 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
470 base::ASCIIToUTF16(kUserDeniedPermissionMessage
)));
474 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
475 if (GetContext()->storage()->IsDisabled()) {
476 SendGetRegistrationError(thread_id
, request_id
, SERVICE_WORKER_ERROR_ABORT
);
480 TRACE_EVENT_ASYNC_BEGIN1(
482 "ServiceWorkerDispatcherHost::GetRegistration",
484 "Document URL", document_url
.spec());
486 GetContext()->storage()->FindRegistrationForDocument(
488 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete
,
495 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
497 const base::string16
& message
,
498 const std::vector
<TransferredMessagePort
>& sent_message_ports
) {
499 TRACE_EVENT0("ServiceWorker",
500 "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
504 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
506 BadMessageReceived();
510 handle
->version()->DispatchMessageEvent(
511 message
, sent_message_ports
,
512 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
515 void ServiceWorkerDispatcherHost::OnProviderCreated(
518 ServiceWorkerProviderType provider_type
) {
519 TRACE_EVENT0("ServiceWorker",
520 "ServiceWorkerDispatcherHost::OnProviderCreated");
523 if (GetContext()->GetProviderHost(render_process_id_
, provider_id
)) {
524 BadMessageReceived();
527 scoped_ptr
<ServiceWorkerProviderHost
> provider_host(
528 new ServiceWorkerProviderHost(render_process_id_
,
532 GetContext()->AsWeakPtr(),
534 GetContext()->AddProviderHost(provider_host
.Pass());
537 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id
) {
538 TRACE_EVENT0("ServiceWorker",
539 "ServiceWorkerDispatcherHost::OnProviderDestroyed");
542 if (!GetContext()->GetProviderHost(render_process_id_
, provider_id
)) {
543 BadMessageReceived();
546 GetContext()->RemoveProviderHost(render_process_id_
, provider_id
);
549 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
550 int provider_id
, int64 version_id
) {
551 TRACE_EVENT0("ServiceWorker",
552 "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
555 ServiceWorkerProviderHost
* provider_host
=
556 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
557 if (!provider_host
) {
558 BadMessageReceived();
561 if (!provider_host
->IsContextAlive())
563 if (!provider_host
->SetHostedVersionId(version_id
))
564 BadMessageReceived();
566 // Retrieve the registration associated with |version_id|.
567 ServiceWorkerVersion
* version
= GetContext()->GetLiveVersion(version_id
);
570 ServiceWorkerRegistration
* registration
=
571 GetContext()->GetLiveRegistration(version
->registration_id());
572 DCHECK(registration
);
574 // Set the document URL to the script url in order to allow
575 // register/unregister/getRegistration on ServiceWorkerGlobalScope.
576 provider_host
->SetDocumentUrl(version
->script_url());
578 ServiceWorkerRegistrationObjectInfo info
;
579 ServiceWorkerVersionAttributes attrs
;
580 GetRegistrationObjectInfoAndVersionAttributes(
581 provider_host
->AsWeakPtr(), registration
, &info
, &attrs
);
583 Send(new ServiceWorkerMsg_AssociateRegistrationWithServiceWorker(
584 kDocumentMainThreadId
, provider_id
, info
, attrs
));
587 ServiceWorkerRegistrationHandle
*
588 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id
,
589 int64 registration_id
) {
590 for (IDMap
<ServiceWorkerRegistrationHandle
, IDMapOwnPointer
>::iterator
591 iter(®istration_handles_
);
594 ServiceWorkerRegistrationHandle
* handle
= iter
.GetCurrentValue();
596 if (handle
->provider_id() == provider_id
&& handle
->registration() &&
597 handle
->registration()->id() == registration_id
) {
604 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
605 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
,
606 ServiceWorkerRegistration
* registration
,
607 ServiceWorkerRegistrationObjectInfo
* info
,
608 ServiceWorkerVersionAttributes
* attrs
) {
609 ServiceWorkerRegistrationHandle
* handle
=
610 GetOrCreateRegistrationHandle(provider_host
, registration
);
611 *info
= handle
->GetObjectInfo();
614 provider_host
->CreateAndRegisterServiceWorkerHandle(
615 registration
->installing_version());
617 provider_host
->CreateAndRegisterServiceWorkerHandle(
618 registration
->waiting_version());
620 provider_host
->CreateAndRegisterServiceWorkerHandle(
621 registration
->active_version());
624 void ServiceWorkerDispatcherHost::RegistrationComplete(
628 ServiceWorkerStatusCode status
,
629 const std::string
& status_message
,
630 int64 registration_id
) {
634 ServiceWorkerProviderHost
* provider_host
=
635 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
637 return; // The provider has already been destroyed.
639 if (status
!= SERVICE_WORKER_OK
) {
640 SendRegistrationError(thread_id
, request_id
, status
, status_message
);
644 ServiceWorkerRegistration
* registration
=
645 GetContext()->GetLiveRegistration(registration_id
);
646 DCHECK(registration
);
648 ServiceWorkerRegistrationObjectInfo info
;
649 ServiceWorkerVersionAttributes attrs
;
650 GetRegistrationObjectInfoAndVersionAttributes(
651 provider_host
->AsWeakPtr(), registration
, &info
, &attrs
);
653 Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
654 thread_id
, request_id
, info
, attrs
));
655 TRACE_EVENT_ASYNC_END1("ServiceWorker",
656 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
662 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
663 int embedded_worker_id
) {
664 TRACE_EVENT0("ServiceWorker",
665 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
668 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
669 if (!registry
->CanHandle(embedded_worker_id
))
671 registry
->OnWorkerReadyForInspection(render_process_id_
, embedded_worker_id
);
674 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
675 int embedded_worker_id
,
678 TRACE_EVENT0("ServiceWorker",
679 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
683 ServiceWorkerProviderHost
* provider_host
=
684 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
685 if (!provider_host
) {
686 BadMessageReceived();
690 provider_host
->SetReadyToSendMessagesToWorker(thread_id
);
692 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
693 if (!registry
->CanHandle(embedded_worker_id
))
695 registry
->OnWorkerScriptLoaded(
696 render_process_id_
, thread_id
, embedded_worker_id
);
699 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
700 int embedded_worker_id
) {
701 TRACE_EVENT0("ServiceWorker",
702 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
705 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
706 if (!registry
->CanHandle(embedded_worker_id
))
708 registry
->OnWorkerScriptLoadFailed(render_process_id_
, embedded_worker_id
);
711 void ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated(
712 int embedded_worker_id
,
714 TRACE_EVENT0("ServiceWorker",
715 "ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated");
718 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
719 if (!registry
->CanHandle(embedded_worker_id
))
721 registry
->OnWorkerScriptEvaluated(
722 render_process_id_
, embedded_worker_id
, success
);
725 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id
) {
726 TRACE_EVENT0("ServiceWorker",
727 "ServiceWorkerDispatcherHost::OnWorkerStarted");
730 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
731 if (!registry
->CanHandle(embedded_worker_id
))
733 registry
->OnWorkerStarted(render_process_id_
, embedded_worker_id
);
736 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id
) {
737 TRACE_EVENT0("ServiceWorker",
738 "ServiceWorkerDispatcherHost::OnWorkerStopped");
741 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
742 if (!registry
->CanHandle(embedded_worker_id
))
744 registry
->OnWorkerStopped(render_process_id_
, embedded_worker_id
);
747 void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
748 int embedded_worker_id
) {
749 TRACE_EVENT0("ServiceWorker",
750 "ServiceWorkerDispatcherHost::OnPausedAfterDownload");
753 GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
754 render_process_id_
, embedded_worker_id
);
757 void ServiceWorkerDispatcherHost::OnReportException(
758 int embedded_worker_id
,
759 const base::string16
& error_message
,
762 const GURL
& source_url
) {
763 TRACE_EVENT0("ServiceWorker",
764 "ServiceWorkerDispatcherHost::OnReportException");
767 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
768 if (!registry
->CanHandle(embedded_worker_id
))
770 registry
->OnReportException(embedded_worker_id
,
777 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
778 int embedded_worker_id
,
779 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params
& params
) {
780 TRACE_EVENT0("ServiceWorker",
781 "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
784 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
785 if (!registry
->CanHandle(embedded_worker_id
))
787 registry
->OnReportConsoleMessage(embedded_worker_id
,
788 params
.source_identifier
,
789 params
.message_level
,
795 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
797 TRACE_EVENT0("ServiceWorker",
798 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
799 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
801 BadMessageReceived();
804 handle
->IncrementRefCount();
807 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
809 TRACE_EVENT0("ServiceWorker",
810 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
811 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
813 BadMessageReceived();
816 handle
->DecrementRefCount();
817 if (handle
->HasNoRefCount())
818 handles_
.Remove(handle_id
);
821 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
822 int registration_handle_id
) {
823 TRACE_EVENT0("ServiceWorker",
824 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
825 ServiceWorkerRegistrationHandle
* handle
=
826 registration_handles_
.Lookup(registration_handle_id
);
828 BadMessageReceived();
831 handle
->IncrementRefCount();
834 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
835 int registration_handle_id
) {
836 TRACE_EVENT0("ServiceWorker",
837 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
838 ServiceWorkerRegistrationHandle
* handle
=
839 registration_handles_
.Lookup(registration_handle_id
);
841 BadMessageReceived();
844 handle
->DecrementRefCount();
845 if (handle
->HasNoRefCount())
846 registration_handles_
.Remove(registration_handle_id
);
849 void ServiceWorkerDispatcherHost::UnregistrationComplete(
852 ServiceWorkerStatusCode status
) {
853 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
854 SendUnregistrationError(thread_id
, request_id
, status
);
857 const bool is_success
= (status
== SERVICE_WORKER_OK
);
858 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id
,
861 TRACE_EVENT_ASYNC_END1(
863 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
868 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
872 ServiceWorkerStatusCode status
,
873 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
874 TRACE_EVENT_ASYNC_END1("ServiceWorker",
875 "ServiceWorkerDispatcherHost::GetRegistration",
878 registration
.get() ? registration
->id()
879 : kInvalidServiceWorkerRegistrationId
);
884 ServiceWorkerProviderHost
* provider_host
=
885 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
887 return; // The provider has already been destroyed.
889 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
890 SendGetRegistrationError(thread_id
, request_id
, status
);
894 ServiceWorkerRegistrationObjectInfo info
;
895 ServiceWorkerVersionAttributes attrs
;
896 if (status
== SERVICE_WORKER_OK
) {
897 DCHECK(registration
.get());
898 if (!registration
->is_uninstalling()) {
899 GetRegistrationObjectInfoAndVersionAttributes(
900 provider_host
->AsWeakPtr(), registration
.get(), &info
, &attrs
);
904 Send(new ServiceWorkerMsg_DidGetRegistration(
905 thread_id
, request_id
, info
, attrs
));
908 void ServiceWorkerDispatcherHost::SendRegistrationError(
911 ServiceWorkerStatusCode status
,
912 const std::string
& status_message
) {
913 base::string16 error_message
;
914 blink::WebServiceWorkerError::ErrorType error_type
;
915 GetServiceWorkerRegistrationStatusResponse(status
, status_message
,
916 &error_type
, &error_message
);
917 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
918 thread_id
, request_id
, error_type
,
919 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) + error_message
));
922 void ServiceWorkerDispatcherHost::SendUnregistrationError(
925 ServiceWorkerStatusCode status
) {
926 base::string16 error_message
;
927 blink::WebServiceWorkerError::ErrorType error_type
;
928 GetServiceWorkerRegistrationStatusResponse(status
, std::string(), &error_type
,
930 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
931 thread_id
, request_id
, error_type
,
932 base::ASCIIToUTF16(kServiceWorkerUnregisterErrorPrefix
) + error_message
));
935 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
938 ServiceWorkerStatusCode status
) {
939 base::string16 error_message
;
940 blink::WebServiceWorkerError::ErrorType error_type
;
941 GetServiceWorkerRegistrationStatusResponse(status
, std::string(), &error_type
,
943 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
944 thread_id
, request_id
, error_type
,
945 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
949 ServiceWorkerContextCore
* ServiceWorkerDispatcherHost::GetContext() {
950 if (!context_wrapper_
.get())
952 return context_wrapper_
->context();
955 void ServiceWorkerDispatcherHost::OnTerminateWorker(int handle_id
) {
956 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
958 BadMessageReceived();
961 handle
->version()->StopWorker(
962 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
965 } // namespace content