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"
28 using blink::WebServiceWorkerError
;
34 const char kShutdownErrorMessage
[] =
35 "The Service Worker system has shutdown.";
36 const char kDisabledErrorMessage
[] = "The browser has disabled Service Worker.";
37 const char kNoDocumentURLErrorMessage
[] =
38 "No URL is associated with the caller's document.";
40 const uint32 kFilteredMessageClasses
[] = {
41 ServiceWorkerMsgStart
,
42 EmbeddedWorkerMsgStart
,
45 bool AllOriginsMatch(const GURL
& url_a
, const GURL
& url_b
, const GURL
& url_c
) {
46 return url_a
.GetOrigin() == url_b
.GetOrigin() &&
47 url_a
.GetOrigin() == url_c
.GetOrigin();
50 // TODO(dominicc): When crbug.com/362214 is fixed use that to be
51 // consistent with Blink's
52 // SecurityOrigin::canAccessFeatureRequiringSecureOrigin.
53 bool OriginCanAccessServiceWorkers(const GURL
& url
) {
54 return url
.SchemeIsSecure() || net::IsLocalhost(url
.host());
57 bool CheckPatternIsUnderTheScriptDirectory(const GURL
& pattern
,
58 const GURL
& script_url
) {
59 size_t slash_pos
= script_url
.spec().rfind('/');
60 if (slash_pos
== std::string::npos
)
62 return pattern
.spec().compare(
63 0, slash_pos
+ 1, script_url
.spec(), 0, slash_pos
+ 1) == 0;
66 bool CanRegisterServiceWorker(const GURL
& document_url
,
68 const GURL
& script_url
) {
69 DCHECK(document_url
.is_valid());
70 DCHECK(pattern
.is_valid());
71 DCHECK(script_url
.is_valid());
72 return AllOriginsMatch(document_url
, pattern
, script_url
) &&
73 OriginCanAccessServiceWorkers(document_url
) &&
74 CheckPatternIsUnderTheScriptDirectory(pattern
, script_url
);
77 bool CanUnregisterServiceWorker(const GURL
& document_url
,
78 const GURL
& pattern
) {
79 DCHECK(document_url
.is_valid());
80 DCHECK(pattern
.is_valid());
81 return document_url
.GetOrigin() == pattern
.GetOrigin() &&
82 OriginCanAccessServiceWorkers(document_url
);
85 bool CanGetRegistration(const GURL
& document_url
,
86 const GURL
& given_document_url
) {
87 DCHECK(document_url
.is_valid());
88 DCHECK(given_document_url
.is_valid());
89 return document_url
.GetOrigin() == given_document_url
.GetOrigin() &&
90 OriginCanAccessServiceWorkers(document_url
);
95 ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
96 int render_process_id
,
97 MessagePortMessageFilter
* message_port_message_filter
,
98 ResourceContext
* resource_context
)
99 : BrowserMessageFilter(kFilteredMessageClasses
,
100 arraysize(kFilteredMessageClasses
)),
101 render_process_id_(render_process_id
),
102 message_port_message_filter_(message_port_message_filter
),
103 resource_context_(resource_context
),
104 channel_ready_(false) {
107 ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
109 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_
);
110 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
115 void ServiceWorkerDispatcherHost::Init(
116 ServiceWorkerContextWrapper
* context_wrapper
) {
117 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
118 BrowserThread::PostTask(
119 BrowserThread::IO
, FROM_HERE
,
120 base::Bind(&ServiceWorkerDispatcherHost::Init
,
121 this, make_scoped_refptr(context_wrapper
)));
125 context_wrapper_
= context_wrapper
;
126 GetContext()->embedded_worker_registry()->AddChildProcessSender(
127 render_process_id_
, this, message_port_message_filter_
);
130 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender
* sender
) {
131 TRACE_EVENT0("ServiceWorker",
132 "ServiceWorkerDispatcherHost::OnFilterAdded");
133 channel_ready_
= true;
134 std::vector
<IPC::Message
*> messages
;
135 pending_messages_
.release(&messages
);
136 for (size_t i
= 0; i
< messages
.size(); ++i
) {
137 BrowserMessageFilter::Send(messages
[i
]);
141 void ServiceWorkerDispatcherHost::OnFilterRemoved() {
142 // Don't wait until the destructor to teardown since a new dispatcher host
143 // for this process might be created before then.
145 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_
);
146 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
149 context_wrapper_
= nullptr;
150 channel_ready_
= false;
153 void ServiceWorkerDispatcherHost::OnDestruct() const {
154 BrowserThread::DeleteOnIOThread::Destruct(this);
157 bool ServiceWorkerDispatcherHost::OnMessageReceived(
158 const IPC::Message
& message
) {
160 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost
, message
)
161 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker
,
162 OnRegisterServiceWorker
)
163 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker
,
164 OnUnregisterServiceWorker
)
165 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration
,
167 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated
,
169 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed
,
171 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId
,
172 OnSetHostedVersionId
)
173 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker
,
174 OnPostMessageToWorker
)
175 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection
,
176 OnWorkerReadyForInspection
)
177 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded
,
178 OnWorkerScriptLoaded
)
179 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed
,
180 OnWorkerScriptLoadFailed
)
181 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptEvaluated
,
182 OnWorkerScriptEvaluated
)
183 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted
,
185 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped
,
187 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload
,
188 OnPausedAfterDownload
)
189 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException
,
191 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage
,
192 OnReportConsoleMessage
)
193 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount
,
194 OnIncrementServiceWorkerRefCount
)
195 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount
,
196 OnDecrementServiceWorkerRefCount
)
197 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount
,
198 OnIncrementRegistrationRefCount
)
199 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount
,
200 OnDecrementRegistrationRefCount
)
201 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker
, OnTerminateWorker
)
202 IPC_MESSAGE_UNHANDLED(handled
= false)
203 IPC_END_MESSAGE_MAP()
205 if (!handled
&& GetContext()) {
207 GetContext()->embedded_worker_registry()->OnMessageReceived(message
);
209 BadMessageReceived();
215 bool ServiceWorkerDispatcherHost::Send(IPC::Message
* message
) {
216 if (channel_ready_
) {
217 BrowserMessageFilter::Send(message
);
218 // Don't bother passing through Send()'s result: it's not reliable.
222 pending_messages_
.push_back(message
);
226 ServiceWorkerRegistrationHandle
*
227 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
229 ServiceWorkerRegistration
* registration
) {
230 ServiceWorkerRegistrationHandle
* handle
=
231 FindRegistrationHandle(provider_id
, registration
->id());
233 handle
->IncrementRefCount();
237 scoped_ptr
<ServiceWorkerRegistrationHandle
> new_handle(
238 new ServiceWorkerRegistrationHandle(
239 GetContext()->AsWeakPtr(), this, provider_id
, registration
));
240 handle
= new_handle
.get();
241 RegisterServiceWorkerRegistrationHandle(new_handle
.Pass());
245 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
246 scoped_ptr
<ServiceWorkerHandle
> handle
) {
247 int handle_id
= handle
->handle_id();
248 handles_
.AddWithID(handle
.release(), handle_id
);
251 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
252 scoped_ptr
<ServiceWorkerRegistrationHandle
> handle
) {
253 int handle_id
= handle
->handle_id();
254 registration_handles_
.AddWithID(handle
.release(), handle_id
);
257 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
262 const GURL
& script_url
) {
263 TRACE_EVENT0("ServiceWorker",
264 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
266 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
269 WebServiceWorkerError::ErrorTypeAbort
,
270 base::ASCIIToUTF16(kShutdownErrorMessage
)));
273 if (!pattern
.is_valid() || !script_url
.is_valid()) {
274 BadMessageReceived();
278 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
279 render_process_id_
, provider_id
);
280 if (!provider_host
) {
281 BadMessageReceived();
284 if (!provider_host
->IsContextAlive()) {
285 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
288 WebServiceWorkerError::ErrorTypeAbort
,
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(
300 WebServiceWorkerError::ErrorTypeSecurity
,
301 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
305 if (!CanRegisterServiceWorker(
306 provider_host
->document_url(), pattern
, script_url
)) {
307 BadMessageReceived();
311 if (!GetContentClient()->browser()->AllowServiceWorker(
312 pattern
, provider_host
->topmost_frame_url(), resource_context_
)) {
313 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
316 WebServiceWorkerError::ErrorTypeDisabled
,
317 base::ASCIIToUTF16(kDisabledErrorMessage
)));
321 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
322 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
324 "Pattern", pattern
.spec(),
325 "Script URL", script_url
.spec());
326 GetContext()->RegisterServiceWorker(
330 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete
,
337 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
341 const GURL
& pattern
) {
342 TRACE_EVENT0("ServiceWorker",
343 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
345 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
348 blink::WebServiceWorkerError::ErrorTypeAbort
,
349 base::ASCIIToUTF16(kShutdownErrorMessage
)));
352 if (!pattern
.is_valid()) {
353 BadMessageReceived();
357 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
358 render_process_id_
, provider_id
);
359 if (!provider_host
) {
360 BadMessageReceived();
363 if (!provider_host
->IsContextAlive()) {
364 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
367 blink::WebServiceWorkerError::ErrorTypeAbort
,
368 base::ASCIIToUTF16(kShutdownErrorMessage
)));
372 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
373 if (provider_host
->document_url().is_empty()) {
374 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
377 WebServiceWorkerError::ErrorTypeSecurity
,
378 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
382 if (!CanUnregisterServiceWorker(provider_host
->document_url(), pattern
)) {
383 BadMessageReceived();
387 if (!GetContentClient()->browser()->AllowServiceWorker(
388 pattern
, provider_host
->topmost_frame_url(), resource_context_
)) {
389 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
392 WebServiceWorkerError::ErrorTypeDisabled
,
393 base::ASCIIToUTF16(kDisabledErrorMessage
)));
397 TRACE_EVENT_ASYNC_BEGIN1(
399 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
401 "Pattern", pattern
.spec());
402 GetContext()->UnregisterServiceWorker(
404 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete
,
410 void ServiceWorkerDispatcherHost::OnGetRegistration(
414 const GURL
& document_url
) {
415 TRACE_EVENT0("ServiceWorker",
416 "ServiceWorkerDispatcherHost::OnGetRegistration");
418 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
421 blink::WebServiceWorkerError::ErrorTypeAbort
,
422 base::ASCIIToUTF16(kShutdownErrorMessage
)));
425 if (!document_url
.is_valid()) {
426 BadMessageReceived();
430 ServiceWorkerProviderHost
* provider_host
= GetContext()->GetProviderHost(
431 render_process_id_
, provider_id
);
432 if (!provider_host
) {
433 BadMessageReceived();
436 if (!provider_host
->IsContextAlive()) {
437 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
440 blink::WebServiceWorkerError::ErrorTypeAbort
,
441 base::ASCIIToUTF16(kShutdownErrorMessage
)));
445 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
446 if (provider_host
->document_url().is_empty()) {
447 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
450 WebServiceWorkerError::ErrorTypeSecurity
,
451 base::ASCIIToUTF16(kNoDocumentURLErrorMessage
)));
455 if (!CanGetRegistration(provider_host
->document_url(), document_url
)) {
456 BadMessageReceived();
460 if (!GetContentClient()->browser()->AllowServiceWorker(
461 provider_host
->document_url(),
462 provider_host
->topmost_frame_url(),
463 resource_context_
)) {
464 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
467 WebServiceWorkerError::ErrorTypeDisabled
,
468 base::ASCIIToUTF16(kDisabledErrorMessage
)));
472 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
473 if (GetContext()->storage()->IsDisabled()) {
474 SendGetRegistrationError(thread_id
, request_id
, SERVICE_WORKER_ERROR_ABORT
);
478 TRACE_EVENT_ASYNC_BEGIN1(
480 "ServiceWorkerDispatcherHost::GetRegistration",
482 "Document URL", document_url
.spec());
484 GetContext()->storage()->FindRegistrationForDocument(
486 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete
,
493 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
495 const base::string16
& message
,
496 const std::vector
<int>& sent_message_port_ids
) {
497 TRACE_EVENT0("ServiceWorker",
498 "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
502 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
504 BadMessageReceived();
508 handle
->version()->DispatchMessageEvent(
509 message
, sent_message_port_ids
,
510 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
513 void ServiceWorkerDispatcherHost::OnProviderCreated(int provider_id
,
514 int render_frame_id
) {
515 TRACE_EVENT0("ServiceWorker",
516 "ServiceWorkerDispatcherHost::OnProviderCreated");
519 if (GetContext()->GetProviderHost(render_process_id_
, provider_id
)) {
520 BadMessageReceived();
523 scoped_ptr
<ServiceWorkerProviderHost
> provider_host(
524 new ServiceWorkerProviderHost(render_process_id_
,
527 GetContext()->AsWeakPtr(),
529 GetContext()->AddProviderHost(provider_host
.Pass());
532 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id
) {
533 TRACE_EVENT0("ServiceWorker",
534 "ServiceWorkerDispatcherHost::OnProviderDestroyed");
537 if (!GetContext()->GetProviderHost(render_process_id_
, provider_id
)) {
538 BadMessageReceived();
541 GetContext()->RemoveProviderHost(render_process_id_
, provider_id
);
544 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
545 int provider_id
, int64 version_id
) {
546 TRACE_EVENT0("ServiceWorker",
547 "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
550 ServiceWorkerProviderHost
* provider_host
=
551 GetContext()->GetProviderHost(render_process_id_
, provider_id
);
552 if (!provider_host
) {
553 BadMessageReceived();
556 if (!provider_host
->IsContextAlive())
558 if (!provider_host
->SetHostedVersionId(version_id
))
559 BadMessageReceived();
562 ServiceWorkerRegistrationHandle
*
563 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id
,
564 int64 registration_id
) {
565 for (IDMap
<ServiceWorkerRegistrationHandle
, IDMapOwnPointer
>::iterator
566 iter(®istration_handles_
);
569 ServiceWorkerRegistrationHandle
* handle
= iter
.GetCurrentValue();
571 if (handle
->provider_id() == provider_id
&& handle
->registration() &&
572 handle
->registration()->id() == registration_id
) {
579 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
581 ServiceWorkerRegistration
* registration
,
582 ServiceWorkerRegistrationObjectInfo
* info
,
583 ServiceWorkerVersionAttributes
* attrs
) {
584 ServiceWorkerRegistrationHandle
* handle
=
585 GetOrCreateRegistrationHandle(provider_id
, registration
);
586 *info
= handle
->GetObjectInfo();
588 attrs
->installing
= handle
->CreateServiceWorkerHandleAndPass(
589 registration
->installing_version());
590 attrs
->waiting
= handle
->CreateServiceWorkerHandleAndPass(
591 registration
->waiting_version());
592 attrs
->active
= handle
->CreateServiceWorkerHandleAndPass(
593 registration
->active_version());
596 void ServiceWorkerDispatcherHost::RegistrationComplete(
600 ServiceWorkerStatusCode status
,
601 int64 registration_id
) {
605 if (status
!= SERVICE_WORKER_OK
) {
606 SendRegistrationError(thread_id
, request_id
, status
);
610 ServiceWorkerRegistration
* registration
=
611 GetContext()->GetLiveRegistration(registration_id
);
612 DCHECK(registration
);
614 ServiceWorkerRegistrationObjectInfo info
;
615 ServiceWorkerVersionAttributes attrs
;
616 GetRegistrationObjectInfoAndVersionAttributes(
617 provider_id
, registration
, &info
, &attrs
);
619 Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
620 thread_id
, request_id
, info
, attrs
));
621 TRACE_EVENT_ASYNC_END1("ServiceWorker",
622 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
628 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
629 int embedded_worker_id
) {
630 TRACE_EVENT0("ServiceWorker",
631 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
634 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
635 if (!registry
->CanHandle(embedded_worker_id
))
637 registry
->OnWorkerReadyForInspection(render_process_id_
, embedded_worker_id
);
640 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
641 int embedded_worker_id
,
643 TRACE_EVENT0("ServiceWorker",
644 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
647 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
648 if (!registry
->CanHandle(embedded_worker_id
))
650 registry
->OnWorkerScriptLoaded(
651 render_process_id_
, thread_id
, embedded_worker_id
);
654 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
655 int embedded_worker_id
) {
656 TRACE_EVENT0("ServiceWorker",
657 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
660 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
661 if (!registry
->CanHandle(embedded_worker_id
))
663 registry
->OnWorkerScriptLoadFailed(render_process_id_
, embedded_worker_id
);
666 void ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated(
667 int embedded_worker_id
,
669 TRACE_EVENT0("ServiceWorker",
670 "ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated");
673 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
674 if (!registry
->CanHandle(embedded_worker_id
))
676 registry
->OnWorkerScriptEvaluated(
677 render_process_id_
, embedded_worker_id
, success
);
680 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id
) {
681 TRACE_EVENT0("ServiceWorker",
682 "ServiceWorkerDispatcherHost::OnWorkerStarted");
685 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
686 if (!registry
->CanHandle(embedded_worker_id
))
688 registry
->OnWorkerStarted(render_process_id_
, embedded_worker_id
);
691 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id
) {
692 TRACE_EVENT0("ServiceWorker",
693 "ServiceWorkerDispatcherHost::OnWorkerStopped");
696 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
697 if (!registry
->CanHandle(embedded_worker_id
))
699 registry
->OnWorkerStopped(render_process_id_
, embedded_worker_id
);
702 void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
703 int embedded_worker_id
) {
704 TRACE_EVENT0("ServiceWorker",
705 "ServiceWorkerDispatcherHost::OnPausedAfterDownload");
708 GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
709 render_process_id_
, embedded_worker_id
);
712 void ServiceWorkerDispatcherHost::OnReportException(
713 int embedded_worker_id
,
714 const base::string16
& error_message
,
717 const GURL
& source_url
) {
718 TRACE_EVENT0("ServiceWorker",
719 "ServiceWorkerDispatcherHost::OnReportException");
722 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
723 if (!registry
->CanHandle(embedded_worker_id
))
725 registry
->OnReportException(embedded_worker_id
,
732 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
733 int embedded_worker_id
,
734 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params
& params
) {
735 TRACE_EVENT0("ServiceWorker",
736 "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
739 EmbeddedWorkerRegistry
* registry
= GetContext()->embedded_worker_registry();
740 if (!registry
->CanHandle(embedded_worker_id
))
742 registry
->OnReportConsoleMessage(embedded_worker_id
,
743 params
.source_identifier
,
744 params
.message_level
,
750 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
752 TRACE_EVENT0("ServiceWorker",
753 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
754 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
756 BadMessageReceived();
759 handle
->IncrementRefCount();
762 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
764 TRACE_EVENT0("ServiceWorker",
765 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
766 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
768 BadMessageReceived();
771 handle
->DecrementRefCount();
772 if (handle
->HasNoRefCount())
773 handles_
.Remove(handle_id
);
776 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
777 int registration_handle_id
) {
778 TRACE_EVENT0("ServiceWorker",
779 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
780 ServiceWorkerRegistrationHandle
* handle
=
781 registration_handles_
.Lookup(registration_handle_id
);
783 BadMessageReceived();
786 handle
->IncrementRefCount();
789 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
790 int registration_handle_id
) {
791 TRACE_EVENT0("ServiceWorker",
792 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
793 ServiceWorkerRegistrationHandle
* handle
=
794 registration_handles_
.Lookup(registration_handle_id
);
796 BadMessageReceived();
799 handle
->DecrementRefCount();
800 if (handle
->HasNoRefCount())
801 registration_handles_
.Remove(registration_handle_id
);
804 void ServiceWorkerDispatcherHost::UnregistrationComplete(
807 ServiceWorkerStatusCode status
) {
808 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
809 SendUnregistrationError(thread_id
, request_id
, status
);
812 const bool is_success
= (status
== SERVICE_WORKER_OK
);
813 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id
,
816 TRACE_EVENT_ASYNC_END1(
818 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
823 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
827 ServiceWorkerStatusCode status
,
828 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
829 TRACE_EVENT_ASYNC_END1("ServiceWorker",
830 "ServiceWorkerDispatcherHost::GetRegistration",
833 registration
.get() ? registration
->id()
834 : kInvalidServiceWorkerRegistrationId
);
839 if (status
!= SERVICE_WORKER_OK
&& status
!= SERVICE_WORKER_ERROR_NOT_FOUND
) {
840 SendGetRegistrationError(thread_id
, request_id
, status
);
844 ServiceWorkerRegistrationObjectInfo info
;
845 ServiceWorkerVersionAttributes attrs
;
846 if (status
== SERVICE_WORKER_OK
) {
847 DCHECK(registration
.get());
848 if (!registration
->is_uninstalling()) {
849 GetRegistrationObjectInfoAndVersionAttributes(
850 provider_id
, registration
.get(), &info
, &attrs
);
854 Send(new ServiceWorkerMsg_DidGetRegistration(
855 thread_id
, request_id
, info
, attrs
));
858 void ServiceWorkerDispatcherHost::SendRegistrationError(
861 ServiceWorkerStatusCode status
) {
862 base::string16 error_message
;
863 blink::WebServiceWorkerError::ErrorType error_type
;
864 GetServiceWorkerRegistrationStatusResponse(
865 status
, &error_type
, &error_message
);
866 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
867 thread_id
, request_id
, error_type
, error_message
));
870 void ServiceWorkerDispatcherHost::SendUnregistrationError(
873 ServiceWorkerStatusCode status
) {
874 base::string16 error_message
;
875 blink::WebServiceWorkerError::ErrorType error_type
;
876 GetServiceWorkerRegistrationStatusResponse(
877 status
, &error_type
, &error_message
);
878 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
879 thread_id
, request_id
, error_type
, error_message
));
882 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
885 ServiceWorkerStatusCode status
) {
886 base::string16 error_message
;
887 blink::WebServiceWorkerError::ErrorType error_type
;
888 GetServiceWorkerRegistrationStatusResponse(
889 status
, &error_type
, &error_message
);
890 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
891 thread_id
, request_id
, error_type
, error_message
));
894 ServiceWorkerContextCore
* ServiceWorkerDispatcherHost::GetContext() {
895 if (!context_wrapper_
.get())
897 return context_wrapper_
->context();
900 void ServiceWorkerDispatcherHost::OnTerminateWorker(int handle_id
) {
901 ServiceWorkerHandle
* handle
= handles_
.Lookup(handle_id
);
903 BadMessageReceived();
906 handle
->version()->StopWorker(
907 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
910 } // namespace content