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