Home | History | Annotate | Download | only in host
      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