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