Process Alt-Svc headers.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_dispatcher_host.cc
blob1c443d33f8d9c4dc99dbff486b2f8f87197fa1c8
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/profiler/scoped_tracker.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/trace_event/trace_event.h"
11 #include "content/browser/bad_message.h"
12 #include "content/browser/message_port_message_filter.h"
13 #include "content/browser/message_port_service.h"
14 #include "content/browser/service_worker/embedded_worker_registry.h"
15 #include "content/browser/service_worker/service_worker_context_core.h"
16 #include "content/browser/service_worker/service_worker_context_wrapper.h"
17 #include "content/browser/service_worker/service_worker_handle.h"
18 #include "content/browser/service_worker/service_worker_registration.h"
19 #include "content/browser/service_worker/service_worker_registration_handle.h"
20 #include "content/browser/service_worker/service_worker_utils.h"
21 #include "content/common/service_worker/embedded_worker_messages.h"
22 #include "content/common/service_worker/service_worker_messages.h"
23 #include "content/common/service_worker/service_worker_types.h"
24 #include "content/public/browser/content_browser_client.h"
25 #include "content/public/common/content_client.h"
26 #include "content/public/common/origin_util.h"
27 #include "ipc/ipc_message_macros.h"
28 #include "net/base/net_util.h"
29 #include "third_party/WebKit/public/platform/WebServiceWorkerError.h"
30 #include "url/gurl.h"
32 using blink::WebServiceWorkerError;
34 namespace content {
36 namespace {
38 const char kNoDocumentURLErrorMessage[] =
39 "No URL is associated with the caller's document.";
40 const char kShutdownErrorMessage[] =
41 "The Service Worker system has shutdown.";
42 const char kUserDeniedPermissionMessage[] =
43 "The user denied permission to use Service Worker.";
45 const uint32 kFilteredMessageClasses[] = {
46 ServiceWorkerMsgStart,
47 EmbeddedWorkerMsgStart,
50 bool AllOriginsMatch(const GURL& url_a, const GURL& url_b, const GURL& url_c) {
51 return url_a.GetOrigin() == url_b.GetOrigin() &&
52 url_a.GetOrigin() == url_c.GetOrigin();
55 bool CanRegisterServiceWorker(const GURL& document_url,
56 const GURL& pattern,
57 const GURL& script_url) {
58 DCHECK(document_url.is_valid());
59 DCHECK(pattern.is_valid());
60 DCHECK(script_url.is_valid());
61 return AllOriginsMatch(document_url, pattern, script_url) &&
62 OriginCanAccessServiceWorkers(document_url) &&
63 OriginCanAccessServiceWorkers(pattern) &&
64 OriginCanAccessServiceWorkers(script_url);
67 bool CanUnregisterServiceWorker(const GURL& document_url,
68 const GURL& pattern) {
69 DCHECK(document_url.is_valid());
70 DCHECK(pattern.is_valid());
71 return document_url.GetOrigin() == pattern.GetOrigin() &&
72 OriginCanAccessServiceWorkers(document_url) &&
73 OriginCanAccessServiceWorkers(pattern);
76 bool CanUpdateServiceWorker(const GURL& document_url, const GURL& pattern) {
77 DCHECK(document_url.is_valid());
78 DCHECK(pattern.is_valid());
79 DCHECK(OriginCanAccessServiceWorkers(document_url));
80 DCHECK(OriginCanAccessServiceWorkers(pattern));
81 return document_url.GetOrigin() == pattern.GetOrigin();
84 bool CanGetRegistration(const GURL& document_url,
85 const GURL& given_document_url) {
86 DCHECK(document_url.is_valid());
87 DCHECK(given_document_url.is_valid());
88 return document_url.GetOrigin() == given_document_url.GetOrigin() &&
89 OriginCanAccessServiceWorkers(document_url) &&
90 OriginCanAccessServiceWorkers(given_document_url);
93 } // namespace
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() {
108 if (GetContext()) {
109 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_);
110 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
111 render_process_id_);
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)));
122 return;
125 context_wrapper_ = context_wrapper;
126 if (!GetContext())
127 return;
128 GetContext()->embedded_worker_registry()->AddChildProcessSender(
129 render_process_id_, this, message_port_message_filter_);
132 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender* sender) {
133 TRACE_EVENT0("ServiceWorker",
134 "ServiceWorkerDispatcherHost::OnFilterAdded");
135 channel_ready_ = true;
136 std::vector<IPC::Message*> messages;
137 pending_messages_.release(&messages);
138 for (size_t i = 0; i < messages.size(); ++i) {
139 BrowserMessageFilter::Send(messages[i]);
143 void ServiceWorkerDispatcherHost::OnFilterRemoved() {
144 // Don't wait until the destructor to teardown since a new dispatcher host
145 // for this process might be created before then.
146 if (GetContext()) {
147 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_);
148 GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
149 render_process_id_);
151 context_wrapper_ = nullptr;
152 channel_ready_ = false;
155 void ServiceWorkerDispatcherHost::OnDestruct() const {
156 BrowserThread::DeleteOnIOThread::Destruct(this);
159 bool ServiceWorkerDispatcherHost::OnMessageReceived(
160 const IPC::Message& message) {
161 bool handled = true;
162 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost, message)
163 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker,
164 OnRegisterServiceWorker)
165 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UpdateServiceWorker,
166 OnUpdateServiceWorker)
167 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker,
168 OnUnregisterServiceWorker)
169 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration,
170 OnGetRegistration)
171 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistrations,
172 OnGetRegistrations)
173 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistrationForReady,
174 OnGetRegistrationForReady)
175 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated,
176 OnProviderCreated)
177 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
178 OnProviderDestroyed)
179 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId,
180 OnSetHostedVersionId)
181 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
182 OnPostMessageToWorker)
183 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection,
184 OnWorkerReadyForInspection)
185 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
186 OnWorkerScriptLoaded)
187 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
188 OnWorkerScriptLoadFailed)
189 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptEvaluated,
190 OnWorkerScriptEvaluated)
191 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
192 OnWorkerStarted)
193 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
194 OnWorkerStopped)
195 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException,
196 OnReportException)
197 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage,
198 OnReportConsoleMessage)
199 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
200 OnIncrementServiceWorkerRefCount)
201 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
202 OnDecrementServiceWorkerRefCount)
203 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount,
204 OnIncrementRegistrationRefCount)
205 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount,
206 OnDecrementRegistrationRefCount)
207 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker, OnTerminateWorker)
208 IPC_MESSAGE_UNHANDLED(handled = false)
209 IPC_END_MESSAGE_MAP()
211 if (!handled && GetContext()) {
212 handled = GetContext()->embedded_worker_registry()->OnMessageReceived(
213 message, render_process_id_);
214 if (!handled)
215 bad_message::ReceivedBadMessage(this, bad_message::SWDH_NOT_HANDLED);
218 return handled;
221 bool ServiceWorkerDispatcherHost::Send(IPC::Message* message) {
222 if (channel_ready_) {
223 BrowserMessageFilter::Send(message);
224 // Don't bother passing through Send()'s result: it's not reliable.
225 return true;
228 pending_messages_.push_back(message);
229 return true;
232 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
233 scoped_ptr<ServiceWorkerHandle> handle) {
234 int handle_id = handle->handle_id();
235 handles_.AddWithID(handle.release(), handle_id);
238 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
239 scoped_ptr<ServiceWorkerRegistrationHandle> handle) {
240 int handle_id = handle->handle_id();
241 registration_handles_.AddWithID(handle.release(), handle_id);
244 ServiceWorkerHandle* ServiceWorkerDispatcherHost::FindServiceWorkerHandle(
245 int provider_id,
246 int64 version_id) {
247 for (IDMap<ServiceWorkerHandle, IDMapOwnPointer>::iterator iter(&handles_);
248 !iter.IsAtEnd(); iter.Advance()) {
249 ServiceWorkerHandle* handle = iter.GetCurrentValue();
250 DCHECK(handle);
251 DCHECK(handle->version());
252 if (handle->provider_id() == provider_id &&
253 handle->version()->version_id() == version_id) {
254 return handle;
257 return NULL;
260 ServiceWorkerRegistrationHandle*
261 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
262 base::WeakPtr<ServiceWorkerProviderHost> provider_host,
263 ServiceWorkerRegistration* registration) {
264 DCHECK(provider_host);
265 ServiceWorkerRegistrationHandle* handle =
266 FindRegistrationHandle(provider_host->provider_id(), registration->id());
267 if (handle) {
268 handle->IncrementRefCount();
269 return handle;
272 scoped_ptr<ServiceWorkerRegistrationHandle> new_handle(
273 new ServiceWorkerRegistrationHandle(
274 GetContext()->AsWeakPtr(), provider_host, registration));
275 handle = new_handle.get();
276 RegisterServiceWorkerRegistrationHandle(new_handle.Pass());
277 return handle;
280 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
281 int thread_id,
282 int request_id,
283 int provider_id,
284 const GURL& pattern,
285 const GURL& script_url) {
286 TRACE_EVENT0("ServiceWorker",
287 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
288 if (!GetContext()) {
289 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
290 thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort,
291 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) +
292 base::ASCIIToUTF16(kShutdownErrorMessage)));
293 return;
295 if (!pattern.is_valid() || !script_url.is_valid()) {
296 bad_message::ReceivedBadMessage(this, bad_message::SWDH_REGISTER_BAD_URL);
297 return;
300 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
301 render_process_id_, provider_id);
302 if (!provider_host) {
303 bad_message::ReceivedBadMessage(this, bad_message::SWDH_REGISTER_NO_HOST);
304 return;
306 if (!provider_host->IsContextAlive()) {
307 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
308 thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort,
309 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) +
310 base::ASCIIToUTF16(kShutdownErrorMessage)));
311 return;
314 // TODO(ksakamoto): Currently, document_url is empty if the document is in an
315 // IFRAME using frame.contentDocument.write(...). We can remove this check
316 // once crbug.com/439697 is fixed.
317 if (provider_host->document_url().is_empty()) {
318 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
319 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity,
320 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) +
321 base::ASCIIToUTF16(kNoDocumentURLErrorMessage)));
322 return;
325 if (!CanRegisterServiceWorker(
326 provider_host->document_url(), pattern, script_url)) {
327 bad_message::ReceivedBadMessage(this, bad_message::SWDH_REGISTER_CANNOT);
328 return;
331 std::string error_message;
332 if (ServiceWorkerUtils::ContainsDisallowedCharacter(pattern, script_url,
333 &error_message)) {
334 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
335 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity,
336 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) +
337 base::UTF8ToUTF16(error_message)));
338 return;
341 if (!GetContentClient()->browser()->AllowServiceWorker(
342 pattern, provider_host->topmost_frame_url(), resource_context_,
343 render_process_id_, provider_host->frame_id())) {
344 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
345 thread_id, request_id, WebServiceWorkerError::ErrorTypeUnknown,
346 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) +
347 base::ASCIIToUTF16(kUserDeniedPermissionMessage)));
348 return;
351 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
352 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
353 request_id,
354 "Pattern", pattern.spec(),
355 "Script URL", script_url.spec());
356 GetContext()->RegisterServiceWorker(
357 pattern,
358 script_url,
359 provider_host,
360 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete,
361 this,
362 thread_id,
363 provider_id,
364 request_id));
367 void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int provider_id,
368 int64 registration_id) {
369 TRACE_EVENT0("ServiceWorker",
370 "ServiceWorkerDispatcherHost::OnUpdateServiceWorker");
371 if (!GetContext())
372 return;
374 ServiceWorkerProviderHost* provider_host =
375 GetContext()->GetProviderHost(render_process_id_, provider_id);
376 if (!provider_host) {
377 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_NO_HOST);
378 return;
380 if (!provider_host->IsContextAlive())
381 return;
383 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
384 if (provider_host->document_url().is_empty())
385 return;
387 ServiceWorkerRegistration* registration =
388 GetContext()->GetLiveRegistration(registration_id);
389 if (!registration) {
390 // |registration| must be alive because a renderer retains a registration
391 // reference at this point.
392 bad_message::ReceivedBadMessage(
393 this, bad_message::SWDH_UPDATE_BAD_REGISTRATION_ID);
394 return;
397 if (!CanUpdateServiceWorker(provider_host->document_url(),
398 registration->pattern())) {
399 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_CANNOT);
400 return;
403 if (!GetContentClient()->browser()->AllowServiceWorker(
404 registration->pattern(), provider_host->topmost_frame_url(),
405 resource_context_, render_process_id_, provider_host->frame_id())) {
406 return;
409 if (!registration->GetNewestVersion()) {
410 // This can happen if update() is called during initial script evaluation.
411 // Abort the following steps according to the spec.
412 return;
415 // The spec says, "update() pings the server for an updated version of this
416 // script without consulting caches", so set |force_bypass_cache| to true.
417 GetContext()->UpdateServiceWorker(registration,
418 true /* force_bypass_cache */);
421 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
422 int thread_id,
423 int request_id,
424 int provider_id,
425 int64 registration_id) {
426 TRACE_EVENT0("ServiceWorker",
427 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
428 if (!GetContext()) {
429 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
430 thread_id, request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
431 base::ASCIIToUTF16(kShutdownErrorMessage)));
432 return;
435 ServiceWorkerProviderHost* provider_host =
436 GetContext()->GetProviderHost(render_process_id_, provider_id);
437 if (!provider_host) {
438 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UNREGISTER_NO_HOST);
439 return;
441 if (!provider_host->IsContextAlive()) {
442 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
443 thread_id, request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
444 base::ASCIIToUTF16(kShutdownErrorMessage)));
445 return;
448 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
449 if (provider_host->document_url().is_empty()) {
450 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
451 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity,
452 base::ASCIIToUTF16(kNoDocumentURLErrorMessage)));
453 return;
456 ServiceWorkerRegistration* registration =
457 GetContext()->GetLiveRegistration(registration_id);
458 if (!registration) {
459 // |registration| must be alive because a renderer retains a registration
460 // reference at this point.
461 bad_message::ReceivedBadMessage(
462 this, bad_message::SWDH_UNREGISTER_BAD_REGISTRATION_ID);
463 return;
466 if (!CanUnregisterServiceWorker(provider_host->document_url(),
467 registration->pattern())) {
468 bad_message::ReceivedBadMessage(this, bad_message::SWDH_UNREGISTER_CANNOT);
469 return;
472 if (!GetContentClient()->browser()->AllowServiceWorker(
473 registration->pattern(), provider_host->topmost_frame_url(),
474 resource_context_, render_process_id_, provider_host->frame_id())) {
475 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
476 thread_id, request_id, WebServiceWorkerError::ErrorTypeUnknown,
477 base::ASCIIToUTF16(kUserDeniedPermissionMessage)));
478 return;
481 TRACE_EVENT_ASYNC_BEGIN1(
482 "ServiceWorker", "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
483 request_id, "Pattern", registration->pattern().spec());
484 GetContext()->UnregisterServiceWorker(
485 registration->pattern(),
486 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete, this,
487 thread_id, request_id));
490 void ServiceWorkerDispatcherHost::OnGetRegistration(
491 int thread_id,
492 int request_id,
493 int provider_id,
494 const GURL& document_url) {
495 TRACE_EVENT0("ServiceWorker",
496 "ServiceWorkerDispatcherHost::OnGetRegistration");
498 DCHECK_CURRENTLY_ON(BrowserThread::IO);
500 if (!GetContext()) {
501 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
502 thread_id, request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
503 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) +
504 base::ASCIIToUTF16(kShutdownErrorMessage)));
505 return;
507 if (!document_url.is_valid()) {
508 bad_message::ReceivedBadMessage(this,
509 bad_message::SWDH_GET_REGISTRATION_BAD_URL);
510 return;
513 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
514 render_process_id_, provider_id);
515 if (!provider_host) {
516 bad_message::ReceivedBadMessage(this,
517 bad_message::SWDH_GET_REGISTRATION_NO_HOST);
518 return;
520 if (!provider_host->IsContextAlive()) {
521 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
522 thread_id, request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
523 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) +
524 base::ASCIIToUTF16(kShutdownErrorMessage)));
525 return;
528 // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed.
529 if (provider_host->document_url().is_empty()) {
530 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
531 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity,
532 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) +
533 base::ASCIIToUTF16(kNoDocumentURLErrorMessage)));
534 return;
537 if (!CanGetRegistration(provider_host->document_url(), document_url)) {
538 bad_message::ReceivedBadMessage(this,
539 bad_message::SWDH_GET_REGISTRATION_CANNOT);
540 return;
543 if (!GetContentClient()->browser()->AllowServiceWorker(
544 provider_host->document_url(), provider_host->topmost_frame_url(),
545 resource_context_, render_process_id_, provider_host->frame_id())) {
546 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
547 thread_id, request_id, WebServiceWorkerError::ErrorTypeUnknown,
548 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) +
549 base::ASCIIToUTF16(kUserDeniedPermissionMessage)));
550 return;
553 if (GetContext()->storage()->IsDisabled()) {
554 SendGetRegistrationError(thread_id, request_id, SERVICE_WORKER_ERROR_ABORT);
555 return;
558 TRACE_EVENT_ASYNC_BEGIN1(
559 "ServiceWorker",
560 "ServiceWorkerDispatcherHost::GetRegistration",
561 request_id,
562 "Document URL", document_url.spec());
564 GetContext()->storage()->FindRegistrationForDocument(
565 document_url,
566 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete,
567 this,
568 thread_id,
569 provider_id,
570 request_id));
573 void ServiceWorkerDispatcherHost::OnGetRegistrations(int thread_id,
574 int request_id,
575 int provider_id) {
576 DCHECK_CURRENTLY_ON(BrowserThread::IO);
578 if (!GetContext()) {
579 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationsError(
580 thread_id, request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
581 base::ASCIIToUTF16(kServiceWorkerGetRegistrationsErrorPrefix) +
582 base::ASCIIToUTF16(kShutdownErrorMessage)));
583 return;
586 ServiceWorkerProviderHost* provider_host =
587 GetContext()->GetProviderHost(render_process_id_, provider_id);
588 if (!provider_host) {
589 bad_message::ReceivedBadMessage(
590 this, bad_message::SWDH_GET_REGISTRATIONS_NO_HOST);
591 return;
593 if (!provider_host->IsContextAlive()) {
594 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationsError(
595 thread_id, request_id, blink::WebServiceWorkerError::ErrorTypeAbort,
596 base::ASCIIToUTF16(kServiceWorkerGetRegistrationsErrorPrefix) +
597 base::ASCIIToUTF16(kShutdownErrorMessage)));
598 return;
601 // TODO(jungkees): This check can be removed once crbug.com/439697 is fixed.
602 if (provider_host->document_url().is_empty()) {
603 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationsError(
604 thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity,
605 base::ASCIIToUTF16(kServiceWorkerGetRegistrationsErrorPrefix) +
606 base::ASCIIToUTF16(kNoDocumentURLErrorMessage)));
607 return;
610 if (!OriginCanAccessServiceWorkers(provider_host->document_url())) {
611 bad_message::ReceivedBadMessage(
612 this, bad_message::SWDH_GET_REGISTRATIONS_INVALID_ORIGIN);
613 return;
616 if (!GetContentClient()->browser()->AllowServiceWorker(
617 provider_host->document_url(), provider_host->topmost_frame_url(),
618 resource_context_, render_process_id_, provider_host->frame_id())) {
619 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationsError(
620 thread_id, request_id, WebServiceWorkerError::ErrorTypeUnknown,
621 base::ASCIIToUTF16(kServiceWorkerGetRegistrationsErrorPrefix) +
622 base::ASCIIToUTF16(kUserDeniedPermissionMessage)));
623 return;
626 if (GetContext()->storage()->IsDisabled()) {
627 SendGetRegistrationsError(thread_id, request_id,
628 SERVICE_WORKER_ERROR_ABORT);
629 return;
632 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker",
633 "ServiceWorkerDispatcherHost::GetRegistrations",
634 request_id);
636 GetContext()->storage()->GetRegistrationsForOrigin(
637 provider_host->document_url().GetOrigin(),
638 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationsComplete, this,
639 thread_id, provider_id, request_id));
642 void ServiceWorkerDispatcherHost::OnGetRegistrationForReady(
643 int thread_id,
644 int request_id,
645 int provider_id) {
646 TRACE_EVENT0("ServiceWorker",
647 "ServiceWorkerDispatcherHost::OnGetRegistrationForReady");
648 if (!GetContext())
649 return;
650 ServiceWorkerProviderHost* provider_host =
651 GetContext()->GetProviderHost(render_process_id_, provider_id);
652 if (!provider_host) {
653 bad_message::ReceivedBadMessage(
654 this, bad_message::SWDH_GET_REGISTRATION_FOR_READY_NO_HOST);
655 return;
657 if (!provider_host->IsContextAlive())
658 return;
660 TRACE_EVENT_ASYNC_BEGIN0(
661 "ServiceWorker",
662 "ServiceWorkerDispatcherHost::GetRegistrationForReady",
663 request_id);
665 if (!provider_host->GetRegistrationForReady(base::Bind(
666 &ServiceWorkerDispatcherHost::GetRegistrationForReadyComplete,
667 this, thread_id, request_id, provider_host->AsWeakPtr()))) {
668 bad_message::ReceivedBadMessage(
669 this, bad_message::SWDH_GET_REGISTRATION_FOR_READY_ALREADY_IN_PROGRESS);
673 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
674 int handle_id,
675 const base::string16& message,
676 const std::vector<TransferredMessagePort>& sent_message_ports) {
677 TRACE_EVENT0("ServiceWorker",
678 "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
679 if (!GetContext())
680 return;
682 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
683 if (!handle) {
684 bad_message::ReceivedBadMessage(this, bad_message::SWDH_POST_MESSAGE);
685 return;
688 handle->version()->DispatchMessageEvent(
689 message, sent_message_ports,
690 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
693 void ServiceWorkerDispatcherHost::OnProviderCreated(
694 int provider_id,
695 int route_id,
696 ServiceWorkerProviderType provider_type) {
697 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
698 tracked_objects::ScopedTracker tracking_profile(
699 FROM_HERE_WITH_EXPLICIT_FUNCTION(
700 "477117 ServiceWorkerDispatcherHost::OnProviderCreated"));
701 TRACE_EVENT0("ServiceWorker",
702 "ServiceWorkerDispatcherHost::OnProviderCreated");
703 if (!GetContext())
704 return;
705 if (GetContext()->GetProviderHost(render_process_id_, provider_id)) {
706 bad_message::ReceivedBadMessage(this,
707 bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
708 return;
710 scoped_ptr<ServiceWorkerProviderHost> provider_host(
711 new ServiceWorkerProviderHost(render_process_id_, route_id, provider_id,
712 provider_type, GetContext()->AsWeakPtr(),
713 this));
714 GetContext()->AddProviderHost(provider_host.Pass());
717 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
718 TRACE_EVENT0("ServiceWorker",
719 "ServiceWorkerDispatcherHost::OnProviderDestroyed");
720 if (!GetContext())
721 return;
722 if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) {
723 bad_message::ReceivedBadMessage(
724 this, bad_message::SWDH_PROVIDER_DESTROYED_NO_HOST);
725 return;
727 GetContext()->RemoveProviderHost(render_process_id_, provider_id);
730 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
731 int provider_id, int64 version_id) {
732 TRACE_EVENT0("ServiceWorker",
733 "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
734 if (!GetContext())
735 return;
736 ServiceWorkerProviderHost* provider_host =
737 GetContext()->GetProviderHost(render_process_id_, provider_id);
738 if (!provider_host) {
739 bad_message::ReceivedBadMessage(
740 this, bad_message::SWDH_SET_HOSTED_VERSION_NO_HOST);
741 return;
743 if (!provider_host->IsContextAlive())
744 return;
745 if (!provider_host->SetHostedVersionId(version_id))
746 bad_message::ReceivedBadMessage(this, bad_message::SWDH_SET_HOSTED_VERSION);
748 ServiceWorkerVersion* version = GetContext()->GetLiveVersion(version_id);
749 if (!version)
750 return;
752 // Retrieve the registration associated with |version|. The registration
753 // must be alive because the version keeps it during starting worker.
754 ServiceWorkerRegistration* registration =
755 GetContext()->GetLiveRegistration(version->registration_id());
756 DCHECK(registration);
757 // TODO(ksakamoto): This is a quick fix for crbug.com/459916.
758 if (!registration)
759 return;
761 // Set the document URL to the script url in order to allow
762 // register/unregister/getRegistration on ServiceWorkerGlobalScope.
763 provider_host->SetDocumentUrl(version->script_url());
765 ServiceWorkerRegistrationObjectInfo info;
766 ServiceWorkerVersionAttributes attrs;
767 GetRegistrationObjectInfoAndVersionAttributes(
768 provider_host->AsWeakPtr(), registration, &info, &attrs);
770 Send(new ServiceWorkerMsg_AssociateRegistrationWithServiceWorker(
771 kDocumentMainThreadId, provider_id, info, attrs));
774 ServiceWorkerRegistrationHandle*
775 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
776 int64 registration_id) {
777 for (IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer>::iterator
778 iter(&registration_handles_);
779 !iter.IsAtEnd();
780 iter.Advance()) {
781 ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
782 DCHECK(handle);
783 DCHECK(handle->registration());
784 if (handle->provider_id() == provider_id &&
785 handle->registration()->id() == registration_id) {
786 return handle;
789 return NULL;
792 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
793 base::WeakPtr<ServiceWorkerProviderHost> provider_host,
794 ServiceWorkerRegistration* registration,
795 ServiceWorkerRegistrationObjectInfo* info,
796 ServiceWorkerVersionAttributes* attrs) {
797 ServiceWorkerRegistrationHandle* handle =
798 GetOrCreateRegistrationHandle(provider_host, registration);
799 *info = handle->GetObjectInfo();
801 attrs->installing = provider_host->GetOrCreateServiceWorkerHandle(
802 registration->installing_version());
803 attrs->waiting = provider_host->GetOrCreateServiceWorkerHandle(
804 registration->waiting_version());
805 attrs->active = provider_host->GetOrCreateServiceWorkerHandle(
806 registration->active_version());
809 void ServiceWorkerDispatcherHost::RegistrationComplete(
810 int thread_id,
811 int provider_id,
812 int request_id,
813 ServiceWorkerStatusCode status,
814 const std::string& status_message,
815 int64 registration_id) {
816 if (!GetContext())
817 return;
819 ServiceWorkerProviderHost* provider_host =
820 GetContext()->GetProviderHost(render_process_id_, provider_id);
821 if (!provider_host)
822 return; // The provider has already been destroyed.
824 if (status != SERVICE_WORKER_OK) {
825 SendRegistrationError(thread_id, request_id, status, status_message);
826 return;
829 ServiceWorkerRegistration* registration =
830 GetContext()->GetLiveRegistration(registration_id);
831 DCHECK(registration);
833 ServiceWorkerRegistrationObjectInfo info;
834 ServiceWorkerVersionAttributes attrs;
835 GetRegistrationObjectInfoAndVersionAttributes(
836 provider_host->AsWeakPtr(), registration, &info, &attrs);
838 Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
839 thread_id, request_id, info, attrs));
840 TRACE_EVENT_ASYNC_END1("ServiceWorker",
841 "ServiceWorkerDispatcherHost::RegisterServiceWorker",
842 request_id,
843 "Registration ID",
844 registration_id);
847 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
848 int embedded_worker_id) {
849 TRACE_EVENT0("ServiceWorker",
850 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
851 if (!GetContext())
852 return;
853 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
854 if (!registry->CanHandle(embedded_worker_id))
855 return;
856 registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id);
859 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
860 int embedded_worker_id,
861 int thread_id,
862 int provider_id) {
863 TRACE_EVENT0("ServiceWorker",
864 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
865 if (!GetContext())
866 return;
868 ServiceWorkerProviderHost* provider_host =
869 GetContext()->GetProviderHost(render_process_id_, provider_id);
870 if (!provider_host) {
871 bad_message::ReceivedBadMessage(
872 this, bad_message::SWDH_WORKER_SCRIPT_LOAD_NO_HOST);
873 return;
876 provider_host->SetReadyToSendMessagesToWorker(thread_id);
878 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
879 if (!registry->CanHandle(embedded_worker_id))
880 return;
881 registry->OnWorkerScriptLoaded(
882 render_process_id_, thread_id, embedded_worker_id);
885 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
886 int embedded_worker_id) {
887 TRACE_EVENT0("ServiceWorker",
888 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
889 if (!GetContext())
890 return;
891 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
892 if (!registry->CanHandle(embedded_worker_id))
893 return;
894 registry->OnWorkerScriptLoadFailed(render_process_id_, embedded_worker_id);
897 void ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated(
898 int embedded_worker_id,
899 bool success) {
900 TRACE_EVENT0("ServiceWorker",
901 "ServiceWorkerDispatcherHost::OnWorkerScriptEvaluated");
902 if (!GetContext())
903 return;
904 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
905 if (!registry->CanHandle(embedded_worker_id))
906 return;
907 registry->OnWorkerScriptEvaluated(
908 render_process_id_, embedded_worker_id, success);
911 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id) {
912 TRACE_EVENT0("ServiceWorker",
913 "ServiceWorkerDispatcherHost::OnWorkerStarted");
914 if (!GetContext())
915 return;
916 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
917 if (!registry->CanHandle(embedded_worker_id))
918 return;
919 registry->OnWorkerStarted(render_process_id_, embedded_worker_id);
922 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id) {
923 TRACE_EVENT0("ServiceWorker",
924 "ServiceWorkerDispatcherHost::OnWorkerStopped");
925 if (!GetContext())
926 return;
927 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
928 if (!registry->CanHandle(embedded_worker_id))
929 return;
930 registry->OnWorkerStopped(render_process_id_, embedded_worker_id);
933 void ServiceWorkerDispatcherHost::OnReportException(
934 int embedded_worker_id,
935 const base::string16& error_message,
936 int line_number,
937 int column_number,
938 const GURL& source_url) {
939 TRACE_EVENT0("ServiceWorker",
940 "ServiceWorkerDispatcherHost::OnReportException");
941 if (!GetContext())
942 return;
943 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
944 if (!registry->CanHandle(embedded_worker_id))
945 return;
946 registry->OnReportException(embedded_worker_id,
947 error_message,
948 line_number,
949 column_number,
950 source_url);
953 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
954 int embedded_worker_id,
955 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params& params) {
956 TRACE_EVENT0("ServiceWorker",
957 "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
958 if (!GetContext())
959 return;
960 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
961 if (!registry->CanHandle(embedded_worker_id))
962 return;
963 registry->OnReportConsoleMessage(embedded_worker_id,
964 params.source_identifier,
965 params.message_level,
966 params.message,
967 params.line_number,
968 params.source_url);
971 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
972 int handle_id) {
973 TRACE_EVENT0("ServiceWorker",
974 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
975 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
976 if (!handle) {
977 bad_message::ReceivedBadMessage(
978 this, bad_message::SWDH_INCREMENT_WORKER_BAD_HANDLE);
979 return;
981 handle->IncrementRefCount();
984 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
985 int handle_id) {
986 TRACE_EVENT0("ServiceWorker",
987 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
988 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
989 if (!handle) {
990 bad_message::ReceivedBadMessage(
991 this, bad_message::SWDH_DECREMENT_WORKER_BAD_HANDLE);
992 return;
994 handle->DecrementRefCount();
995 if (handle->HasNoRefCount())
996 handles_.Remove(handle_id);
999 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
1000 int registration_handle_id) {
1001 TRACE_EVENT0("ServiceWorker",
1002 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
1003 ServiceWorkerRegistrationHandle* handle =
1004 registration_handles_.Lookup(registration_handle_id);
1005 if (!handle) {
1006 bad_message::ReceivedBadMessage(
1007 this, bad_message::SWDH_INCREMENT_REGISTRATION_BAD_HANDLE);
1008 return;
1010 handle->IncrementRefCount();
1013 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
1014 int registration_handle_id) {
1015 TRACE_EVENT0("ServiceWorker",
1016 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
1017 ServiceWorkerRegistrationHandle* handle =
1018 registration_handles_.Lookup(registration_handle_id);
1019 if (!handle) {
1020 bad_message::ReceivedBadMessage(
1021 this, bad_message::SWDH_DECREMENT_REGISTRATION_BAD_HANDLE);
1022 return;
1024 handle->DecrementRefCount();
1025 if (handle->HasNoRefCount())
1026 registration_handles_.Remove(registration_handle_id);
1029 void ServiceWorkerDispatcherHost::UnregistrationComplete(
1030 int thread_id,
1031 int request_id,
1032 ServiceWorkerStatusCode status) {
1033 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
1034 SendUnregistrationError(thread_id, request_id, status);
1035 return;
1037 const bool is_success = (status == SERVICE_WORKER_OK);
1038 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id,
1039 request_id,
1040 is_success));
1041 TRACE_EVENT_ASYNC_END1(
1042 "ServiceWorker",
1043 "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
1044 request_id,
1045 "Status", status);
1048 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
1049 int thread_id,
1050 int provider_id,
1051 int request_id,
1052 ServiceWorkerStatusCode status,
1053 const scoped_refptr<ServiceWorkerRegistration>& registration) {
1054 TRACE_EVENT_ASYNC_END1("ServiceWorker",
1055 "ServiceWorkerDispatcherHost::GetRegistration",
1056 request_id,
1057 "Registration ID",
1058 registration.get() ? registration->id()
1059 : kInvalidServiceWorkerRegistrationId);
1061 if (!GetContext())
1062 return;
1064 ServiceWorkerProviderHost* provider_host =
1065 GetContext()->GetProviderHost(render_process_id_, provider_id);
1066 if (!provider_host)
1067 return; // The provider has already been destroyed.
1069 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
1070 SendGetRegistrationError(thread_id, request_id, status);
1071 return;
1074 ServiceWorkerRegistrationObjectInfo info;
1075 ServiceWorkerVersionAttributes attrs;
1076 if (status == SERVICE_WORKER_OK) {
1077 DCHECK(registration.get());
1078 if (!registration->is_uninstalling()) {
1079 GetRegistrationObjectInfoAndVersionAttributes(
1080 provider_host->AsWeakPtr(), registration.get(), &info, &attrs);
1084 Send(new ServiceWorkerMsg_DidGetRegistration(
1085 thread_id, request_id, info, attrs));
1088 void ServiceWorkerDispatcherHost::GetRegistrationsComplete(
1089 int thread_id,
1090 int provider_id,
1091 int request_id,
1092 const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
1093 registrations) {
1094 TRACE_EVENT_ASYNC_END0("ServiceWorker",
1095 "ServiceWorkerDispatcherHost::GetRegistrations",
1096 request_id);
1097 if (!GetContext())
1098 return;
1100 ServiceWorkerProviderHost* provider_host =
1101 GetContext()->GetProviderHost(render_process_id_, provider_id);
1102 if (!provider_host)
1103 return; // The provider has already been destroyed.
1105 std::vector<ServiceWorkerRegistrationObjectInfo> object_infos;
1106 std::vector<ServiceWorkerVersionAttributes> version_attrs;
1108 for (const auto& registration : registrations) {
1109 DCHECK(registration.get());
1110 if (!registration->is_uninstalling()) {
1111 ServiceWorkerRegistrationObjectInfo object_info;
1112 ServiceWorkerVersionAttributes version_attr;
1113 GetRegistrationObjectInfoAndVersionAttributes(
1114 provider_host->AsWeakPtr(), registration.get(), &object_info,
1115 &version_attr);
1116 object_infos.push_back(object_info);
1117 version_attrs.push_back(version_attr);
1121 Send(new ServiceWorkerMsg_DidGetRegistrations(thread_id, request_id,
1122 object_infos, version_attrs));
1125 void ServiceWorkerDispatcherHost::GetRegistrationForReadyComplete(
1126 int thread_id,
1127 int request_id,
1128 base::WeakPtr<ServiceWorkerProviderHost> provider_host,
1129 ServiceWorkerRegistration* registration) {
1130 DCHECK(registration);
1131 TRACE_EVENT_ASYNC_END1("ServiceWorker",
1132 "ServiceWorkerDispatcherHost::GetRegistrationForReady",
1133 request_id,
1134 "Registration ID",
1135 registration ? registration->id()
1136 : kInvalidServiceWorkerRegistrationId);
1138 if (!GetContext())
1139 return;
1141 ServiceWorkerRegistrationObjectInfo info;
1142 ServiceWorkerVersionAttributes attrs;
1143 GetRegistrationObjectInfoAndVersionAttributes(
1144 provider_host, registration, &info, &attrs);
1145 Send(new ServiceWorkerMsg_DidGetRegistrationForReady(
1146 thread_id, request_id, info, attrs));
1149 void ServiceWorkerDispatcherHost::SendRegistrationError(
1150 int thread_id,
1151 int request_id,
1152 ServiceWorkerStatusCode status,
1153 const std::string& status_message) {
1154 base::string16 error_message;
1155 blink::WebServiceWorkerError::ErrorType error_type;
1156 GetServiceWorkerRegistrationStatusResponse(status, status_message,
1157 &error_type, &error_message);
1158 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
1159 thread_id, request_id, error_type,
1160 base::ASCIIToUTF16(kServiceWorkerRegisterErrorPrefix) + error_message));
1163 void ServiceWorkerDispatcherHost::SendUnregistrationError(
1164 int thread_id,
1165 int request_id,
1166 ServiceWorkerStatusCode status) {
1167 base::string16 error_message;
1168 blink::WebServiceWorkerError::ErrorType error_type;
1169 GetServiceWorkerRegistrationStatusResponse(status, std::string(), &error_type,
1170 &error_message);
1171 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
1172 thread_id, request_id, error_type,
1173 base::ASCIIToUTF16(kServiceWorkerUnregisterErrorPrefix) + error_message));
1176 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
1177 int thread_id,
1178 int request_id,
1179 ServiceWorkerStatusCode status) {
1180 base::string16 error_message;
1181 blink::WebServiceWorkerError::ErrorType error_type;
1182 GetServiceWorkerRegistrationStatusResponse(status, std::string(), &error_type,
1183 &error_message);
1184 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
1185 thread_id, request_id, error_type,
1186 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) +
1187 error_message));
1190 void ServiceWorkerDispatcherHost::SendGetRegistrationsError(
1191 int thread_id,
1192 int request_id,
1193 ServiceWorkerStatusCode status) {
1194 base::string16 error_message;
1195 blink::WebServiceWorkerError::ErrorType error_type;
1196 GetServiceWorkerRegistrationStatusResponse(status, std::string(), &error_type,
1197 &error_message);
1198 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationsError(
1199 thread_id, request_id, error_type,
1200 base::ASCIIToUTF16(kServiceWorkerGetRegistrationErrorPrefix) +
1201 error_message));
1204 ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
1205 if (!context_wrapper_.get())
1206 return nullptr;
1207 return context_wrapper_->context();
1210 void ServiceWorkerDispatcherHost::OnTerminateWorker(int handle_id) {
1211 ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
1212 if (!handle) {
1213 bad_message::ReceivedBadMessage(this,
1214 bad_message::SWDH_TERMINATE_BAD_HANDLE);
1215 return;
1217 handle->version()->StopWorker(
1218 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
1221 } // namespace content