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 namespace internal { 20 21 // static 22 void 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 35 ResourceMessageFilter::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 43 ResourceMessageFilter::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 51 ResourceMessageFilter::~ResourceMessageFilter() { 52 } 53 54 void ResourceMessageFilter::OnFilterAdded(ResourceHost* resource_host) { 55 resource_host_ = resource_host; 56 } 57 58 void ResourceMessageFilter::OnFilterDestroyed() { 59 resource_host_ = NULL; 60 } 61 62 bool 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 82 void 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 93 scoped_refptr<base::TaskRunner> 94 ResourceMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) { 95 return NULL; 96 } 97 98 void ResourceMessageFilter::DispatchMessage(const IPC::Message& msg, 99 HostMessageContext context) { 100 RunMessageHandlerAndReply(msg, &context); 101 } 102 103 } // namespace host 104 } // namespace ppapi 105