Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / renderer / pepper / renderer_ppapi_host_impl.cc
blobff8e819ec370c61887e9c5863c94ab648ec825c8
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.
5 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/process/process_handle.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "content/common/sandbox_util.h"
15 #include "content/renderer/pepper/fullscreen_container.h"
16 #include "content/renderer/pepper/host_globals.h"
17 #include "content/renderer/pepper/pepper_browser_connection.h"
18 #include "content/renderer/pepper/pepper_graphics_2d_host.h"
19 #include "content/renderer/pepper/pepper_in_process_resource_creation.h"
20 #include "content/renderer/pepper/pepper_in_process_router.h"
21 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
22 #include "content/renderer/pepper/plugin_module.h"
23 #include "content/renderer/render_view_impl.h"
24 #include "content/renderer/render_widget_fullscreen_pepper.h"
25 #include "ipc/ipc_message.h"
26 #include "ppapi/host/ppapi_host.h"
27 #include "ppapi/proxy/host_dispatcher.h"
28 #include "third_party/WebKit/public/platform/WebRect.h"
29 #include "third_party/WebKit/public/web/WebDocument.h"
30 #include "third_party/WebKit/public/web/WebElement.h"
31 #include "third_party/WebKit/public/web/WebPluginContainer.h"
32 #include "ui/gfx/geometry/point.h"
34 namespace content {
35 // static
36 CONTENT_EXPORT RendererPpapiHost* RendererPpapiHost::GetForPPInstance(
37 PP_Instance instance) {
38 return RendererPpapiHostImpl::GetForPPInstance(instance);
41 // Out-of-process constructor.
42 RendererPpapiHostImpl::RendererPpapiHostImpl(
43 PluginModule* module,
44 ppapi::proxy::HostDispatcher* dispatcher,
45 const ppapi::PpapiPermissions& permissions)
46 : module_(module),
47 dispatcher_(dispatcher),
48 is_external_plugin_host_(false) {
49 // Hook the PpapiHost up to the dispatcher for out-of-process communication.
50 ppapi_host_.reset(new ppapi::host::PpapiHost(dispatcher, permissions));
51 ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
52 new ContentRendererPepperHostFactory(this)));
53 dispatcher->AddFilter(ppapi_host_.get());
54 is_running_in_process_ = false;
57 // In-process constructor.
58 RendererPpapiHostImpl::RendererPpapiHostImpl(
59 PluginModule* module,
60 const ppapi::PpapiPermissions& permissions)
61 : module_(module), dispatcher_(NULL), is_external_plugin_host_(false) {
62 // Hook the host up to the in-process router.
63 in_process_router_.reset(new PepperInProcessRouter(this));
64 ppapi_host_.reset(new ppapi::host::PpapiHost(
65 in_process_router_->GetRendererToPluginSender(), permissions));
66 ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
67 new ContentRendererPepperHostFactory(this)));
68 is_running_in_process_ = true;
71 RendererPpapiHostImpl::~RendererPpapiHostImpl() {
72 // Delete the host explicitly first. This shutdown will destroy the
73 // resources, which may want to do cleanup in their destructors and expect
74 // their pointers to us to be valid.
75 ppapi_host_.reset();
78 // static
79 RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForOutOfProcess(
80 PluginModule* module,
81 ppapi::proxy::HostDispatcher* dispatcher,
82 const ppapi::PpapiPermissions& permissions) {
83 DCHECK(!module->renderer_ppapi_host());
84 RendererPpapiHostImpl* result =
85 new RendererPpapiHostImpl(module, dispatcher, permissions);
87 // Takes ownership of pointer.
88 module->SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl>(result));
90 return result;
93 // static
94 RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForInProcess(
95 PluginModule* module,
96 const ppapi::PpapiPermissions& permissions) {
97 DCHECK(!module->renderer_ppapi_host());
98 RendererPpapiHostImpl* result =
99 new RendererPpapiHostImpl(module, permissions);
101 // Takes ownership of pointer.
102 module->SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl>(result));
104 return result;
107 // static
108 RendererPpapiHostImpl* RendererPpapiHostImpl::GetForPPInstance(
109 PP_Instance pp_instance) {
110 PepperPluginInstanceImpl* instance =
111 HostGlobals::Get()->GetInstance(pp_instance);
112 if (!instance)
113 return NULL;
115 // All modules created by content will have their embedder state be the
116 // host impl.
117 return instance->module()->renderer_ppapi_host();
120 scoped_ptr<ppapi::thunk::ResourceCreationAPI>
121 RendererPpapiHostImpl::CreateInProcessResourceCreationAPI(
122 PepperPluginInstanceImpl* instance) {
123 return scoped_ptr<ppapi::thunk::ResourceCreationAPI>(
124 new PepperInProcessResourceCreation(this, instance));
127 PepperPluginInstanceImpl* RendererPpapiHostImpl::GetPluginInstanceImpl(
128 PP_Instance instance) const {
129 return GetAndValidateInstance(instance);
132 bool RendererPpapiHostImpl::IsExternalPluginHost() const {
133 return is_external_plugin_host_;
136 ppapi::host::PpapiHost* RendererPpapiHostImpl::GetPpapiHost() {
137 return ppapi_host_.get();
140 RenderFrame* RendererPpapiHostImpl::GetRenderFrameForInstance(
141 PP_Instance instance) const {
142 PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
143 if (!instance_object)
144 return NULL;
146 // Since we're the embedder, we can make assumptions about the helper on
147 // the instance and get back to our RenderFrame.
148 return instance_object->render_frame();
151 RenderView* RendererPpapiHostImpl::GetRenderViewForInstance(
152 PP_Instance instance) const {
153 PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
154 if (!instance_object)
155 return NULL;
157 // Since we're the embedder, we can make assumptions about the helper on
158 // the instance and get back to our RenderView.
159 return instance_object->render_frame()->render_view();
162 bool RendererPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
163 return !!GetAndValidateInstance(instance);
166 PepperPluginInstance* RendererPpapiHostImpl::GetPluginInstance(
167 PP_Instance instance) const {
168 return GetAndValidateInstance(instance);
171 blink::WebPluginContainer* RendererPpapiHostImpl::GetContainerForInstance(
172 PP_Instance instance) const {
173 PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
174 if (!instance_object)
175 return NULL;
176 return instance_object->container();
179 base::ProcessId RendererPpapiHostImpl::GetPluginPID() const {
180 if (dispatcher_)
181 return dispatcher_->channel()->GetPeerPID();
182 return base::kNullProcessId;
185 bool RendererPpapiHostImpl::HasUserGesture(PP_Instance instance) const {
186 PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
187 if (!instance_object)
188 return false;
190 if (instance_object->module()->permissions().HasPermission(
191 ppapi::PERMISSION_BYPASS_USER_GESTURE))
192 return true;
193 return instance_object->IsProcessingUserGesture();
196 int RendererPpapiHostImpl::GetRoutingIDForWidget(PP_Instance instance) const {
197 PepperPluginInstanceImpl* plugin_instance = GetAndValidateInstance(instance);
198 if (!plugin_instance)
199 return 0;
200 if (plugin_instance->flash_fullscreen()) {
201 FullscreenContainer* container = plugin_instance->fullscreen_container();
202 return static_cast<RenderWidgetFullscreenPepper*>(container)->routing_id();
204 return GetRenderViewForInstance(instance)->GetRoutingID();
207 gfx::Point RendererPpapiHostImpl::PluginPointToRenderFrame(
208 PP_Instance instance,
209 const gfx::Point& pt) const {
210 PepperPluginInstanceImpl* plugin_instance = GetAndValidateInstance(instance);
211 if (!plugin_instance || plugin_instance->flash_fullscreen()) {
212 // Flash fullscreen is special in that it renders into its own separate,
213 // dedicated window. So, do not offset the point.
214 return pt;
216 return gfx::Point(pt.x() + plugin_instance->view_data().rect.point.x,
217 pt.y() + plugin_instance->view_data().rect.point.y);
220 IPC::PlatformFileForTransit RendererPpapiHostImpl::ShareHandleWithRemote(
221 base::PlatformFile handle,
222 bool should_close_source) {
223 if (!dispatcher_) {
224 DCHECK(is_running_in_process_);
225 // Duplicate the file handle for in process mode so this function
226 // has the same semantics for both in process mode and out of
227 // process mode (i.e., the remote side must cloes the handle).
228 return BrokerGetFileHandleForProcess(
229 handle, base::GetCurrentProcId(), should_close_source);
231 return dispatcher_->ShareHandleWithRemote(handle, should_close_source);
234 base::SharedMemoryHandle
235 RendererPpapiHostImpl::ShareSharedMemoryHandleWithRemote(
236 const base::SharedMemoryHandle& handle) {
237 if (!dispatcher_) {
238 DCHECK(is_running_in_process_);
239 return base::SharedMemory::DuplicateHandle(handle);
241 return dispatcher_->ShareSharedMemoryHandleWithRemote(handle);
244 bool RendererPpapiHostImpl::IsRunningInProcess() const {
245 return is_running_in_process_;
248 std::string RendererPpapiHostImpl::GetPluginName() const {
249 return module_->name();
252 void RendererPpapiHostImpl::SetToExternalPluginHost() {
253 is_external_plugin_host_ = true;
256 void RendererPpapiHostImpl::CreateBrowserResourceHosts(
257 PP_Instance instance,
258 const std::vector<IPC::Message>& nested_msgs,
259 const base::Callback<void(const std::vector<int>&)>& callback) const {
260 RenderFrame* render_frame = GetRenderFrameForInstance(instance);
261 PepperBrowserConnection* browser_connection =
262 PepperBrowserConnection::Get(render_frame);
263 if (!browser_connection) {
264 base::ThreadTaskRunnerHandle::Get()->PostTask(
265 FROM_HERE,
266 base::Bind(callback, std::vector<int>(nested_msgs.size(), 0)));
267 } else {
268 browser_connection->SendBrowserCreate(
269 module_->GetPluginChildId(), instance, nested_msgs, callback);
273 GURL RendererPpapiHostImpl::GetDocumentURL(PP_Instance pp_instance) const {
274 PepperPluginInstanceImpl* instance = GetAndValidateInstance(pp_instance);
275 if (!instance)
276 return GURL();
277 return instance->document_url();
280 PepperPluginInstanceImpl* RendererPpapiHostImpl::GetAndValidateInstance(
281 PP_Instance pp_instance) const {
282 PepperPluginInstanceImpl* instance =
283 HostGlobals::Get()->GetInstance(pp_instance);
284 if (!instance)
285 return NULL;
286 if (!instance->IsValidInstanceOf(module_))
287 return NULL;
288 return instance;
291 } // namespace content