blob: d73d4c44f4c7fe92a695c4dad0507ac03074a366 [file] [log] [blame]
// 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