Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_dispatcher_host.cc
blob009cbe917edcda483ce1bf623c0ce1b846967754
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 CheckPatternIsUnderTheScriptDirectory(const GURL& pattern,
56 const GURL& script_url) {
57 size_t slash_pos = script_url.spec().rfind('/');
58 if (slash_pos == std::string::npos)
59 return false;
60 return pattern.spec().compare(
61 0, slash_pos + 1, script_url.spec(), 0, slash_pos + 1) == 0;
64 bool CanRegisterServiceWorker(const GURL& document_url,
65 const GURL& pattern,
66 const GURL& script_url) {
67 DCHECK(document_url.is_valid());
68 DCHECK(pattern.is_valid());
69 DCHECK(script_url.is_valid());
70 return AllOriginsMatch(document_url, pattern, script_url) &&
71 OriginCanAccessServiceWorkers(document_url) &&
72 CheckPatternIsUnderTheScriptDirectory(pattern, script_url);
75 bool CanUnregisterServiceWorker(const GURL& document_url,
76 const GURL& pattern) {
77 DCHECK(document_url.is_valid());
78 DCHECK(pattern.is_valid());
79 return document_url.GetOrigin() == pattern.GetOrigin() &&
80 OriginCanAccessServiceWorkers(document_url);
83 bool CanGetRegistration(const GURL& document_url,
84 const GURL& given_document_url) {
85 DCHECK(document_url.is_valid());
86 DCHECK(given_document_url.is_valid());
87 return document_url.GetOrigin() == given_document_url.GetOrigin() &&
88 OriginCanAccessServiceWorkers(document_url);
91 } // namespace
93 ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
94 int render_process_id,
95 MessagePortMessageFilter* message_port_message_filter,
96 ResourceContext* resource_context)
97 : BrowserMessageFilter(kFilteredMessageClasses,
98 arraysize(kFilteredMessageClasses)),
99 render_process_id_(render_process_id),
100 message_port_message_filter_(message_port_message_filter),
101 resource_context_(resource_context),
102 channel_ready_(false) {
105 ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
106 if (GetContext()) {
107 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_);
108 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
109 render_process_id_);
113 void ServiceWorkerDispatcherHost::Init(
114 ServiceWorkerContextWrapper* context_wrapper) {
115 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
116 BrowserThread::PostTask(
117 BrowserThread::IO, FROM_HERE,
118 base::Bind(&ServiceWorkerDispatcherHost::Init,
119 this, make_scoped_refptr(context_wrapper)));
120 return;
123 context_wrapper_ = context_wrapper;
124 GetContext()->embedded_worker_registry()->AddChildProcessSender(
125 render_process_id_, this, message_port_message_filter_);
128 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender* sender) {
129 TRACE_EVENT0("ServiceWorker",
130 "ServiceWorkerDispatcherHost::OnFilterAdded");
131 channel_ready_ = true;
132 std::vector<IPC::Message*> messages;
133 pending_messages_.release(&messages);
134 for (size_t i = 0; i < messages.size(); ++i) {
135 BrowserMessageFilter::Send(messages[i]);
139 void ServiceWorkerDispatcherHost::OnFilterRemoved() {
140 // Don't wait until the destructor to teardown since a new dispatcher host
141 // for this process might be created before then.
142 if (GetContext()) {
143 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_);
144 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
145 render_process_id_);
147 context_wrapper_ = nullptr;
148 channel_ready_ = false;
151 void ServiceWorkerDispatcherHost::OnDestruct() const {
152 BrowserThread::DeleteOnIOThread::Destruct(this);
155 bool ServiceWorkerDispatcherHost::OnMessageReceived(
156 const IPC::Message& message) {
157 bool handled = true;
158 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost, message)
159 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker,
160 OnRegisterServiceWorker)
161 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker,
162 OnUnregisterServiceWorker)
163 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration,
164 OnGetRegistration)
165 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated,
166 OnProviderCreated)
167 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
168 OnProviderDestroyed)
169 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId,
170 OnSetHostedVersionId)
171 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
172 OnPostMessageToWorker)
173 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection,
174 OnWorkerReadyForInspection)
175 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
176 OnWorkerScriptLoaded)
177 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
178 OnWorkerScriptLoadFailed)
179 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptEvaluated,
180 OnWorkerScriptEvaluated)
181 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
182 OnWorkerStarted)
183 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
184 OnWorkerStopped)
185 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload,
186 OnPausedAfterDownload)
187 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException,
188 OnReportException)
189 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage,
190 OnReportConsoleMessage)
191 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
192 OnIncrementServiceWorkerRefCount)
193 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
194 OnDecrementServiceWorkerRefCount)
195 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount,
196 OnIncrementRegistrationRefCount)
197 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount,
198 OnDecrementRegistrationRefCount)
199 IPC_MESSAGE_UNHANDLED(handled = false)
200 IPC_END_MESSAGE_MAP()
202 if (!handled && GetContext()) {
203 handled =
204 GetContext()->embedded_worker_registry()->OnMessageReceived(message);
205 if (!handled)
206 BadMessageReceived();
209 return handled;
212 bool ServiceWorkerDispatcherHost::Send(IPC::Message* message) {
213 if (channel_ready_) {
214 BrowserMessageFilter::Send(message);
215 // Don't bother passing through Send()'s result: it's not reliable.
216 return true;
219 pending_messages_.push_back(message);
220 return true;
223 ServiceWorkerRegistrationHandle*
224 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
225 int provider_id,
226 ServiceWorkerRegistration* registration) {
227 ServiceWorkerRegistrationHandle* handle =
228 FindRegistrationHandle(provider_id, registration->id());
229 if (handle) {
230 handle->IncrementRefCount();
231 return handle;
234 scoped_ptr<ServiceWorkerRegistrationHandle> new_handle(
235 new ServiceWorkerRegistrationHandle(
236 GetContext()->AsWeakPtr(), this, provider_id, registration));
237 handle = new_handle.get();
238 RegisterServiceWorkerRegistrationHandle(new_handle.Pass());
239 return handle;
242 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
243 scoped_ptr<ServiceWorkerHandle> handle) {
244 int handle_id = handle->handle_id();
245 handles_.AddWithID(handle.release(), handle_id);
248 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
249 scoped_ptr<ServiceWorkerRegistrationHandle> handle) {
250 int handle_id = handle->handle_id();
251 registration_handles_.AddWithID(handle.release(), handle_id);
254 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
255 int thread_id,
256 int request_id,
257 int provider_id,
258 const GURL& pattern,
259 const GURL& script_url) {
260 TRACE_EVENT0("ServiceWorker",
261 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
262 if (!GetContext()) {
263 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
264 thread_id,
265 request_id,
266 WebServiceWorkerError::ErrorTypeAbort,
267 base::ASCIIToUTF16(kShutdownErrorMessage)));
268 return;
270 if (!pattern.is_valid() || !script_url.is_valid()) {
271 BadMessageReceived();
272 return;
275 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
276 render_process_id_, provider_id);
277 if (!provider_host) {
278 BadMessageReceived();
279 return;
281 if (!provider_host->IsContextAlive()) {
282 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
283 thread_id,
284 request_id,
285 WebServiceWorkerError::ErrorTypeAbort,
286 base::ASCIIToUTF16(kShutdownErrorMessage)));
287 return;
290 if (!CanRegisterServiceWorker(
291 provider_host->document_url(), pattern, script_url)) {
292 BadMessageReceived();
293 return;
296 if (!GetContentClient()->browser()->AllowServiceWorker(
297 pattern, provider_host->topmost_frame_url(), resource_context_)) {
298 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
299 thread_id,
300 request_id,
301 WebServiceWorkerError::ErrorTypeDisabled,
302 base::ASCIIToUTF16(kDisabledErrorMessage)));
303 return;
306 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
307 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
308 request_id,
309 "Pattern", pattern.spec(),
310 "Script URL", script_url.spec());
311 GetContext()->RegisterServiceWorker(
312 pattern,
313 script_url,
314 provider_host,
315 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete,
316 this,
317 thread_id,
318 provider_id,
319 request_id));
322 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
323 int thread_id,
324 int request_id,
325 int provider_id,
326 const GURL& pattern) {
327 TRACE_EVENT0("ServiceWorker",
328 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
329 if (!GetContext()) {
330 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
331 thread_id,
332 request_id,
333 blink::WebServiceWorkerError::ErrorTypeAbort,
334 base::ASCIIToUTF16(kShutdownErrorMessage)));
335 return;
337 if (!pattern.is_valid()) {
338 BadMessageReceived();
339 return;
342 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
343 render_process_id_, provider_id);
344 if (!provider_host) {
345 BadMessageReceived();
346 return;
348 if (!provider_host->IsContextAlive()) {
349 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
350 thread_id,
351 request_id,
352 blink::WebServiceWorkerError::ErrorTypeAbort,
353 base::ASCIIToUTF16(kShutdownErrorMessage)));
354 return;
357 if (!CanUnregisterServiceWorker(provider_host->document_url(), pattern)) {
358 BadMessageReceived();
359 return;
362 if (!GetContentClient()->browser()->AllowServiceWorker(
363 pattern, provider_host->topmost_frame_url(), resource_context_)) {
364 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
365 thread_id,
366 request_id,
367 WebServiceWorkerError::ErrorTypeDisabled,
368 base::ASCIIToUTF16(kDisabledErrorMessage)));
369 return;
372 TRACE_EVENT_ASYNC_BEGIN1(
373 "ServiceWorker",
374 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
375 request_id,
376 "Pattern", pattern.spec());
377 GetContext()->UnregisterServiceWorker(
378 pattern,
379 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete,
380 this,
381 thread_id,
382 request_id));
385 void ServiceWorkerDispatcherHost::OnGetRegistration(
386 int thread_id,
387 int request_id,
388 int provider_id,
389 const GURL& document_url) {
390 TRACE_EVENT0("ServiceWorker",
391 "ServiceWorkerDispatcherHost::OnGetRegistration");
392 if (!GetContext()) {
393 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
394 thread_id,
395 request_id,
396 blink::WebServiceWorkerError::ErrorTypeAbort,
397 base::ASCIIToUTF16(kShutdownErrorMessage)));
398 return;
400 if (!document_url.is_valid()) {
401 BadMessageReceived();
402 return;
405 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
406 render_process_id_, provider_id);
407 if (!provider_host) {
408 BadMessageReceived();
409 return;
411 if (!provider_host->IsContextAlive()) {
412 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
413 thread_id,
414 request_id,
415 blink::WebServiceWorkerError::ErrorTypeAbort,
416 base::ASCIIToUTF16(kShutdownErrorMessage)));
417 return;
420 if (!CanGetRegistration(provider_host->document_url(), document_url)) {
421 BadMessageReceived();
422 return;
425 if (!GetContentClient()->browser()->AllowServiceWorker(
426 provider_host->document_url(),
427 provider_host->topmost_frame_url(),
428 resource_context_)) {
429 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
430 thread_id,
431 request_id,
432 WebServiceWorkerError::ErrorTypeDisabled,
433 base::ASCIIToUTF16(kDisabledErrorMessage)));
434 return;
437 DCHECK_CURRENTLY_ON(BrowserThread::IO);
438 if (GetContext()->storage()->IsDisabled()) {
439 SendGetRegistrationError(thread_id, request_id, SERVICE_WORKER_ERROR_ABORT);
440 return;
443 TRACE_EVENT_ASYNC_BEGIN1(
444 "ServiceWorker",
445 "ServiceWorkerDispatcherHost::GetRegistration",
446 request_id,
447 "Document URL", document_url.spec());
449 GetContext()->storage()->FindRegistrationForDocument(
450 document_url,
451 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete,
452 this,
453 thread_id,
454 provider_id,
455 request_id));
458 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
459 int handle_id,
460 const base::string16& message,
461 const std::vector<int>& sent_message_port_ids) {
462 TRACE_EVENT0("ServiceWorker",
463 "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
464 if (!GetContext())
465 return;
467 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
468 if (!handle) {
469 BadMessageReceived();
470 return;
473 handle->version()->DispatchMessageEvent(
474 message, sent_message_port_ids,
475 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
478 void ServiceWorkerDispatcherHost::OnProviderCreated(int provider_id) {
479 TRACE_EVENT0("ServiceWorker",
480 "ServiceWorkerDispatcherHost::OnProviderCreated");
481 if (!GetContext())
482 return;
483 if (GetContext()->GetProviderHost(render_process_id_, provider_id)) {
484 BadMessageReceived();
485 return;
487 scoped_ptr<ServiceWorkerProviderHost> provider_host(
488 new ServiceWorkerProviderHost(
489 render_process_id_, provider_id, GetContext()->AsWeakPtr(), this));
490 GetContext()->AddProviderHost(provider_host.Pass());
493 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
494 TRACE_EVENT0("ServiceWorker",
495 "ServiceWorkerDispatcherHost::OnProviderDestroyed");
496 if (!GetContext())
497 return;
498 if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) {
499 BadMessageReceived();
500 return;
502 GetContext()->RemoveProviderHost(render_process_id_, provider_id);
505 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
506 int provider_id, int64 version_id) {
507 TRACE_EVENT0("ServiceWorker",
508 "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
509 if (!GetContext())
510 return;
511 ServiceWorkerProviderHost* provider_host =
512 GetContext()->GetProviderHost(render_process_id_, provider_id);
513 if (!provider_host) {
514 BadMessageReceived();
515 return;
517 if (!provider_host->IsContextAlive())
518 return;
519 if (!provider_host->SetHostedVersionId(version_id))
520 BadMessageReceived();
523 ServiceWorkerRegistrationHandle*
524 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
525 int64 registration_id) {
526 for (IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer>::iterator
527 iter(&registration_handles_);
528 !iter.IsAtEnd();
529 iter.Advance()) {
530 ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
531 DCHECK(handle);
532 if (handle->provider_id() == provider_id && handle->registration() &&
533 handle->registration()->id() == registration_id) {
534 return handle;
537 return NULL;
540 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
541 int provider_id,
542 ServiceWorkerRegistration* registration,
543 ServiceWorkerRegistrationObjectInfo* info,
544 ServiceWorkerVersionAttributes* attrs) {
545 ServiceWorkerRegistrationHandle* handle =
546 GetOrCreateRegistrationHandle(provider_id, registration);
547 *info = handle->GetObjectInfo();
549 attrs->installing = handle->CreateServiceWorkerHandleAndPass(
550 registration->installing_version());
551 attrs->waiting = handle->CreateServiceWorkerHandleAndPass(
552 registration->waiting_version());
553 attrs->active = handle->CreateServiceWorkerHandleAndPass(
554 registration->active_version());
557 void ServiceWorkerDispatcherHost::RegistrationComplete(
558 int thread_id,
559 int provider_id,
560 int request_id,
561 ServiceWorkerStatusCode status,
562 int64 registration_id) {
563 if (!GetContext())
564 return;
566 if (status != SERVICE_WORKER_OK) {
567 SendRegistrationError(thread_id, request_id, status);
568 return;
571 ServiceWorkerRegistration* registration =
572 GetContext()->GetLiveRegistration(registration_id);
573 DCHECK(registration);
575 ServiceWorkerRegistrationObjectInfo info;
576 ServiceWorkerVersionAttributes attrs;
577 GetRegistrationObjectInfoAndVersionAttributes(
578 provider_id, registration, &info, &attrs);
580 Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
581 thread_id, request_id, info, attrs));
582 TRACE_EVENT_ASYNC_END1("ServiceWorker",
583 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
584 request_id,
585 "Registration ID",
586 registration_id);
589 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
590 int embedded_worker_id) {
591 TRACE_EVENT0("ServiceWorker",
592 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
593 if (!GetContext())
594 return;
595 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
596 if (!registry->CanHandle(embedded_worker_id))
597 return;
598 registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id);
601 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
602 int embedded_worker_id,
603 int thread_id) {
604 TRACE_EVENT0("ServiceWorker",
605 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
606 if (!GetContext())
607 return;
608 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
609 if (!registry->CanHandle(embedded_worker_id))
610 return;
611 registry->OnWorkerScriptLoaded(
612 render_process_id_, thread_id, embedded_worker_id);
615 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
616 int embedded_worker_id) {
617 TRACE_EVENT0("ServiceWorker",
618 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
619 if (!GetContext())
620 return;
621 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
622 if (!registry->CanHandle(embedded_worker_id))
623 return;
624 registry->OnWorkerScriptLoadFailed(render_process_id_, embedded_worker_id);
627 void ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated(
628 int embedded_worker_id,
629 bool success) {
630 TRACE_EVENT0("ServiceWorker",
631 "ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated");
632 if (!GetContext())
633 return;
634 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
635 if (!registry->CanHandle(embedded_worker_id))
636 return;
637 registry->OnWorkerScriptEvaluated(
638 render_process_id_, embedded_worker_id, success);
641 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id) {
642 TRACE_EVENT0("ServiceWorker",
643 "ServiceWorkerDispatcherHost::OnWorkerStarted");
644 if (!GetContext())
645 return;
646 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
647 if (!registry->CanHandle(embedded_worker_id))
648 return;
649 registry->OnWorkerStarted(render_process_id_, embedded_worker_id);
652 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id) {
653 TRACE_EVENT0("ServiceWorker",
654 "ServiceWorkerDispatcherHost::OnWorkerStopped");
655 if (!GetContext())
656 return;
657 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
658 if (!registry->CanHandle(embedded_worker_id))
659 return;
660 registry->OnWorkerStopped(render_process_id_, embedded_worker_id);
663 void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
664 int embedded_worker_id) {
665 TRACE_EVENT0("ServiceWorker",
666 "ServiceWorkerDispatcherHost::OnPausedAfterDownload");
667 if (!GetContext())
668 return;
669 GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
670 render_process_id_, embedded_worker_id);
673 void ServiceWorkerDispatcherHost::OnReportException(
674 int embedded_worker_id,
675 const base::string16& error_message,
676 int line_number,
677 int column_number,
678 const GURL& source_url) {
679 TRACE_EVENT0("ServiceWorker",
680 "ServiceWorkerDispatcherHost::OnReportException");
681 if (!GetContext())
682 return;
683 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
684 if (!registry->CanHandle(embedded_worker_id))
685 return;
686 registry->OnReportException(embedded_worker_id,
687 error_message,
688 line_number,
689 column_number,
690 source_url);
693 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
694 int embedded_worker_id,
695 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params& params) {
696 TRACE_EVENT0("ServiceWorker",
697 "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
698 if (!GetContext())
699 return;
700 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
701 if (!registry->CanHandle(embedded_worker_id))
702 return;
703 registry->OnReportConsoleMessage(embedded_worker_id,
704 params.source_identifier,
705 params.message_level,
706 params.message,
707 params.line_number,
708 params.source_url);
711 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
712 int handle_id) {
713 TRACE_EVENT0("ServiceWorker",
714 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
715 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
716 if (!handle) {
717 BadMessageReceived();
718 return;
720 handle->IncrementRefCount();
723 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
724 int handle_id) {
725 TRACE_EVENT0("ServiceWorker",
726 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
727 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
728 if (!handle) {
729 BadMessageReceived();
730 return;
732 handle->DecrementRefCount();
733 if (handle->HasNoRefCount())
734 handles_.Remove(handle_id);
737 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
738 int registration_handle_id) {
739 TRACE_EVENT0("ServiceWorker",
740 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
741 ServiceWorkerRegistrationHandle* handle =
742 registration_handles_.Lookup(registration_handle_id);
743 if (!handle) {
744 BadMessageReceived();
745 return;
747 handle->IncrementRefCount();
750 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
751 int registration_handle_id) {
752 TRACE_EVENT0("ServiceWorker",
753 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
754 ServiceWorkerRegistrationHandle* handle =
755 registration_handles_.Lookup(registration_handle_id);
756 if (!handle) {
757 BadMessageReceived();
758 return;
760 handle->DecrementRefCount();
761 if (handle->HasNoRefCount())
762 registration_handles_.Remove(registration_handle_id);
765 void ServiceWorkerDispatcherHost::UnregistrationComplete(
766 int thread_id,
767 int request_id,
768 ServiceWorkerStatusCode status) {
769 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
770 SendUnregistrationError(thread_id, request_id, status);
771 return;
773 const bool is_success = (status == SERVICE_WORKER_OK);
774 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id,
775 request_id,
776 is_success));
777 TRACE_EVENT_ASYNC_END1(
778 "ServiceWorker",
779 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
780 request_id,
781 "Status", status);
784 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
785 int thread_id,
786 int provider_id,
787 int request_id,
788 ServiceWorkerStatusCode status,
789 const scoped_refptr<ServiceWorkerRegistration>& registration) {
790 TRACE_EVENT_ASYNC_END1("ServiceWorker",
791 "ServiceWorkerDispatcherHost::GetRegistration",
792 request_id,
793 "Registration ID",
794 registration.get() ? registration->id()
795 : kInvalidServiceWorkerRegistrationId);
797 if (!GetContext())
798 return;
800 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
801 SendGetRegistrationError(thread_id, request_id, status);
802 return;
805 ServiceWorkerRegistrationObjectInfo info;
806 ServiceWorkerVersionAttributes attrs;
807 if (status == SERVICE_WORKER_OK) {
808 DCHECK(registration.get());
809 if (!registration->is_uninstalling()) {
810 GetRegistrationObjectInfoAndVersionAttributes(
811 provider_id, registration.get(), &info, &attrs);
815 Send(new ServiceWorkerMsg_DidGetRegistration(
816 thread_id, request_id, info, attrs));
819 void ServiceWorkerDispatcherHost::SendRegistrationError(
820 int thread_id,
821 int request_id,
822 ServiceWorkerStatusCode status) {
823 base::string16 error_message;
824 blink::WebServiceWorkerError::ErrorType error_type;
825 GetServiceWorkerRegistrationStatusResponse(
826 status, &error_type, &error_message);
827 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
828 thread_id, request_id, error_type, error_message));
831 void ServiceWorkerDispatcherHost::SendUnregistrationError(
832 int thread_id,
833 int request_id,
834 ServiceWorkerStatusCode status) {
835 base::string16 error_message;
836 blink::WebServiceWorkerError::ErrorType error_type;
837 GetServiceWorkerRegistrationStatusResponse(
838 status, &error_type, &error_message);
839 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
840 thread_id, request_id, error_type, error_message));
843 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
844 int thread_id,
845 int request_id,
846 ServiceWorkerStatusCode status) {
847 base::string16 error_message;
848 blink::WebServiceWorkerError::ErrorType error_type;
849 GetServiceWorkerRegistrationStatusResponse(
850 status, &error_type, &error_message);
851 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
852 thread_id, request_id, error_type, error_message));
855 ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
856 if (!context_wrapper_.get())
857 return nullptr;
858 return context_wrapper_->context();
861 } // namespace content