Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / renderer_ppapi_host_impl.cc
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/renderer/pepper/renderer_ppapi_host_impl.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/process/process_handle.h"
12 #include "content/common/sandbox_util.h"
13 #include "content/renderer/pepper/fullscreen_container.h"
14 #include "content/renderer/pepper/host_globals.h"
15 #include "content/renderer/pepper/pepper_browser_connection.h"
16 #include "content/renderer/pepper/pepper_graphics_2d_host.h"
17 #include "content/renderer/pepper/pepper_in_process_resource_creation.h"
18 #include "content/renderer/pepper/pepper_in_process_router.h"
19 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
20 #include "content/renderer/pepper/plugin_module.h"
21 #include "content/renderer/render_view_impl.h"
22 #include "content/renderer/render_widget_fullscreen_pepper.h"
23 #include "ipc/ipc_message.h"
24 #include "ppapi/host/ppapi_host.h"
25 #include "ppapi/proxy/host_dispatcher.h"
26 #include "third_party/WebKit/public/platform/WebRect.h"
27 #include "third_party/WebKit/public/web/WebDocument.h"
28 #include "third_party/WebKit/public/web/WebElement.h"
29 #include "third_party/WebKit/public/web/WebPluginContainer.h"
30 #include "ui/gfx/point.h"
31
32 namespace content {
33 // static
34 CONTENT_EXPORT RendererPpapiHost* RendererPpapiHost::GetForPPInstance(
35     PP_Instance instance) {
36   return RendererPpapiHostImpl::GetForPPInstance(instance);
37 }
38
39 // Out-of-process constructor.
40 RendererPpapiHostImpl::RendererPpapiHostImpl(
41     PluginModule* module,
42     ppapi::proxy::HostDispatcher* dispatcher,
43     const ppapi::PpapiPermissions& permissions)
44     : module_(module), dispatcher_(dispatcher) {
45   // Hook the PpapiHost up to the dispatcher for out-of-process communication.
46   ppapi_host_.reset(new ppapi::host::PpapiHost(dispatcher, permissions));
47   ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
48       new ContentRendererPepperHostFactory(this)));
49   dispatcher->AddFilter(ppapi_host_.get());
50   is_running_in_process_ = false;
51 }
52
53 // In-process constructor.
54 RendererPpapiHostImpl::RendererPpapiHostImpl(
55     PluginModule* module,
56     const ppapi::PpapiPermissions& permissions)
57     : module_(module), dispatcher_(NULL) {
58   // Hook the host up to the in-process router.
59   in_process_router_.reset(new PepperInProcessRouter(this));
60   ppapi_host_.reset(new ppapi::host::PpapiHost(
61       in_process_router_->GetRendererToPluginSender(), permissions));
62   ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
63       new ContentRendererPepperHostFactory(this)));
64   is_running_in_process_ = true;
65 }
66
67 RendererPpapiHostImpl::~RendererPpapiHostImpl() {
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 // static
75 RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForOutOfProcess(
76     PluginModule* module,
77     ppapi::proxy::HostDispatcher* dispatcher,
78     const ppapi::PpapiPermissions& permissions) {
79   DCHECK(!module->renderer_ppapi_host());
80   RendererPpapiHostImpl* result =
81       new RendererPpapiHostImpl(module, dispatcher, permissions);
82
83   // Takes ownership of pointer.
84   module->SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl>(result));
85
86   return result;
87 }
88
89 // static
90 RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForInProcess(
91     PluginModule* module,
92     const ppapi::PpapiPermissions& permissions) {
93   DCHECK(!module->renderer_ppapi_host());
94   RendererPpapiHostImpl* result =
95       new RendererPpapiHostImpl(module, permissions);
96
97   // Takes ownership of pointer.
98   module->SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl>(result));
99
100   return result;
101 }
102
103 // static
104 RendererPpapiHostImpl* RendererPpapiHostImpl::GetForPPInstance(
105     PP_Instance pp_instance) {
106   PepperPluginInstanceImpl* instance =
107       HostGlobals::Get()->GetInstance(pp_instance);
108   if (!instance)
109     return NULL;
110
111   // All modules created by content will have their embedder state be the
112   // host impl.
113   return instance->module()->renderer_ppapi_host();
114 }
115
116 scoped_ptr<ppapi::thunk::ResourceCreationAPI>
117 RendererPpapiHostImpl::CreateInProcessResourceCreationAPI(
118     PepperPluginInstanceImpl* instance) {
119   return scoped_ptr<ppapi::thunk::ResourceCreationAPI>(
120       new PepperInProcessResourceCreation(this, instance));
121 }
122
123 PepperPluginInstanceImpl* RendererPpapiHostImpl::GetPluginInstanceImpl(
124     PP_Instance instance) const {
125   return GetAndValidateInstance(instance);
126 }
127
128 ppapi::host::PpapiHost* RendererPpapiHostImpl::GetPpapiHost() {
129   return ppapi_host_.get();
130 }
131
132 RenderFrame* RendererPpapiHostImpl::GetRenderFrameForInstance(
133     PP_Instance instance) const {
134   PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
135   if (!instance_object)
136     return NULL;
137
138   // Since we're the embedder, we can make assumptions about the helper on
139   // the instance and get back to our RenderFrame.
140   return instance_object->render_frame();
141 }
142
143 RenderView* RendererPpapiHostImpl::GetRenderViewForInstance(
144     PP_Instance instance) const {
145   PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
146   if (!instance_object)
147     return NULL;
148
149   // Since we're the embedder, we can make assumptions about the helper on
150   // the instance and get back to our RenderView.
151   return instance_object->render_frame()->render_view();
152 }
153
154 bool RendererPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
155   return !!GetAndValidateInstance(instance);
156 }
157
158 PepperPluginInstance* RendererPpapiHostImpl::GetPluginInstance(
159     PP_Instance instance) const {
160   return GetAndValidateInstance(instance);
161 }
162
163 blink::WebPluginContainer* RendererPpapiHostImpl::GetContainerForInstance(
164     PP_Instance instance) const {
165   PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
166   if (!instance_object)
167     return NULL;
168   return instance_object->container();
169 }
170
171 base::ProcessId RendererPpapiHostImpl::GetPluginPID() const {
172   if (dispatcher_)
173     return dispatcher_->channel()->peer_pid();
174   return base::kNullProcessId;
175 }
176
177 bool RendererPpapiHostImpl::HasUserGesture(PP_Instance instance) const {
178   PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
179   if (!instance_object)
180     return false;
181
182   if (instance_object->module()->permissions().HasPermission(
183           ppapi::PERMISSION_BYPASS_USER_GESTURE))
184     return true;
185   return instance_object->IsProcessingUserGesture();
186 }
187
188 int RendererPpapiHostImpl::GetRoutingIDForWidget(PP_Instance instance) const {
189   PepperPluginInstanceImpl* plugin_instance = GetAndValidateInstance(instance);
190   if (!plugin_instance)
191     return 0;
192   if (plugin_instance->flash_fullscreen()) {
193     FullscreenContainer* container = plugin_instance->fullscreen_container();
194     return static_cast<RenderWidgetFullscreenPepper*>(container)->routing_id();
195   }
196   return GetRenderViewForInstance(instance)->GetRoutingID();
197 }
198
199 gfx::Point RendererPpapiHostImpl::PluginPointToRenderFrame(
200     PP_Instance instance,
201     const gfx::Point& pt) const {
202   PepperPluginInstanceImpl* plugin_instance = GetAndValidateInstance(instance);
203   if (!plugin_instance || plugin_instance->flash_fullscreen()) {
204     // Flash fullscreen is special in that it renders into its own separate,
205     // dedicated window.  So, do not offset the point.
206     return pt;
207   }
208   return gfx::Point(pt.x() + plugin_instance->view_data().rect.point.x,
209                     pt.y() + plugin_instance->view_data().rect.point.y);
210 }
211
212 IPC::PlatformFileForTransit RendererPpapiHostImpl::ShareHandleWithRemote(
213     base::PlatformFile handle,
214     bool should_close_source) {
215   if (!dispatcher_) {
216     DCHECK(is_running_in_process_);
217     // Duplicate the file handle for in process mode so this function
218     // has the same semantics for both in process mode and out of
219     // process mode (i.e., the remote side must cloes the handle).
220     return BrokerGetFileHandleForProcess(
221         handle, base::GetCurrentProcId(), should_close_source);
222   }
223   return dispatcher_->ShareHandleWithRemote(handle, should_close_source);
224 }
225
226 bool RendererPpapiHostImpl::IsRunningInProcess() const {
227   return is_running_in_process_;
228 }
229
230 void RendererPpapiHostImpl::CreateBrowserResourceHosts(
231     PP_Instance instance,
232     const std::vector<IPC::Message>& nested_msgs,
233     const base::Callback<void(const std::vector<int>&)>& callback) const {
234   RenderFrame* render_frame = GetRenderFrameForInstance(instance);
235   PepperBrowserConnection* browser_connection =
236       PepperBrowserConnection::Get(render_frame);
237   if (!browser_connection) {
238     base::MessageLoop::current()->PostTask(
239         FROM_HERE,
240         base::Bind(callback, std::vector<int>(nested_msgs.size(), 0)));
241   } else {
242     browser_connection->SendBrowserCreate(
243         module_->GetPluginChildId(), instance, nested_msgs, callback);
244   }
245 }
246
247 GURL RendererPpapiHostImpl::GetDocumentURL(PP_Instance instance) const {
248   PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance);
249   if (!instance_object)
250     return GURL();
251
252   return instance_object->container()->element().document().url();
253 }
254
255 PepperPluginInstanceImpl* RendererPpapiHostImpl::GetAndValidateInstance(
256     PP_Instance pp_instance) const {
257   PepperPluginInstanceImpl* instance =
258       HostGlobals::Get()->GetInstance(pp_instance);
259   if (!instance)
260     return NULL;
261   if (!instance->IsValidInstanceOf(module_))
262     return NULL;
263   return instance;
264 }
265
266 }  // namespace content