1 // Copyright (c) 2012 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/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 6 7 #include "content/browser/tracing/trace_message_filter.h" 8 #include "content/common/pepper_renderer_instance_data.h" 9 #include "content/public/browser/render_view_host.h" 10 #include "content/public/common/process_type.h" 11 #include "ipc/ipc_message_macros.h" 12 13 namespace content { 14 15 // static 16 BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess( 17 IPC::Sender* sender, 18 ppapi::PpapiPermissions permissions, 19 base::ProcessHandle plugin_child_process, 20 IPC::ChannelProxy* channel, 21 net::HostResolver* host_resolver, 22 int render_process_id, 23 int render_view_id, 24 const base::FilePath& profile_directory) { 25 scoped_refptr<PepperMessageFilter> pepper_message_filter( 26 new PepperMessageFilter(permissions, 27 host_resolver, 28 render_process_id, 29 render_view_id)); 30 31 // The plugin name and path shouldn't be needed for external plugins. 32 BrowserPpapiHostImpl* browser_ppapi_host = 33 new BrowserPpapiHostImpl(sender, permissions, std::string(), 34 base::FilePath(), profile_directory, true, 35 pepper_message_filter); 36 browser_ppapi_host->set_plugin_process_handle(plugin_child_process); 37 38 channel->AddFilter(pepper_message_filter); 39 channel->AddFilter(browser_ppapi_host->message_filter().get()); 40 channel->AddFilter(new TraceMessageFilter()); 41 42 return browser_ppapi_host; 43 } 44 45 BrowserPpapiHostImpl::BrowserPpapiHostImpl( 46 IPC::Sender* sender, 47 const ppapi::PpapiPermissions& permissions, 48 const std::string& plugin_name, 49 const base::FilePath& plugin_path, 50 const base::FilePath& profile_data_directory, 51 bool external_plugin, 52 const scoped_refptr<PepperMessageFilter>& pepper_message_filter) 53 : ppapi_host_(new ppapi::host::PpapiHost(sender, permissions)), 54 plugin_process_handle_(base::kNullProcessHandle), 55 plugin_name_(plugin_name), 56 plugin_path_(plugin_path), 57 profile_data_directory_(profile_data_directory), 58 external_plugin_(external_plugin) { 59 message_filter_ = new HostMessageFilter(ppapi_host_.get()); 60 ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>( 61 new ContentBrowserPepperHostFactory(this, pepper_message_filter))); 62 } 63 64 BrowserPpapiHostImpl::~BrowserPpapiHostImpl() { 65 // Notify the filter so it won't foward messages to us. 66 message_filter_->OnHostDestroyed(); 67 68 // Delete the host explicitly first. This shutdown will destroy the 69 // resources, which may want to do cleanup in their destructors and expect 70 // their pointers to us to be valid. 71 ppapi_host_.reset(); 72 } 73 74 ppapi::host::PpapiHost* BrowserPpapiHostImpl::GetPpapiHost() { 75 return ppapi_host_.get(); 76 } 77 78 base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const { 79 // Handle should previously have been set before use. 80 DCHECK(plugin_process_handle_ != base::kNullProcessHandle); 81 return plugin_process_handle_; 82 } 83 84 bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const { 85 return instance_map_.find(instance) != instance_map_.end(); 86 } 87 88 bool BrowserPpapiHostImpl::GetRenderViewIDsForInstance( 89 PP_Instance instance, 90 int* render_process_id, 91 int* render_view_id) const { 92 InstanceMap::const_iterator found = instance_map_.find(instance); 93 if (found == instance_map_.end()) { 94 *render_process_id = 0; 95 *render_view_id = 0; 96 return false; 97 } 98 99 *render_process_id = found->second.render_process_id; 100 *render_view_id = found->second.render_view_id; 101 return true; 102 } 103 104 const std::string& BrowserPpapiHostImpl::GetPluginName() { 105 return plugin_name_; 106 } 107 108 const base::FilePath& BrowserPpapiHostImpl::GetPluginPath() { 109 return plugin_path_; 110 } 111 112 const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() { 113 return profile_data_directory_; 114 } 115 116 GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) { 117 InstanceMap::const_iterator found = instance_map_.find(instance); 118 if (found == instance_map_.end()) 119 return GURL(); 120 return found->second.document_url; 121 } 122 123 GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) { 124 InstanceMap::const_iterator found = instance_map_.find(instance); 125 if (found == instance_map_.end()) 126 return GURL(); 127 return found->second.plugin_url; 128 } 129 130 void BrowserPpapiHostImpl::AddInstance( 131 PP_Instance instance, 132 const PepperRendererInstanceData& instance_data) { 133 DCHECK(instance_map_.find(instance) == instance_map_.end()); 134 instance_map_[instance] = instance_data; 135 } 136 137 void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) { 138 InstanceMap::iterator found = instance_map_.find(instance); 139 if (found == instance_map_.end()) { 140 NOTREACHED(); 141 return; 142 } 143 instance_map_.erase(found); 144 } 145 146 bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived( 147 const IPC::Message& msg) { 148 // Don't forward messages if our owner object has been destroyed. 149 if (!ppapi_host_) 150 return false; 151 152 /* TODO(brettw) when we add messages, here, the code should look like this: 153 bool handled = true; 154 IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl, msg) 155 // Add necessary message handlers here. 156 IPC_MESSAGE_UNHANDLED(handled = ppapi_host_->OnMessageReceived(msg)) 157 IPC_END_MESSAGE_MAP(); 158 return handled; 159 */ 160 return ppapi_host_->OnMessageReceived(msg); 161 } 162 163 void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() { 164 DCHECK(ppapi_host_); 165 ppapi_host_ = NULL; 166 } 167 168 } // namespace content 169