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_GetRegistrationForReady
,
167 OnGetRegistrationForReady
)
168 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated
,
170 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed
,
172 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId
,
173 OnSetHostedVersionId
)
174 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker
,
175 OnPostMessageToWorker
)
176 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection
,
177 OnWorkerReadyForInspection
)
178 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded
,
179 OnWorkerScriptLoaded
)
180 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed
,
181 OnWorkerScriptLoadFailed
)
182 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptEvaluated
,
183 OnWorkerScriptEvaluated
)
184 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted
,
186 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped
,
188 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload
,
189 OnPausedAfterDownload
)
190 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException
,
192 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage
,
193 OnReportConsoleMessage
)
194 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount
,
195 OnIncrementServiceWorkerRefCount
)
196 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount
,
197 OnDecrementServiceWorkerRefCount
)
198 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount
,
199 OnIncrementRegistrationRefCount
)
200 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount
,
201 OnDecrementRegistrationRefCount
)
202 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker
, OnTerminateWorker
)
203 IPC_MESSAGE_UNHANDLED(handled
= false)
204 IPC_END_MESSAGE_MAP()
206 if (!handled
&& GetContext()) {
207 handled
= GetContext()->embedded_worker_registry()->OnMessageReceived(
208 message
, render_process_id_
);
210 BadMessageReceived();
216 bool ServiceWorkerDispatcherHost::Send(IPC::Message
* message
) {
217 if (channel_ready_
) {
218 BrowserMessageFilter::Send(message
);
219 // Don't bother passing through Send()'s result: it's not reliable.
223 pending_messages_
.push_back(message
);
227 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
228 scoped_ptr
<ServiceWorkerHandle
> handle
) {
229 int handle_id
= handle
->handle_id();
230 handles_
.AddWithID(handle
.release(), handle_id
);
233 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
234 scoped_ptr
<ServiceWorkerRegistrationHandle
> handle
) {
235 int handle_id
= handle
->handle_id();
236 registration_handles_
.AddWithID(handle
.release(), handle_id
);
239 ServiceWorkerRegistrationHandle
*
240 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
241 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
,
242 ServiceWorkerRegistration
* registration
) {
243 DCHECK(provider_host
);
244 ServiceWorkerRegistrationHandle
* handle
=
245 FindRegistrationHandle(provider_host
->provider_id(), registration
->id());
247 handle
->IncrementRefCount();
251 scoped_ptr
<ServiceWorkerRegistrationHandle
> new_handle(
252 new ServiceWorkerRegistrationHandle(
253 GetContext()->AsWeakPtr(), provider_host
, registration
));
254 handle
= new_handle
.get();
255 RegisterServiceWorkerRegistrationHandle(new_handle
.Pass());
259 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
264 const GURL
& script_url
) {
265 TRACE_EVENT0("ServiceWorker",
266 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
268 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
269 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeAbort
,
270 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
271 base::ASCIIToUTF16(kShutdownErrorMessage
)));
274 if (!pattern
.is_valid() || !script_url
.is_valid()) {
275 BadMessageReceived();
279 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
280 render_process_id_
, provider_id
);
281 if (!provider_host
) {
282 BadMessageReceived();
285 if (!provider_host
->IsContextAlive()) {
286 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
287 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeAbort
,
288 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
289 base::ASCIIToUTF16(kShutdownErrorMessage
)));
293 // TODO(ksakamoto): Currently, document_url is empty if the document is in an
294 // IFRAME using frame.contentDocument.write(...). We can remove this check
295 // once crbug.com/439697 is fixed.
296 if (provider_host
->document_url().is_empty()) {
297 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
298 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeSecurity
,
299 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
300 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
304 if (!CanRegisterServiceWorker(
305 provider_host
->document_url(), pattern
, script_url
)) {
306 BadMessageReceived();
310 std::string error_message
;
311 if (ServiceWorkerUtils::ContainsDisallowedCharacter(pattern
, script_url
,
313 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
314 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeSecurity
,
315 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
316 base::UTF8ToUTF16(error_message
)));
320 if (!GetContentClient()->browser()->AllowServiceWorker(
321 pattern
, provider_host
->topmost_frame_url(), resource_context_
)) {
322 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
323 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeUnknown
,
324 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) +
325 base::ASCIIToUTF16(kUserDeniedPermissionMessage
)));
329 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
330 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
332 "Pattern", pattern
.spec(),
333 "Script URL", script_url
.spec());
334 GetContext()->RegisterServiceWorker(
338 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete
,
345 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
349 const GURL
& pattern
) {
350 TRACE_EVENT0("ServiceWorker",
351 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
353 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
356 blink::WebServiceWorkerError::ErrorTypeAbort
,
357 base::ASCIIToUTF16(kShutdownErrorMessage
)));
360 if (!pattern
.is_valid()) {
361 BadMessageReceived();
365 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
366 render_process_id_
, provider_id
);
367 if (!provider_host
) {
368 BadMessageReceived();
371 if (!provider_host
->IsContextAlive()) {
372 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
375 blink::WebServiceWorkerError::ErrorTypeAbort
,
376 base::ASCIIToUTF16(kShutdownErrorMessage
)));
380 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
381 if (provider_host
->document_url().is_empty()) {
382 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
385 WebServiceWorkerError::ErrorTypeSecurity
,
386 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
390 if (!CanUnregisterServiceWorker(provider_host
->document_url(), pattern
)) {
391 BadMessageReceived();
395 if (!GetContentClient()->browser()->AllowServiceWorker(
396 pattern
, provider_host
->topmost_frame_url(), resource_context_
)) {
397 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
400 WebServiceWorkerError::ErrorTypeUnknown
,
401 base::ASCIIToUTF16(kUserDeniedPermissionMessage
)));
405 TRACE_EVENT_ASYNC_BEGIN1(
407 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
409 "Pattern", pattern
.spec());
410 GetContext()->UnregisterServiceWorker(
412 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete
,
418 void ServiceWorkerDispatcherHost::OnGetRegistration(
422 const GURL
& document_url
) {
423 TRACE_EVENT0("ServiceWorker",
424 "ServiceWorkerDispatcherHost::OnGetRegistration");
426 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
427 thread_id
, request_id
, blink::WebServiceWorkerError::ErrorTypeAbort
,
428 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
429 base::ASCIIToUTF16(kShutdownErrorMessage
)));
432 if (!document_url
.is_valid()) {
433 BadMessageReceived();
437 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
438 render_process_id_
, provider_id
);
439 if (!provider_host
) {
440 BadMessageReceived();
443 if (!provider_host
->IsContextAlive()) {
444 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
445 thread_id
, request_id
, blink::WebServiceWorkerError::ErrorTypeAbort
,
446 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
447 base::ASCIIToUTF16(kShutdownErrorMessage
)));
451 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
452 if (provider_host
->document_url().is_empty()) {
453 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
454 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeSecurity
,
455 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
456 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
460 if (!CanGetRegistration(provider_host
->document_url(), document_url
)) {
461 BadMessageReceived();
465 if (!GetContentClient()->browser()->AllowServiceWorker(
466 provider_host
->document_url(),
467 provider_host
->topmost_frame_url(),
468 resource_context_
)) {
469 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
470 thread_id
, request_id
, WebServiceWorkerError::ErrorTypeUnknown
,
471 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
472 base::ASCIIToUTF16(kUserDeniedPermissionMessage
)));
476 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
477 if (GetContext()->storage()->IsDisabled()) {
478 SendGetRegistrationError(thread_id
, request_id
, SERVICE_WORKER_ERROR_ABORT
);
482 TRACE_EVENT_ASYNC_BEGIN1(
484 "ServiceWorkerDispatcherHost::GetRegistration",
486 "Document URL", document_url
.spec());
488 GetContext()->storage()->FindRegistrationForDocument(
490 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete
,
497 void ServiceWorkerDispatcherHost::OnGetRegistrationForReady(
501 TRACE_EVENT0("ServiceWorker",
502 "ServiceWorkerDispatcherHost::OnGetRegistrationForReady");
505 ServiceWorkerProviderHost
* provider_host
=
506 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
507 if (!provider_host
) {
508 BadMessageReceived();
511 if (!provider_host
->IsContextAlive())
514 TRACE_EVENT_ASYNC_BEGIN0(
516 "ServiceWorkerDispatcherHost::GetRegistrationForReady",
519 if (!provider_host
->GetRegistrationForReady(base::Bind(
520 &ServiceWorkerDispatcherHost::GetRegistrationForReadyComplete
,
521 this, thread_id
, request_id
, provider_host
->AsWeakPtr()))) {
522 BadMessageReceived();
526 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
528 const base::string16
& message
,
529 const std::vector
<TransferredMessagePort
>& sent_message_ports
) {
530 TRACE_EVENT0("ServiceWorker",
531 "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
535 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
537 BadMessageReceived();
541 handle
->version()->DispatchMessageEvent(
542 message
, sent_message_ports
,
543 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
546 void ServiceWorkerDispatcherHost::OnProviderCreated(
549 ServiceWorkerProviderType provider_type
) {
550 TRACE_EVENT0("ServiceWorker",
551 "ServiceWorkerDispatcherHost::OnProviderCreated");
554 if (GetContext()->GetProviderHost(render_process_id_
, provider_id
)) {
555 BadMessageReceived();
558 scoped_ptr
<ServiceWorkerProviderHost
> provider_host(
559 new ServiceWorkerProviderHost(render_process_id_
,
563 GetContext()->AsWeakPtr(),
565 GetContext()->AddProviderHost(provider_host
.Pass());
568 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id
) {
569 TRACE_EVENT0("ServiceWorker",
570 "ServiceWorkerDispatcherHost::OnProviderDestroyed");
573 if (!GetContext()->GetProviderHost(render_process_id_
, provider_id
)) {
574 BadMessageReceived();
577 GetContext()->RemoveProviderHost(render_process_id_
, provider_id
);
580 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
581 int provider_id
, int64 version_id
) {
582 TRACE_EVENT0("ServiceWorker",
583 "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
586 ServiceWorkerProviderHost
* provider_host
=
587 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
588 if (!provider_host
) {
589 BadMessageReceived();
592 if (!provider_host
->IsContextAlive())
594 if (!provider_host
->SetHostedVersionId(version_id
))
595 BadMessageReceived();
597 ServiceWorkerVersion
* version
= GetContext()->GetLiveVersion(version_id
);
601 // Retrieve the registration associated with |version|. The registration
602 // must be alive because the version keeps it during starting worker.
603 ServiceWorkerRegistration
* registration
=
604 GetContext()->GetLiveRegistration(version
->registration_id());
605 DCHECK(registration
);
606 // TODO(ksakamoto): This is a quick fix for crbug.com/459916.
610 // Set the document URL to the script url in order to allow
611 // register/unregister/getRegistration on ServiceWorkerGlobalScope.
612 provider_host
->SetDocumentUrl(version
->script_url());
614 ServiceWorkerRegistrationObjectInfo info
;
615 ServiceWorkerVersionAttributes attrs
;
616 GetRegistrationObjectInfoAndVersionAttributes(
617 provider_host
->AsWeakPtr(), registration
, &info
, &attrs
);
619 Send(new ServiceWorkerMsg_AssociateRegistrationWithServiceWorker(
620 kDocumentMainThreadId
, provider_id
, info
, attrs
));
623 ServiceWorkerRegistrationHandle
*
624 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id
,
625 int64 registration_id
) {
626 for (IDMap
<ServiceWorkerRegistrationHandle
, IDMapOwnPointer
>::iterator
627 iter(®istration_handles_
);
630 ServiceWorkerRegistrationHandle
* handle
= iter
.GetCurrentValue();
632 if (handle
->provider_id() == provider_id
&& handle
->registration() &&
633 handle
->registration()->id() == registration_id
) {
640 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
641 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
,
642 ServiceWorkerRegistration
* registration
,
643 ServiceWorkerRegistrationObjectInfo
* info
,
644 ServiceWorkerVersionAttributes
* attrs
) {
645 ServiceWorkerRegistrationHandle
* handle
=
646 GetOrCreateRegistrationHandle(provider_host
, registration
);
647 *info
= handle
->GetObjectInfo();
650 provider_host
->CreateAndRegisterServiceWorkerHandle(
651 registration
->installing_version());
653 provider_host
->CreateAndRegisterServiceWorkerHandle(
654 registration
->waiting_version());
656 provider_host
->CreateAndRegisterServiceWorkerHandle(
657 registration
->active_version());
660 void ServiceWorkerDispatcherHost::RegistrationComplete(
664 ServiceWorkerStatusCode status
,
665 const std::string
& status_message
,
666 int64 registration_id
) {
670 ServiceWorkerProviderHost
* provider_host
=
671 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
673 return; // The provider has already been destroyed.
675 if (status
!= SERVICE_WORKER_OK
) {
676 SendRegistrationError(thread_id
, request_id
, status
, status_message
);
680 ServiceWorkerRegistration
* registration
=
681 GetContext()->GetLiveRegistration(registration_id
);
682 DCHECK(registration
);
684 ServiceWorkerRegistrationObjectInfo info
;
685 ServiceWorkerVersionAttributes attrs
;
686 GetRegistrationObjectInfoAndVersionAttributes(
687 provider_host
->AsWeakPtr(), registration
, &info
, &attrs
);
689 Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
690 thread_id
, request_id
, info
, attrs
));
691 TRACE_EVENT_ASYNC_END1("ServiceWorker",
692 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
698 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
699 int embedded_worker_id
) {
700 TRACE_EVENT0("ServiceWorker",
701 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
704 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
705 if (!registry
->CanHandle(embedded_worker_id
))
707 registry
->OnWorkerReadyForInspection(render_process_id_
, embedded_worker_id
);
710 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
711 int embedded_worker_id
,
714 TRACE_EVENT0("ServiceWorker",
715 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
719 ServiceWorkerProviderHost
* provider_host
=
720 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
721 if (!provider_host
) {
722 BadMessageReceived();
726 provider_host
->SetReadyToSendMessagesToWorker(thread_id
);
728 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
729 if (!registry
->CanHandle(embedded_worker_id
))
731 registry
->OnWorkerScriptLoaded(
732 render_process_id_
, thread_id
, embedded_worker_id
);
735 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
736 int embedded_worker_id
) {
737 TRACE_EVENT0("ServiceWorker",
738 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
741 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
742 if (!registry
->CanHandle(embedded_worker_id
))
744 registry
->OnWorkerScriptLoadFailed(render_process_id_
, embedded_worker_id
);
747 void ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated(
748 int embedded_worker_id
,
750 TRACE_EVENT0("ServiceWorker",
751 "ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated");
754 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
755 if (!registry
->CanHandle(embedded_worker_id
))
757 registry
->OnWorkerScriptEvaluated(
758 render_process_id_
, embedded_worker_id
, success
);
761 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id
) {
762 TRACE_EVENT0("ServiceWorker",
763 "ServiceWorkerDispatcherHost::OnWorkerStarted");
766 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
767 if (!registry
->CanHandle(embedded_worker_id
))
769 registry
->OnWorkerStarted(render_process_id_
, embedded_worker_id
);
772 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id
) {
773 TRACE_EVENT0("ServiceWorker",
774 "ServiceWorkerDispatcherHost::OnWorkerStopped");
777 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
778 if (!registry
->CanHandle(embedded_worker_id
))
780 registry
->OnWorkerStopped(render_process_id_
, embedded_worker_id
);
783 void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
784 int embedded_worker_id
) {
785 TRACE_EVENT0("ServiceWorker",
786 "ServiceWorkerDispatcherHost::OnPausedAfterDownload");
789 GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
790 render_process_id_
, embedded_worker_id
);
793 void ServiceWorkerDispatcherHost::OnReportException(
794 int embedded_worker_id
,
795 const base::string16
& error_message
,
798 const GURL
& source_url
) {
799 TRACE_EVENT0("ServiceWorker",
800 "ServiceWorkerDispatcherHost::OnReportException");
803 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
804 if (!registry
->CanHandle(embedded_worker_id
))
806 registry
->OnReportException(embedded_worker_id
,
813 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
814 int embedded_worker_id
,
815 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params
& params
) {
816 TRACE_EVENT0("ServiceWorker",
817 "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
820 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
821 if (!registry
->CanHandle(embedded_worker_id
))
823 registry
->OnReportConsoleMessage(embedded_worker_id
,
824 params
.source_identifier
,
825 params
.message_level
,
831 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
833 TRACE_EVENT0("ServiceWorker",
834 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
835 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
837 BadMessageReceived();
840 handle
->IncrementRefCount();
843 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
845 TRACE_EVENT0("ServiceWorker",
846 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
847 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
849 BadMessageReceived();
852 handle
->DecrementRefCount();
853 if (handle
->HasNoRefCount())
854 handles_
.Remove(handle_id
);
857 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
858 int registration_handle_id
) {
859 TRACE_EVENT0("ServiceWorker",
860 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
861 ServiceWorkerRegistrationHandle
* handle
=
862 registration_handles_
.Lookup(registration_handle_id
);
864 BadMessageReceived();
867 handle
->IncrementRefCount();
870 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
871 int registration_handle_id
) {
872 TRACE_EVENT0("ServiceWorker",
873 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
874 ServiceWorkerRegistrationHandle
* handle
=
875 registration_handles_
.Lookup(registration_handle_id
);
877 BadMessageReceived();
880 handle
->DecrementRefCount();
881 if (handle
->HasNoRefCount())
882 registration_handles_
.Remove(registration_handle_id
);
885 void ServiceWorkerDispatcherHost::UnregistrationComplete(
888 ServiceWorkerStatusCode status
) {
889 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
890 SendUnregistrationError(thread_id
, request_id
, status
);
893 const bool is_success
= (status
== SERVICE_WORKER_OK
);
894 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id
,
897 TRACE_EVENT_ASYNC_END1(
899 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
904 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
908 ServiceWorkerStatusCode status
,
909 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
910 TRACE_EVENT_ASYNC_END1("ServiceWorker",
911 "ServiceWorkerDispatcherHost::GetRegistration",
914 registration
.get() ? registration
->id()
915 : kInvalidServiceWorkerRegistrationId
);
920 ServiceWorkerProviderHost
* provider_host
=
921 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
923 return; // The provider has already been destroyed.
925 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
926 SendGetRegistrationError(thread_id
, request_id
, status
);
930 ServiceWorkerRegistrationObjectInfo info
;
931 ServiceWorkerVersionAttributes attrs
;
932 if (status
== SERVICE_WORKER_OK
) {
933 DCHECK(registration
.get());
934 if (!registration
->is_uninstalling()) {
935 GetRegistrationObjectInfoAndVersionAttributes(
936 provider_host
->AsWeakPtr(), registration
.get(), &info
, &attrs
);
940 Send(new ServiceWorkerMsg_DidGetRegistration(
941 thread_id
, request_id
, info
, attrs
));
944 void ServiceWorkerDispatcherHost::GetRegistrationForReadyComplete(
947 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
,
948 ServiceWorkerRegistration
* registration
) {
949 DCHECK(registration
);
950 TRACE_EVENT_ASYNC_END1("ServiceWorker",
951 "ServiceWorkerDispatcherHost::GetRegistrationForReady",
954 registration
? registration
->id()
955 : kInvalidServiceWorkerRegistrationId
);
960 ServiceWorkerRegistrationObjectInfo info
;
961 ServiceWorkerVersionAttributes attrs
;
962 GetRegistrationObjectInfoAndVersionAttributes(
963 provider_host
, registration
, &info
, &attrs
);
964 Send(new ServiceWorkerMsg_DidGetRegistrationForReady(
965 thread_id
, request_id
, info
, attrs
));
968 void ServiceWorkerDispatcherHost::SendRegistrationError(
971 ServiceWorkerStatusCode status
,
972 const std::string
& status_message
) {
973 base::string16 error_message
;
974 blink::WebServiceWorkerError::ErrorType error_type
;
975 GetServiceWorkerRegistrationStatusResponse(status
, status_message
,
976 &error_type
, &error_message
);
977 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
978 thread_id
, request_id
, error_type
,
979 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix
) + error_message
));
982 void ServiceWorkerDispatcherHost::SendUnregistrationError(
985 ServiceWorkerStatusCode status
) {
986 base::string16 error_message
;
987 blink::WebServiceWorkerError::ErrorType error_type
;
988 GetServiceWorkerRegistrationStatusResponse(status
, std::string(), &error_type
,
990 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
991 thread_id
, request_id
, error_type
,
992 base::ASCIIToUTF16(kServiceWorkerUnregisterErrorPrefix
) + error_message
));
995 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
998 ServiceWorkerStatusCode status
) {
999 base::string16 error_message
;
1000 blink::WebServiceWorkerError::ErrorType error_type
;
1001 GetServiceWorkerRegistrationStatusResponse(status
, std::string(), &error_type
,
1003 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
1004 thread_id
, request_id
, error_type
,
1005 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix
) +
1009 ServiceWorkerContextCore
* ServiceWorkerDispatcherHost::GetContext() {
1010 if (!context_wrapper_
.get())
1012 return context_wrapper_
->context();
1015 void ServiceWorkerDispatcherHost::OnTerminateWorker(int handle_id
) {
1016 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
1018 BadMessageReceived();
1021 handle
->version()->StopWorker(
1022 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1025 } // namespace content