Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2011 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/proxy/plugin_message_filter.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "ipc/ipc_channel.h"
     10 #include "ppapi/proxy/ppapi_messages.h"
     11 #include "ppapi/proxy/resource_message_params.h"
     12 #include "ppapi/proxy/resource_reply_thread_registrar.h"
     13 #include "ppapi/shared_impl/ppapi_globals.h"
     14 #include "ppapi/shared_impl/proxy_lock.h"
     15 #include "ppapi/shared_impl/resource.h"
     16 #include "ppapi/shared_impl/resource_tracker.h"
     17 
     18 namespace ppapi {
     19 namespace proxy {
     20 
     21 PluginMessageFilter::PluginMessageFilter(
     22     std::set<PP_Instance>* seen_instance_ids,
     23     scoped_refptr<ResourceReplyThreadRegistrar> registrar)
     24     : seen_instance_ids_(seen_instance_ids),
     25       resource_reply_thread_registrar_(registrar),
     26       sender_(NULL) {
     27 }
     28 
     29 PluginMessageFilter::~PluginMessageFilter() {
     30 }
     31 
     32 void PluginMessageFilter::OnFilterAdded(IPC::Sender* sender) {
     33   sender_ = sender;
     34 }
     35 
     36 void PluginMessageFilter::OnFilterRemoved() {
     37   sender_ = NULL;
     38 }
     39 
     40 bool PluginMessageFilter::OnMessageReceived(const IPC::Message& message) {
     41   bool handled = true;
     42   IPC_BEGIN_MESSAGE_MAP(PluginMessageFilter, message)
     43     IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnMsgReserveInstanceId)
     44     IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply)
     45     IPC_MESSAGE_UNHANDLED(handled = false)
     46   IPC_END_MESSAGE_MAP()
     47   return handled;
     48 }
     49 
     50 bool PluginMessageFilter::Send(IPC::Message* msg) {
     51   if (sender_)
     52     return sender_->Send(msg);
     53   delete msg;
     54   return false;
     55 }
     56 
     57 // static
     58 void PluginMessageFilter::DispatchResourceReplyForTest(
     59     const ResourceMessageReplyParams& reply_params,
     60     const IPC::Message& nested_msg) {
     61   DispatchResourceReply(reply_params, nested_msg);
     62 }
     63 
     64 void PluginMessageFilter::OnMsgReserveInstanceId(PP_Instance instance,
     65                                                  bool* usable) {
     66   // If |seen_instance_ids_| is set to NULL, we are not supposed to see this
     67   // message.
     68   CHECK(seen_instance_ids_);
     69   // See the message definition for how this works.
     70   if (seen_instance_ids_->find(instance) != seen_instance_ids_->end()) {
     71     // Instance ID already seen, reject it.
     72     *usable = false;
     73     return;
     74   }
     75 
     76   // This instance ID is new so we can return that it's usable and mark it as
     77   // used for future reference.
     78   seen_instance_ids_->insert(instance);
     79   *usable = true;
     80 }
     81 
     82 void PluginMessageFilter::OnMsgResourceReply(
     83     const ResourceMessageReplyParams& reply_params,
     84     const IPC::Message& nested_msg) {
     85   scoped_refptr<base::MessageLoopProxy> target =
     86       resource_reply_thread_registrar_->GetTargetThreadAndUnregister(
     87           reply_params.pp_resource(), reply_params.sequence());
     88 
     89   target->PostTask(
     90       FROM_HERE,
     91       base::Bind(&DispatchResourceReply, reply_params, nested_msg));
     92 }
     93 
     94 // static
     95 void PluginMessageFilter::DispatchResourceReply(
     96     const ResourceMessageReplyParams& reply_params,
     97     const IPC::Message& nested_msg) {
     98   ProxyAutoLock lock;
     99   Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource(
    100       reply_params.pp_resource());
    101   if (!resource) {
    102     DVLOG_IF(1, reply_params.sequence() != 0)
    103         << "Pepper resource reply message received but the resource doesn't "
    104            "exist (probably has been destroyed).";
    105     return;
    106   }
    107   resource->OnReplyReceived(reply_params, nested_msg);
    108 }
    109 
    110 }  // namespace proxy
    111 }  // namespace ppapi
    112