1// Copyright (c) 2012 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 "ppapi/host/resource_message_filter.h" 6 7#include "base/bind.h" 8#include "base/message_loop/message_loop.h" 9#include "base/message_loop/message_loop_proxy.h" 10#include "base/task_runner.h" 11#include "ipc/ipc_message.h" 12#include "ppapi/c/pp_errors.h" 13#include "ppapi/host/ppapi_host.h" 14#include "ppapi/host/resource_host.h" 15 16namespace ppapi { 17namespace host { 18 19namespace internal { 20 21// static 22void ResourceMessageFilterDeleteTraits::Destruct( 23 const ResourceMessageFilter* filter) { 24 if (!filter->deletion_message_loop_proxy_->BelongsToCurrentThread()) { 25 // During shutdown the object may not be deleted, but it should be okay to 26 // leak in that case. 27 filter->deletion_message_loop_proxy_->DeleteSoon(FROM_HERE, filter); 28 } else { 29 delete filter; 30 } 31} 32 33} // namespace internal 34 35ResourceMessageFilter::ResourceMessageFilter() 36 : deletion_message_loop_proxy_( 37 base::MessageLoop::current()->message_loop_proxy()), 38 reply_thread_message_loop_proxy_( 39 base::MessageLoop::current()->message_loop_proxy()), 40 resource_host_(NULL) { 41} 42 43ResourceMessageFilter::ResourceMessageFilter( 44 scoped_refptr<base::MessageLoopProxy> reply_thread_message_loop_proxy) 45 : deletion_message_loop_proxy_( 46 base::MessageLoop::current()->message_loop_proxy()), 47 reply_thread_message_loop_proxy_(reply_thread_message_loop_proxy), 48 resource_host_(NULL) { 49} 50 51ResourceMessageFilter::~ResourceMessageFilter() { 52} 53 54void ResourceMessageFilter::OnFilterAdded(ResourceHost* resource_host) { 55 resource_host_ = resource_host; 56} 57 58void ResourceMessageFilter::OnFilterDestroyed() { 59 resource_host_ = NULL; 60} 61 62bool ResourceMessageFilter::HandleMessage(const IPC::Message& msg, 63 HostMessageContext* context) { 64 scoped_refptr<base::TaskRunner> runner = OverrideTaskRunnerForMessage(msg); 65 if (runner.get()) { 66 if (runner->RunsTasksOnCurrentThread()) { 67 DispatchMessage(msg, *context); 68 } else { 69 // TODO(raymes): We need to make a copy so the context can be used on 70 // other threads. It would be better to have a thread-safe refcounted 71 // context. 72 HostMessageContext context_copy = *context; 73 runner->PostTask(FROM_HERE, base::Bind( 74 &ResourceMessageFilter::DispatchMessage, this, msg, context_copy)); 75 } 76 return true; 77 } 78 79 return false; 80} 81 82void ResourceMessageFilter::SendReply(const ReplyMessageContext& context, 83 const IPC::Message& msg) { 84 if (!reply_thread_message_loop_proxy_->BelongsToCurrentThread()) { 85 reply_thread_message_loop_proxy_->PostTask(FROM_HERE, 86 base::Bind(&ResourceMessageFilter::SendReply, this, context, msg)); 87 return; 88 } 89 if (resource_host_) 90 resource_host_->SendReply(context, msg); 91} 92 93scoped_refptr<base::TaskRunner> 94ResourceMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) { 95 return NULL; 96} 97 98void ResourceMessageFilter::DispatchMessage(const IPC::Message& msg, 99 HostMessageContext context) { 100 RunMessageHandlerAndReply(msg, &context); 101} 102 103} // namespace host 104} // namespace ppapi 105