| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/child/service_worker/service_worker_message_filter.h" |
| |
| #include <stddef.h> |
| |
| #include "content/child/service_worker/service_worker_dispatcher.h" |
| #include "content/child/thread_safe_sender.h" |
| #include "content/common/service_worker/service_worker_messages.h" |
| #include "content/common/service_worker/service_worker_types.h" |
| #include "ipc/ipc_message_macros.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| // Sends a ServiceWorkerObjectDestroyed message to the browser so it can delete |
| // the ServiceWorker handle. |
| void SendServiceWorkerObjectDestroyed( |
| ThreadSafeSender* sender, |
| int handle_id) { |
| if (handle_id == kInvalidServiceWorkerHandleId) |
| return; |
| sender->Send( |
| new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id)); |
| } |
| |
| void SendRegistrationObjectDestroyed( |
| ThreadSafeSender* sender, |
| int handle_id) { |
| if (handle_id == kInvalidServiceWorkerRegistrationHandleId) |
| return; |
| sender->Send( |
| new ServiceWorkerHostMsg_DecrementRegistrationRefCount(handle_id)); |
| } |
| |
| } // namespace |
| |
| ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender) |
| : WorkerThreadMessageFilter(sender) { |
| } |
| |
| ServiceWorkerMessageFilter::~ServiceWorkerMessageFilter() {} |
| |
| bool ServiceWorkerMessageFilter::ShouldHandleMessage( |
| const IPC::Message& msg) const { |
| return IPC_MESSAGE_CLASS(msg) == ServiceWorkerMsgStart; |
| } |
| |
| void ServiceWorkerMessageFilter::OnFilteredMessageReceived( |
| const IPC::Message& msg) { |
| ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( |
| thread_safe_sender(), main_thread_task_runner()) |
| ->OnMessageReceived(msg); |
| } |
| |
| bool ServiceWorkerMessageFilter::GetWorkerThreadIdForMessage( |
| const IPC::Message& msg, |
| int* ipc_thread_id) { |
| return base::PickleIterator(msg).ReadInt(ipc_thread_id); |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleMessageReceived( |
| const IPC::Message& msg) { |
| // Specifically handle some messages in case we failed to post task |
| // to the thread (meaning that the context on the thread is now gone). |
| IPC_BEGIN_MESSAGE_MAP(ServiceWorkerMessageFilter, msg) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration, |
| OnStaleAssociateRegistration) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, |
| OnStaleGetRegistration) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistration, |
| OnStaleGetRegistration) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrations, |
| OnStaleGetRegistrations) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistrationForReady, |
| OnStaleGetRegistration) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes, |
| OnStaleSetVersionAttributes) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker, |
| OnStaleSetControllerServiceWorker) |
| IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument, |
| OnStaleMessageToDocument) |
| IPC_END_MESSAGE_MAP() |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleAssociateRegistration( |
| int thread_id, |
| int provider_id, |
| const ServiceWorkerRegistrationObjectInfo& info, |
| const ServiceWorkerVersionAttributes& attrs) { |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.installing.handle_id); |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.waiting.handle_id); |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.active.handle_id); |
| SendRegistrationObjectDestroyed(thread_safe_sender(), info.handle_id); |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleGetRegistration( |
| int thread_id, |
| int request_id, |
| const ServiceWorkerRegistrationObjectInfo& info, |
| const ServiceWorkerVersionAttributes& attrs) { |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.installing.handle_id); |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.waiting.handle_id); |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.active.handle_id); |
| SendRegistrationObjectDestroyed(thread_safe_sender(), info.handle_id); |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleGetRegistrations( |
| int thread_id, |
| int request_id, |
| const std::vector<ServiceWorkerRegistrationObjectInfo>& infos, |
| const std::vector<ServiceWorkerVersionAttributes>& attrs) { |
| DCHECK_EQ(infos.size(), attrs.size()); |
| for (size_t i = 0; i < infos.size(); ++i) |
| OnStaleGetRegistration(thread_id, request_id, infos[i], attrs[i]); |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes( |
| int thread_id, |
| int registration_handle_id, |
| int changed_mask, |
| const ServiceWorkerVersionAttributes& attrs) { |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.installing.handle_id); |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.waiting.handle_id); |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| attrs.active.handle_id); |
| // Don't have to decrement registration refcount because the sender of the |
| // SetVersionAttributes message doesn't increment it. |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleSetControllerServiceWorker( |
| int thread_id, |
| int provider_id, |
| const ServiceWorkerObjectInfo& info, |
| bool should_notify_controllerchange) { |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), info.handle_id); |
| } |
| |
| void ServiceWorkerMessageFilter::OnStaleMessageToDocument( |
| const ServiceWorkerMsg_MessageToDocument_Params& params) { |
| SendServiceWorkerObjectDestroyed(thread_safe_sender(), |
| params.service_worker_info.handle_id); |
| } |
| |
| } // namespace content |