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_->GetTargetThread(reply_params, 87 nested_msg); 88 89 if (!target.get()) { 90 DispatchResourceReply(reply_params, nested_msg); 91 } else { 92 target->PostTask( 93 FROM_HERE, 94 base::Bind(&DispatchResourceReply, reply_params, nested_msg)); 95 } 96 } 97 98 // static 99 void PluginMessageFilter::DispatchResourceReply( 100 const ResourceMessageReplyParams& reply_params, 101 const IPC::Message& nested_msg) { 102 ProxyAutoLock lock; 103 Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource( 104 reply_params.pp_resource()); 105 if (!resource) { 106 DVLOG_IF(1, reply_params.sequence() != 0) 107 << "Pepper resource reply message received but the resource doesn't " 108 "exist (probably has been destroyed)."; 109 return; 110 } 111 resource->OnReplyReceived(reply_params, nested_msg); 112 } 113 114 } // namespace proxy 115 } // namespace ppapi 116