Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_dispatcher_host.cc
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.
4
5 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
6
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 "ipc/ipc_message_macros.h"
22 #include "third_party/WebKit/public/platform/WebServiceWorkerError.h"
23 #include "url/gurl.h"
24
25 using blink::WebServiceWorkerError;
26
27 namespace content {
28
29 namespace {
30
31 const char kShutdownErrorMessage[] =
32     "The Service Worker system has shutdown.";
33
34 const uint32 kFilteredMessageClasses[] = {
35   ServiceWorkerMsgStart,
36   EmbeddedWorkerMsgStart,
37 };
38
39 // TODO(dominicc): When crbug.com/362214 is fixed, make
40 // Can(R|Unr)egisterServiceWorker also check that these are secure
41 // origins to defend against compromised renderers.
42 bool CanRegisterServiceWorker(const GURL& document_url,
43                               const GURL& pattern,
44                               const GURL& script_url) {
45   // TODO: Respect Chrome's content settings, if we add a setting for
46   // controlling whether Service Worker is allowed.
47   return document_url.GetOrigin() == pattern.GetOrigin() &&
48          document_url.GetOrigin() == script_url.GetOrigin();
49 }
50
51 bool CanUnregisterServiceWorker(const GURL& document_url,
52                                 const GURL& pattern) {
53   // TODO: Respect Chrome's content settings, if we add a setting for
54   // controlling whether Service Worker is allowed.
55   return document_url.GetOrigin() == pattern.GetOrigin();
56 }
57
58 bool CanGetRegistration(const GURL& document_url,
59                         const GURL& given_document_url) {
60   // TODO: Respect Chrome's content settings, if we add a setting for
61   // controlling whether Service Worker is allowed.
62   return document_url.GetOrigin() == given_document_url.GetOrigin();
63 }
64
65 }  // namespace
66
67 ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
68     int render_process_id,
69     MessagePortMessageFilter* message_port_message_filter)
70     : BrowserMessageFilter(kFilteredMessageClasses,
71                            arraysize(kFilteredMessageClasses)),
72       render_process_id_(render_process_id),
73       message_port_message_filter_(message_port_message_filter),
74       channel_ready_(false) {
75 }
76
77 ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
78   if (GetContext()) {
79     GetContext()->RemoveAllProviderHostsForProcess(render_process_id_);
80     GetContext()->embedded_worker_registry()->RemoveChildProcessSender(
81         render_process_id_);
82   }
83 }
84
85 void ServiceWorkerDispatcherHost::Init(
86     ServiceWorkerContextWrapper* context_wrapper) {
87   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
88     BrowserThread::PostTask(
89         BrowserThread::IO, FROM_HERE,
90         base::Bind(&ServiceWorkerDispatcherHost::Init,
91                    this, make_scoped_refptr(context_wrapper)));
92     return;
93   }
94   context_wrapper_ = context_wrapper;
95   GetContext()->embedded_worker_registry()->AddChildProcessSender(
96       render_process_id_, this);
97 }
98
99 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender* sender) {
100   TRACE_EVENT0("ServiceWorker",
101                "ServiceWorkerDispatcherHost::OnFilterAdded");
102   BrowserMessageFilter::OnFilterAdded(sender);
103   channel_ready_ = true;
104   std::vector<IPC::Message*> messages;
105   pending_messages_.release(&messages);
106   for (size_t i = 0; i < messages.size(); ++i) {
107     BrowserMessageFilter::Send(messages[i]);
108   }
109 }
110
111 void ServiceWorkerDispatcherHost::OnDestruct() const {
112   BrowserThread::DeleteOnIOThread::Destruct(this);
113 }
114
115 bool ServiceWorkerDispatcherHost::OnMessageReceived(
116     const IPC::Message& message) {
117   bool handled = true;
118   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost, message)
119     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker,
120                         OnRegisterServiceWorker)
121     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker,
122                         OnUnregisterServiceWorker)
123     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration,
124                         OnGetRegistration)
125     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated,
126                         OnProviderCreated)
127     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
128                         OnProviderDestroyed)
129     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId,
130                         OnSetHostedVersionId)
131     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
132                         OnPostMessageToWorker)
133     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection,
134                         OnWorkerReadyForInspection)
135     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
136                         OnWorkerScriptLoaded)
137     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
138                         OnWorkerScriptLoadFailed)
139     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
140                         OnWorkerStarted)
141     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
142                         OnWorkerStopped)
143     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload,
144                         OnPausedAfterDownload)
145     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException,
146                         OnReportException)
147     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage,
148                         OnReportConsoleMessage)
149     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
150                         OnIncrementServiceWorkerRefCount)
151     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
152                         OnDecrementServiceWorkerRefCount)
153     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount,
154                         OnIncrementRegistrationRefCount)
155     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount,
156                         OnDecrementRegistrationRefCount)
157     IPC_MESSAGE_UNHANDLED(handled = false)
158   IPC_END_MESSAGE_MAP()
159
160   if (!handled && GetContext()) {
161     handled =
162         GetContext()->embedded_worker_registry()->OnMessageReceived(message);
163     if (!handled)
164       BadMessageReceived();
165   }
166
167   return handled;
168 }
169
170 bool ServiceWorkerDispatcherHost::Send(IPC::Message* message) {
171   if (channel_ready_) {
172     BrowserMessageFilter::Send(message);
173     // Don't bother passing through Send()'s result: it's not reliable.
174     return true;
175   }
176
177   pending_messages_.push_back(message);
178   return true;
179 }
180
181 ServiceWorkerRegistrationHandle*
182 ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle(
183     int provider_id,
184     ServiceWorkerRegistration* registration) {
185   ServiceWorkerRegistrationHandle* handle =
186       FindRegistrationHandle(provider_id, registration->id());
187   if (handle) {
188     handle->IncrementRefCount();
189     return handle;
190   }
191
192   scoped_ptr<ServiceWorkerRegistrationHandle> new_handle(
193       new ServiceWorkerRegistrationHandle(
194           GetContext()->AsWeakPtr(), this, provider_id, registration));
195   handle = new_handle.get();
196   RegisterServiceWorkerRegistrationHandle(new_handle.Pass());
197   return handle;
198 }
199
200 void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
201     scoped_ptr<ServiceWorkerHandle> handle) {
202   int handle_id = handle->handle_id();
203   handles_.AddWithID(handle.release(), handle_id);
204 }
205
206 void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
207     scoped_ptr<ServiceWorkerRegistrationHandle> handle) {
208   int handle_id = handle->handle_id();
209   registration_handles_.AddWithID(handle.release(), handle_id);
210 }
211
212 void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
213     int thread_id,
214     int request_id,
215     int provider_id,
216     const GURL& pattern,
217     const GURL& script_url) {
218   TRACE_EVENT0("ServiceWorker",
219                "ServiceWorkerDispatcherHost::OnRegisterServiceWorker");
220   if (!GetContext()) {
221     Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
222         thread_id,
223         request_id,
224         WebServiceWorkerError::ErrorTypeAbort,
225         base::ASCIIToUTF16(kShutdownErrorMessage)));
226     return;
227   }
228
229   ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
230       render_process_id_, provider_id);
231   if (!provider_host) {
232     BadMessageReceived();
233     return;
234   }
235   if (!provider_host->IsContextAlive()) {
236     Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
237         thread_id,
238         request_id,
239         WebServiceWorkerError::ErrorTypeAbort,
240         base::ASCIIToUTF16(kShutdownErrorMessage)));
241     return;
242   }
243
244   if (!CanRegisterServiceWorker(
245       provider_host->document_url(), pattern, script_url)) {
246     BadMessageReceived();
247     return;
248   }
249   TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
250                            "ServiceWorkerDispatcherHost::RegisterServiceWorker",
251                            request_id,
252                            "Pattern", pattern.spec(),
253                            "Script URL", script_url.spec());
254   GetContext()->RegisterServiceWorker(
255       pattern,
256       script_url,
257       provider_host,
258       base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete,
259                  this,
260                  thread_id,
261                  provider_id,
262                  request_id));
263 }
264
265 void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
266     int thread_id,
267     int request_id,
268     int provider_id,
269     const GURL& pattern) {
270   TRACE_EVENT0("ServiceWorker",
271                "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker");
272   if (!GetContext()) {
273     Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
274         thread_id,
275         request_id,
276         blink::WebServiceWorkerError::ErrorTypeAbort,
277         base::ASCIIToUTF16(kShutdownErrorMessage)));
278     return;
279   }
280
281   ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
282       render_process_id_, provider_id);
283   if (!provider_host) {
284     BadMessageReceived();
285     return;
286   }
287   if (!provider_host->IsContextAlive()) {
288     Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
289         thread_id,
290         request_id,
291         blink::WebServiceWorkerError::ErrorTypeAbort,
292         base::ASCIIToUTF16(kShutdownErrorMessage)));
293     return;
294   }
295
296   if (!CanUnregisterServiceWorker(provider_host->document_url(), pattern)) {
297     BadMessageReceived();
298     return;
299   }
300
301   TRACE_EVENT_ASYNC_BEGIN1(
302       "ServiceWorker",
303       "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
304       request_id,
305       "Pattern", pattern.spec());
306   GetContext()->UnregisterServiceWorker(
307       pattern,
308       base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete,
309                  this,
310                  thread_id,
311                  request_id));
312 }
313
314 void ServiceWorkerDispatcherHost::OnGetRegistration(
315     int thread_id,
316     int request_id,
317     int provider_id,
318     const GURL& document_url) {
319   TRACE_EVENT0("ServiceWorker",
320                "ServiceWorkerDispatcherHost::OnGetRegistration");
321   if (!GetContext()) {
322     Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
323         thread_id,
324         request_id,
325         blink::WebServiceWorkerError::ErrorTypeAbort,
326         base::ASCIIToUTF16(kShutdownErrorMessage)));
327     return;
328   }
329
330   ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(
331       render_process_id_, provider_id);
332   if (!provider_host) {
333     BadMessageReceived();
334     return;
335   }
336   if (!provider_host->IsContextAlive()) {
337     Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
338         thread_id,
339         request_id,
340         blink::WebServiceWorkerError::ErrorTypeAbort,
341         base::ASCIIToUTF16(kShutdownErrorMessage)));
342     return;
343   }
344
345   if (!CanGetRegistration(provider_host->document_url(), document_url)) {
346     BadMessageReceived();
347     return;
348   }
349
350   DCHECK_CURRENTLY_ON(BrowserThread::IO);
351   if (GetContext()->storage()->IsDisabled()) {
352     SendGetRegistrationError(thread_id, request_id, SERVICE_WORKER_ERROR_ABORT);
353     return;
354   }
355
356   TRACE_EVENT_ASYNC_BEGIN1(
357       "ServiceWorker",
358       "ServiceWorkerDispatcherHost::GetRegistration",
359       request_id,
360       "Document URL", document_url.spec());
361
362   GetContext()->storage()->FindRegistrationForDocument(
363       document_url,
364       base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete,
365                  this,
366                  thread_id,
367                  provider_id,
368                  request_id));
369 }
370
371 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
372     int handle_id,
373     const base::string16& message,
374     const std::vector<int>& sent_message_port_ids) {
375   TRACE_EVENT0("ServiceWorker",
376                "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
377   if (!GetContext())
378     return;
379
380   ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
381   if (!handle) {
382     BadMessageReceived();
383     return;
384   }
385
386   std::vector<int> new_routing_ids;
387   message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
388       sent_message_port_ids, &new_routing_ids);
389   handle->version()->SendMessage(
390       ServiceWorkerMsg_MessageToWorker(message,
391                                        sent_message_port_ids,
392                                        new_routing_ids),
393       base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
394 }
395
396 void ServiceWorkerDispatcherHost::OnProviderCreated(int provider_id) {
397   TRACE_EVENT0("ServiceWorker",
398                "ServiceWorkerDispatcherHost::OnProviderCreated");
399   if (!GetContext())
400     return;
401   if (GetContext()->GetProviderHost(render_process_id_, provider_id)) {
402     BadMessageReceived();
403     return;
404   }
405   scoped_ptr<ServiceWorkerProviderHost> provider_host(
406       new ServiceWorkerProviderHost(
407           render_process_id_, provider_id, GetContext()->AsWeakPtr(), this));
408   GetContext()->AddProviderHost(provider_host.Pass());
409 }
410
411 void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
412   TRACE_EVENT0("ServiceWorker",
413                "ServiceWorkerDispatcherHost::OnProviderDestroyed");
414   if (!GetContext())
415     return;
416   if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) {
417     BadMessageReceived();
418     return;
419   }
420   GetContext()->RemoveProviderHost(render_process_id_, provider_id);
421 }
422
423 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
424     int provider_id, int64 version_id) {
425   TRACE_EVENT0("ServiceWorker",
426                "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
427   if (!GetContext())
428     return;
429   ServiceWorkerProviderHost* provider_host =
430       GetContext()->GetProviderHost(render_process_id_, provider_id);
431   if (!provider_host) {
432     BadMessageReceived();
433     return;
434   }
435   if (!provider_host->IsContextAlive())
436     return;
437   if (!provider_host->SetHostedVersionId(version_id))
438     BadMessageReceived();
439 }
440
441 ServiceWorkerRegistrationHandle*
442 ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
443                                                     int64 registration_id) {
444   for (IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer>::iterator
445            iter(&registration_handles_);
446        !iter.IsAtEnd();
447        iter.Advance()) {
448     ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
449     DCHECK(handle);
450     if (handle->provider_id() == provider_id && handle->registration() &&
451         handle->registration()->id() == registration_id) {
452       return handle;
453     }
454   }
455   return NULL;
456 }
457
458 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
459     int provider_id,
460     ServiceWorkerRegistration* registration,
461     ServiceWorkerRegistrationObjectInfo* info,
462     ServiceWorkerVersionAttributes* attrs) {
463   ServiceWorkerRegistrationHandle* handle =
464     GetOrCreateRegistrationHandle(provider_id, registration);
465   *info = handle->GetObjectInfo();
466
467   attrs->installing = handle->CreateServiceWorkerHandleAndPass(
468       registration->installing_version());
469   attrs->waiting = handle->CreateServiceWorkerHandleAndPass(
470       registration->waiting_version());
471   attrs->active = handle->CreateServiceWorkerHandleAndPass(
472       registration->active_version());
473 }
474
475 void ServiceWorkerDispatcherHost::RegistrationComplete(
476     int thread_id,
477     int provider_id,
478     int request_id,
479     ServiceWorkerStatusCode status,
480     int64 registration_id,
481     int64 version_id) {
482   if (!GetContext())
483     return;
484
485   if (status != SERVICE_WORKER_OK) {
486     SendRegistrationError(thread_id, request_id, status);
487     return;
488   }
489
490   ServiceWorkerRegistration* registration =
491       GetContext()->GetLiveRegistration(registration_id);
492   DCHECK(registration);
493
494   ServiceWorkerRegistrationObjectInfo info;
495   ServiceWorkerVersionAttributes attrs;
496   GetRegistrationObjectInfoAndVersionAttributes(
497       provider_id, registration, &info, &attrs);
498
499   Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
500       thread_id, request_id, info, attrs));
501   TRACE_EVENT_ASYNC_END2("ServiceWorker",
502                          "ServiceWorkerDispatcherHost::RegisterServiceWorker",
503                          request_id,
504                          "Registration ID", registration_id,
505                          "Version ID", version_id);
506 }
507
508 void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection(
509     int embedded_worker_id) {
510   TRACE_EVENT0("ServiceWorker",
511                "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection");
512   if (!GetContext())
513     return;
514   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
515   if (!registry->CanHandle(embedded_worker_id))
516     return;
517   registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id);
518 }
519
520 void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(
521     int embedded_worker_id,
522     int thread_id) {
523   TRACE_EVENT0("ServiceWorker",
524                "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded");
525   if (!GetContext())
526     return;
527   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
528   if (!registry->CanHandle(embedded_worker_id))
529     return;
530   registry->OnWorkerScriptLoaded(
531       render_process_id_, thread_id, embedded_worker_id);
532 }
533
534 void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
535     int embedded_worker_id) {
536   TRACE_EVENT0("ServiceWorker",
537                "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed");
538   if (!GetContext())
539     return;
540   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
541   if (!registry->CanHandle(embedded_worker_id))
542     return;
543   registry->OnWorkerScriptLoadFailed(render_process_id_, embedded_worker_id);
544 }
545
546 void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id) {
547   TRACE_EVENT0("ServiceWorker",
548                "ServiceWorkerDispatcherHost::OnWorkerStarted");
549   if (!GetContext())
550     return;
551   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
552   if (!registry->CanHandle(embedded_worker_id))
553     return;
554   registry->OnWorkerStarted(render_process_id_, embedded_worker_id);
555 }
556
557 void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id) {
558   TRACE_EVENT0("ServiceWorker",
559                "ServiceWorkerDispatcherHost::OnWorkerStopped");
560   if (!GetContext())
561     return;
562   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
563   if (!registry->CanHandle(embedded_worker_id))
564     return;
565   registry->OnWorkerStopped(render_process_id_, embedded_worker_id);
566 }
567
568 void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
569     int embedded_worker_id) {
570   TRACE_EVENT0("ServiceWorker",
571                "ServiceWorkerDispatcherHost::OnPausedAfterDownload");
572   if (!GetContext())
573     return;
574   GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
575       render_process_id_, embedded_worker_id);
576 }
577
578 void ServiceWorkerDispatcherHost::OnReportException(
579     int embedded_worker_id,
580     const base::string16& error_message,
581     int line_number,
582     int column_number,
583     const GURL& source_url) {
584   TRACE_EVENT0("ServiceWorker",
585                "ServiceWorkerDispatcherHost::OnReportException");
586   if (!GetContext())
587     return;
588   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
589   if (!registry->CanHandle(embedded_worker_id))
590     return;
591   registry->OnReportException(embedded_worker_id,
592                               error_message,
593                               line_number,
594                               column_number,
595                               source_url);
596 }
597
598 void ServiceWorkerDispatcherHost::OnReportConsoleMessage(
599     int embedded_worker_id,
600     const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params& params) {
601   TRACE_EVENT0("ServiceWorker",
602                "ServiceWorkerDispatcherHost::OnReportConsoleMessage");
603   if (!GetContext())
604     return;
605   EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry();
606   if (!registry->CanHandle(embedded_worker_id))
607     return;
608   registry->OnReportConsoleMessage(embedded_worker_id,
609                                    params.source_identifier,
610                                    params.message_level,
611                                    params.message,
612                                    params.line_number,
613                                    params.source_url);
614 }
615
616 void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
617     int handle_id) {
618   TRACE_EVENT0("ServiceWorker",
619                "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");
620   ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
621   if (!handle) {
622     BadMessageReceived();
623     return;
624   }
625   handle->IncrementRefCount();
626 }
627
628 void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
629     int handle_id) {
630   TRACE_EVENT0("ServiceWorker",
631                "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");
632   ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
633   if (!handle) {
634     BadMessageReceived();
635     return;
636   }
637   handle->DecrementRefCount();
638   if (handle->HasNoRefCount())
639     handles_.Remove(handle_id);
640 }
641
642 void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
643     int registration_handle_id) {
644   TRACE_EVENT0("ServiceWorker",
645                "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount");
646   ServiceWorkerRegistrationHandle* handle =
647       registration_handles_.Lookup(registration_handle_id);
648   if (!handle) {
649     BadMessageReceived();
650     return;
651   }
652   handle->IncrementRefCount();
653 }
654
655 void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
656     int registration_handle_id) {
657   TRACE_EVENT0("ServiceWorker",
658                "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount");
659   ServiceWorkerRegistrationHandle* handle =
660       registration_handles_.Lookup(registration_handle_id);
661   if (!handle) {
662     BadMessageReceived();
663     return;
664   }
665   handle->DecrementRefCount();
666   if (handle->HasNoRefCount())
667     registration_handles_.Remove(registration_handle_id);
668 }
669
670 void ServiceWorkerDispatcherHost::UnregistrationComplete(
671     int thread_id,
672     int request_id,
673     ServiceWorkerStatusCode status) {
674   if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
675     SendUnregistrationError(thread_id, request_id, status);
676     return;
677   }
678   const bool is_success = (status == SERVICE_WORKER_OK);
679   Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id,
680                                                       request_id,
681                                                       is_success));
682   TRACE_EVENT_ASYNC_END1(
683       "ServiceWorker",
684       "ServiceWorkerDispatcherHost::UnregisterServiceWorker",
685       request_id,
686       "Status", status);
687 }
688
689 void ServiceWorkerDispatcherHost::GetRegistrationComplete(
690     int thread_id,
691     int provider_id,
692     int request_id,
693     ServiceWorkerStatusCode status,
694     const scoped_refptr<ServiceWorkerRegistration>& registration) {
695   TRACE_EVENT_ASYNC_END1("ServiceWorker",
696                          "ServiceWorkerDispatcherHost::GetRegistration",
697                          request_id,
698                          "Registration ID",
699                          registration.get() ? registration->id()
700                              : kInvalidServiceWorkerRegistrationId);
701   if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
702     SendGetRegistrationError(thread_id, request_id, status);
703     return;
704   }
705
706   ServiceWorkerRegistrationObjectInfo info;
707   ServiceWorkerVersionAttributes attrs;
708   if (status == SERVICE_WORKER_OK) {
709     DCHECK(registration.get());
710     if (!registration->is_uninstalling()) {
711       GetRegistrationObjectInfoAndVersionAttributes(
712           provider_id, registration.get(), &info, &attrs);
713     }
714   }
715
716   Send(new ServiceWorkerMsg_DidGetRegistration(
717       thread_id, request_id, info, attrs));
718 }
719
720 void ServiceWorkerDispatcherHost::SendRegistrationError(
721     int thread_id,
722     int request_id,
723     ServiceWorkerStatusCode status) {
724   base::string16 error_message;
725   blink::WebServiceWorkerError::ErrorType error_type;
726   GetServiceWorkerRegistrationStatusResponse(
727       status, &error_type, &error_message);
728   Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
729       thread_id, request_id, error_type, error_message));
730 }
731
732 void ServiceWorkerDispatcherHost::SendUnregistrationError(
733     int thread_id,
734     int request_id,
735     ServiceWorkerStatusCode status) {
736   base::string16 error_message;
737   blink::WebServiceWorkerError::ErrorType error_type;
738   GetServiceWorkerRegistrationStatusResponse(
739       status, &error_type, &error_message);
740   Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError(
741       thread_id, request_id, error_type, error_message));
742 }
743
744 void ServiceWorkerDispatcherHost::SendGetRegistrationError(
745     int thread_id,
746     int request_id,
747     ServiceWorkerStatusCode status) {
748   base::string16 error_message;
749   blink::WebServiceWorkerError::ErrorType error_type;
750   GetServiceWorkerRegistrationStatusResponse(
751       status, &error_type, &error_message);
752   Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError(
753       thread_id, request_id, error_type, error_message));
754 }
755
756 ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
757   return context_wrapper_->context();
758 }
759
760 }  // namespace content