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
CreateExternalPluginProcess(IPC::Sender * sender,ppapi::PpapiPermissions permissions,base::ProcessHandle plugin_child_process,IPC::ChannelProxy * channel,int render_process_id,int render_view_id,const base::FilePath & profile_directory)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
BrowserPpapiHostImpl(IPC::Sender * sender,const ppapi::PpapiPermissions & permissions,const std::string & plugin_name,const base::FilePath & plugin_path,const base::FilePath & profile_data_directory,bool in_process,bool external_plugin)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
~BrowserPpapiHostImpl()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
GetPpapiHost()73 ppapi::host::PpapiHost* BrowserPpapiHostImpl::GetPpapiHost() {
74 return ppapi_host_.get();
75 }
76
GetPluginProcessHandle() const77 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
IsValidInstance(PP_Instance instance) const83 bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
84 return instance_map_.find(instance) != instance_map_.end();
85 }
86
GetRenderViewIDsForInstance(PP_Instance instance,int * render_process_id,int * render_view_id) const87 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
GetPluginName()103 const std::string& BrowserPpapiHostImpl::GetPluginName() {
104 return plugin_name_;
105 }
106
GetPluginPath()107 const base::FilePath& BrowserPpapiHostImpl::GetPluginPath() {
108 return plugin_path_;
109 }
110
GetProfileDataDirectory()111 const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() {
112 return profile_data_directory_;
113 }
114
GetDocumentURLForInstance(PP_Instance instance)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
GetPluginURLForInstance(PP_Instance instance)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
AddInstance(PP_Instance instance,const PepperRendererInstanceData & instance_data)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
DeleteInstance(PP_Instance instance)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
OnMessageReceived(const IPC::Message & msg)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
OnHostDestroyed()162 void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() {
163 DCHECK(ppapi_host_);
164 ppapi_host_ = NULL;
165 }
166
167 } // namespace content
168