// Copyright (c) 2012 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 "ppapi/host/resource_message_filter.h" #include "base/bind.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/task_runner.h" #include "base/thread_task_runner_handle.h" #include "ipc/ipc_message.h" #include "ppapi/c/pp_errors.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/host/resource_host.h" namespace ppapi { namespace host { namespace internal { // static void ResourceMessageFilterDeleteTraits::Destruct( const ResourceMessageFilter* filter) { if (!filter->deletion_task_runner_->BelongsToCurrentThread()) { // During shutdown the object may not be deleted, but it should be okay to // leak in that case. filter->deletion_task_runner_->DeleteSoon(FROM_HERE, filter); } else { delete filter; } } } // namespace internal ResourceMessageFilter::ResourceMessageFilter() : deletion_task_runner_(base::ThreadTaskRunnerHandle::Get()), reply_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), resource_host_(NULL) { } ResourceMessageFilter::ResourceMessageFilter( scoped_refptr reply_thread_task_runner) : deletion_task_runner_(base::ThreadTaskRunnerHandle::Get()), reply_thread_task_runner_(reply_thread_task_runner), resource_host_(NULL) { } ResourceMessageFilter::~ResourceMessageFilter() { } void ResourceMessageFilter::OnFilterAdded(ResourceHost* resource_host) { resource_host_ = resource_host; } void ResourceMessageFilter::OnFilterDestroyed() { resource_host_ = NULL; } bool ResourceMessageFilter::HandleMessage(const IPC::Message& msg, HostMessageContext* context) { scoped_refptr runner = OverrideTaskRunnerForMessage(msg); if (runner.get()) { if (runner->RunsTasksOnCurrentThread()) { DispatchMessage(msg, *context); } else { // TODO(raymes): We need to make a copy so the context can be used on // other threads. It would be better to have a thread-safe refcounted // context. HostMessageContext context_copy = *context; runner->PostTask(FROM_HERE, base::Bind( &ResourceMessageFilter::DispatchMessage, this, msg, context_copy)); } return true; } return false; } void ResourceMessageFilter::SendReply(const ReplyMessageContext& context, const IPC::Message& msg) { if (!reply_thread_task_runner_->BelongsToCurrentThread()) { reply_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&ResourceMessageFilter::SendReply, this, context, msg)); return; } if (resource_host_) resource_host_->SendReply(context, msg); } scoped_refptr ResourceMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) { return NULL; } void ResourceMessageFilter::DispatchMessage(const IPC::Message& msg, HostMessageContext context) { RunMessageHandlerAndReply(msg, &context); } } // namespace host } // namespace ppapi