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