Home | History | Annotate | Download | only in service_worker
      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/child/service_worker/service_worker_message_filter.h"
      6 
      7 #include "base/message_loop/message_loop_proxy.h"
      8 #include "content/child/service_worker/service_worker_dispatcher.h"
      9 #include "content/child/thread_safe_sender.h"
     10 #include "content/child/worker_thread_task_runner.h"
     11 #include "content/common/service_worker/service_worker_messages.h"
     12 #include "ipc/ipc_message_macros.h"
     13 
     14 namespace content {
     15 
     16 namespace {
     17 
     18 // Sends a ServiceWorkerObjectDestroyed message to the browser so it can delete
     19 // the ServiceWorker handle.
     20 void SendServiceWorkerObjectDestroyed(
     21     scoped_refptr<ThreadSafeSender> sender,
     22     int handle_id) {
     23   if (handle_id == kInvalidServiceWorkerHandleId)
     24     return;
     25   sender->Send(
     26       new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id));
     27 }
     28 
     29 }  // namespace
     30 
     31 ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender)
     32     : main_thread_loop_proxy_(base::MessageLoopProxy::current()),
     33       thread_safe_sender_(sender) {}
     34 
     35 ServiceWorkerMessageFilter::~ServiceWorkerMessageFilter() {}
     36 
     37 base::TaskRunner* ServiceWorkerMessageFilter::OverrideTaskRunnerForMessage(
     38     const IPC::Message& msg) {
     39   if (IPC_MESSAGE_CLASS(msg) != ServiceWorkerMsgStart)
     40     return NULL;
     41   int ipc_thread_id = 0;
     42   const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id);
     43   DCHECK(success);
     44   if (!ipc_thread_id)
     45     return main_thread_loop_proxy_.get();
     46   return new WorkerThreadTaskRunner(ipc_thread_id);
     47 }
     48 
     49 bool ServiceWorkerMessageFilter::OnMessageReceived(const IPC::Message& msg) {
     50   if (IPC_MESSAGE_CLASS(msg) != ServiceWorkerMsgStart)
     51     return false;
     52   ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
     53       thread_safe_sender_.get())->OnMessageReceived(msg);
     54   return true;
     55 }
     56 
     57 void ServiceWorkerMessageFilter::OnStaleMessageReceived(
     58     const IPC::Message& msg) {
     59   // Specifically handle some messages in case we failed to post task
     60   // to the thread (meaning that the context on the thread is now gone).
     61   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerMessageFilter, msg)
     62     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered,
     63                         OnStaleRegistered)
     64     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetWaitingServiceWorker,
     65                         OnStaleSetServiceWorker)
     66     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
     67                         OnStaleSetServiceWorker)
     68   IPC_END_MESSAGE_MAP()
     69 }
     70 
     71 void ServiceWorkerMessageFilter::OnStaleRegistered(
     72     int thread_id,
     73     int request_id,
     74     const ServiceWorkerObjectInfo& info) {
     75   SendServiceWorkerObjectDestroyed(thread_safe_sender_, info.handle_id);
     76 }
     77 
     78 void ServiceWorkerMessageFilter::OnStaleSetServiceWorker(
     79     int thread_id,
     80     int provider_id,
     81     const ServiceWorkerObjectInfo& info) {
     82   SendServiceWorkerObjectDestroyed(thread_safe_sender_, info.handle_id);
     83 }
     84 
     85 }  // namespace content
     86