1 // Copyright 2013 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 "content/renderer/pepper/pepper_browser_connection.h" 6 7 #include <limits> 8 9 #include "base/logging.h" 10 #include "content/common/view_messages.h" 11 #include "content/renderer/pepper/pepper_in_process_router.h" 12 #include "content/renderer/render_view_impl.h" 13 #include "ipc/ipc_message_macros.h" 14 #include "ppapi/proxy/ppapi_messages.h" 15 #include "ppapi/proxy/resource_message_params.h" 16 17 namespace content { 18 19 PepperBrowserConnection::PepperBrowserConnection(RenderView* render_view) 20 : RenderViewObserver(render_view), 21 RenderViewObserverTracker<PepperBrowserConnection>(render_view), 22 next_sequence_number_(1) { 23 } 24 25 PepperBrowserConnection::~PepperBrowserConnection() { 26 } 27 28 bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) { 29 // Check if the message is an in-process reply. 30 if (PepperInProcessRouter::OnPluginMsgReceived(msg)) 31 return true; 32 33 bool handled = true; 34 IPC_BEGIN_MESSAGE_MAP(PepperBrowserConnection, msg) 35 IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostFromHostReply, 36 OnMsgCreateResourceHostFromHostReply) 37 IPC_MESSAGE_UNHANDLED(handled = false) 38 IPC_END_MESSAGE_MAP() 39 40 return handled; 41 } 42 43 void PepperBrowserConnection::DidCreateInProcessInstance( 44 PP_Instance instance, 45 int render_view_id, 46 const GURL& document_url, 47 const GURL& plugin_url) { 48 Send(new ViewHostMsg_DidCreateInProcessInstance( 49 instance, 50 // Browser provides the render process id. 51 PepperRendererInstanceData(0, 52 render_view_id, 53 document_url, 54 plugin_url))); 55 } 56 57 void PepperBrowserConnection::DidDeleteInProcessInstance(PP_Instance instance) { 58 Send(new ViewHostMsg_DidDeleteInProcessInstance(instance)); 59 } 60 61 void PepperBrowserConnection::SendBrowserCreate( 62 int child_process_id, 63 PP_Instance instance, 64 const IPC::Message& nested_msg, 65 const PendingResourceIDCallback& callback) { 66 int32_t sequence_number = GetNextSequence(); 67 pending_create_map_[sequence_number] = callback; 68 ppapi::proxy::ResourceMessageCallParams params(0, sequence_number); 69 Send(new PpapiHostMsg_CreateResourceHostFromHost( 70 routing_id(), 71 child_process_id, 72 params, 73 instance, 74 nested_msg)); 75 } 76 77 void PepperBrowserConnection::SendBrowserFileRefGetInfo( 78 int child_process_id, 79 const std::vector<PP_Resource>& resources, 80 const FileRefGetInfoCallback& callback) { 81 int32_t sequence_number = GetNextSequence(); 82 get_info_map_[sequence_number] = callback; 83 Send(new PpapiHostMsg_FileRef_GetInfoForRenderer( 84 routing_id(), child_process_id, sequence_number, resources)); 85 } 86 87 void PepperBrowserConnection::OnMsgCreateResourceHostFromHostReply( 88 int32_t sequence_number, 89 int pending_resource_host_id) { 90 // Check that the message is destined for the plugin this object is associated 91 // with. 92 std::map<int32_t, PendingResourceIDCallback>::iterator it = 93 pending_create_map_.find(sequence_number); 94 if (it != pending_create_map_.end()) { 95 it->second.Run(pending_resource_host_id); 96 pending_create_map_.erase(it); 97 } else { 98 NOTREACHED(); 99 } 100 } 101 102 void PepperBrowserConnection::OnMsgFileRefGetInfoReply( 103 int32_t sequence_number, 104 const std::vector<PP_Resource>& resources, 105 const std::vector<PP_FileSystemType>& types, 106 const std::vector<std::string>& file_system_url_specs, 107 const std::vector<base::FilePath>& external_paths) { 108 // Check that the message is destined for the plugin this object is associated 109 // with. 110 std::map<int32_t, FileRefGetInfoCallback>::iterator it = 111 get_info_map_.find(sequence_number); 112 if (it != get_info_map_.end()) { 113 FileRefGetInfoCallback callback = it->second; 114 get_info_map_.erase(it); 115 callback.Run(resources, types, file_system_url_specs, external_paths); 116 } else { 117 NOTREACHED(); 118 } 119 } 120 121 int32_t PepperBrowserConnection::GetNextSequence() { 122 // Return the value with wraparound, making sure we don't make a sequence 123 // number with a 0 ID. Note that signed wraparound is undefined in C++ so we 124 // manually check. 125 int32_t ret = next_sequence_number_; 126 if (next_sequence_number_ == std::numeric_limits<int32_t>::max()) 127 next_sequence_number_ = 1; // Skip 0 which is invalid. 128 else 129 next_sequence_number_++; 130 return ret; 131 } 132 133 } // namespace content 134