• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PluginMessageFilter(std::set<PP_Instance> * seen_instance_ids,scoped_refptr<ResourceReplyThreadRegistrar> registrar)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 
~PluginMessageFilter()29 PluginMessageFilter::~PluginMessageFilter() {
30 }
31 
OnFilterAdded(IPC::Sender * sender)32 void PluginMessageFilter::OnFilterAdded(IPC::Sender* sender) {
33   sender_ = sender;
34 }
35 
OnFilterRemoved()36 void PluginMessageFilter::OnFilterRemoved() {
37   sender_ = NULL;
38 }
39 
OnMessageReceived(const IPC::Message & message)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 
Send(IPC::Message * msg)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
DispatchResourceReplyForTest(const ResourceMessageReplyParams & reply_params,const IPC::Message & nested_msg)58 void PluginMessageFilter::DispatchResourceReplyForTest(
59     const ResourceMessageReplyParams& reply_params,
60     const IPC::Message& nested_msg) {
61   DispatchResourceReply(reply_params, nested_msg);
62 }
63 
OnMsgReserveInstanceId(PP_Instance instance,bool * usable)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 
OnMsgResourceReply(const ResourceMessageReplyParams & reply_params,const IPC::Message & nested_msg)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
DispatchResourceReply(const ResourceMessageReplyParams & reply_params,const IPC::Message & nested_msg)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