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 16 namespace ppapi { 17 namespace host { 18 19 ResourceMessageFilter::ResourceMessageFilter() 20 : reply_thread_message_loop_proxy_( 21 base::MessageLoop::current()->message_loop_proxy()), 22 resource_host_(NULL) {} 23 24 ResourceMessageFilter::ResourceMessageFilter( 25 scoped_refptr<base::MessageLoopProxy> reply_thread_message_loop_proxy) 26 : reply_thread_message_loop_proxy_(reply_thread_message_loop_proxy), 27 resource_host_(NULL) { 28 } 29 30 ResourceMessageFilter::~ResourceMessageFilter() { 31 } 32 33 void ResourceMessageFilter::OnFilterAdded(ResourceHost* resource_host) { 34 resource_host_ = resource_host; 35 } 36 37 void ResourceMessageFilter::OnFilterDestroyed() { 38 resource_host_ = NULL; 39 } 40 41 bool ResourceMessageFilter::HandleMessage(const IPC::Message& msg, 42 HostMessageContext* context) { 43 scoped_refptr<base::TaskRunner> runner = OverrideTaskRunnerForMessage(msg); 44 if (runner.get()) { 45 if (runner->RunsTasksOnCurrentThread()) { 46 DispatchMessage(msg, *context); 47 } else { 48 // TODO(raymes): We need to make a copy so the context can be used on 49 // other threads. It would be better to have a thread-safe refcounted 50 // context. 51 HostMessageContext context_copy = *context; 52 runner->PostTask(FROM_HERE, base::Bind( 53 &ResourceMessageFilter::DispatchMessage, this, msg, context_copy)); 54 } 55 return true; 56 } 57 58 return false; 59 } 60 61 void ResourceMessageFilter::SendReply(const ReplyMessageContext& context, 62 const IPC::Message& msg) { 63 if (!reply_thread_message_loop_proxy_->BelongsToCurrentThread()) { 64 reply_thread_message_loop_proxy_->PostTask(FROM_HERE, 65 base::Bind(&ResourceMessageFilter::SendReply, this, context, msg)); 66 return; 67 } 68 if (resource_host_) 69 resource_host_->SendReply(context, msg); 70 } 71 72 scoped_refptr<base::TaskRunner> 73 ResourceMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) { 74 return NULL; 75 } 76 77 void ResourceMessageFilter::DispatchMessage(const IPC::Message& msg, 78 HostMessageContext context) { 79 RunMessageHandlerAndReply(msg, &context); 80 } 81 82 } // namespace host 83 } // namespace ppapi 84