Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: content/renderer/browser_plugin/guest_to_embedder_channel.cc

Issue 9968097: Browser Plugin: Renderer-side changes (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Updated after merging with ToT Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Use of this source code is governed by a BSD-style license that can be
2 // found in the LICENSE file.
3
4 #include "content/renderer/browser_plugin/guest_to_embedder_channel.h"
5
6 #include "base/process_util.h"
7 #include "content/common/browser_plugin_messages.h"
8 #include "content/common/child_process.h"
9 #include "content/renderer/browser_plugin/browser_plugin_var_serialization_rules .h"
10 #include "content/renderer/render_thread_impl.h"
11 #include "content/renderer/render_view_impl.h"
12 #include "ipc/ipc_message_macros.h"
jam 2012/05/16 02:22:40 nit: not needed
Fady Samuel 2012/05/16 04:43:54 Done.
13 #include "ppapi/c/pp_bool.h"
14 #include "ppapi/c/pp_graphics_3d.h"
15 #include "ppapi/proxy/ppapi_command_buffer_proxy.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/shared_impl/api_id.h"
18 #include "ppapi/shared_impl/ppapi_globals.h"
19 #include "ppapi/shared_impl/var.h"
20 #include "webkit/plugins/ppapi/event_conversion.h"
21
22 namespace content {
23
24 GuestToEmbedderChannel::GuestToEmbedderChannel(
25 const std::string& embedder_channel_name)
26 : Dispatcher(NULL),
27 embedder_channel_name_(embedder_channel_name) {
28 SetSerializationRules(new BrowserPluginVarSerializationRules());
29 }
30
31 bool GuestToEmbedderChannel::OnMessageReceived(const IPC::Message& message) {
32 bool handled = true;
33 bool msg_is_ok = true;
34 IPC_BEGIN_MESSAGE_MAP_EX(GuestToEmbedderChannel, message, msg_is_ok)
35 IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnSupportsInterface)
36 IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnSetPreferences)
37 IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnReserveInstanceId)
38 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate,
39 OnDidCreate)
40 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidDestroy,
41 OnDidDestroy)
42 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView,
43 OnDidChangeView)
44 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus,
45 OnDidChangeFocus)
46 IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage,
47 OnHandleMessage)
48 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent,
49 OnHandleFilteredInputEvent)
50 IPC_MESSAGE_HANDLER(PpapiMsg_PPPGraphics3D_ContextLost,
51 OnContextLost)
52 // Have the super handle all other messages.
53 IPC_MESSAGE_UNHANDLED(handled = false)
54 IPC_END_MESSAGE_MAP_EX()
55
56 if (!msg_is_ok) {
57 // The message had a handler, but its deserialization failed.
58 // Kill the renderer to avoid potential spoofing attacks.
59 CHECK(false) << "Unable to deserialize message in ProxyChannel.";
jam 2012/05/16 02:22:40 you're in an untrusted process getting IPCs from a
Fady Samuel 2012/05/16 04:43:54 This is a copy-and-paste remnant. Removing. This
60 }
61 return handled;
62 }
63
64 bool GuestToEmbedderChannel::Send(IPC::Message* message) {
65 // We always want guest->host messages to arrive in-order. If some sync
66 // and some async messages are sent in response to a synchronous
67 // host->guest call, the sync reply will be processed before the async
68 // reply, and everything will be confused.
69 //
70 // Allowing all async messages to unblock the renderer means more reentrancy
71 // there but gives correct ordering.
72 message->set_unblock(true);
73 return ProxyChannel::Send(message);
74 }
75
76 void GuestToEmbedderChannel::OnChannelError() {
77 // We cannot destroy the GuestToEmbedderChannel here because a
78 // PpapiCommandBufferProxy may still refer to this object.
79 // However, we should not be using this channel again once we get a
80 // channel error so when remove it from the channel manager.
81 RenderThreadImpl::current()->browser_plugin_channel_manager()->
82 RemoveChannelByName(embedder_channel_name_);
83 }
84
85 bool GuestToEmbedderChannel::IsPlugin() const {
86 return true;
87 }
88
89 WebGraphicsContext3DCommandBufferImpl*
90 GuestToEmbedderChannel::CreateWebGraphicsContext3D(
91 RenderViewImpl* render_view,
92 const WebKit::WebGraphicsContext3D::Attributes& attributes,
93 bool offscreen) {
94 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
95 new WebGraphicsContext3DCommandBufferImpl(
96 0, GURL(), NULL,
97 render_view->AsWeakPtr()));
98
99 // Special case: RenderView initialization has not yet completed.
100 if (!render_view->pp_instance())
101 return context.release();
102
103 if (CreateGraphicsContext(context.get(),
104 attributes,
105 offscreen,
106 render_view))
107 return context.release();
108
109 return NULL;
110 }
111
112 void GuestToEmbedderChannel::IssueSwapBuffers(
113 const ppapi::HostResource& resource) {
114 Send(new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
115 ppapi::API_ID_PPB_GRAPHICS_3D, resource));
116 }
117
118 bool GuestToEmbedderChannel::InitChannel(
119 const IPC::ChannelHandle& channel_handle) {
120 return ProxyChannel::InitWithChannel(&delegate_, channel_handle, false);
121 }
122
123 void GuestToEmbedderChannel::OnSupportsInterface(
124 const std::string& interface_name,
125 bool* result) {
126 // TODO: This is a hack to avoid getting GetInstanceObject messages
127 // and failing a CHECK. A more correct solution is to implement
128 // VarSerializationRules for GuestToEmbedderChannel.
129 *result = interface_name.find("PPP_Instance_Private") == std::string::npos;
130 }
131
132 void GuestToEmbedderChannel::OnSetPreferences(const ppapi::Preferences& prefs) {
133 // TODO(fsamuel): Do we care about these preferences?
134 // These look like some font stuff from WebPreferences.
135 // Perhaps this should be plumbed into our associated RenderView?
136 NOTIMPLEMENTED();
137 }
138
139 void GuestToEmbedderChannel::OnReserveInstanceId(PP_Instance instance,
140 bool* usable) {
141 *usable =
142 render_view_instances_.find(instance) == render_view_instances_.end();
143 }
144
145 void GuestToEmbedderChannel::RequestInputEvents(PP_Instance instance) {
146 // Request receipt of input events
147 Send(new PpapiHostMsg_PPBInstance_RequestInputEvents(
148 ppapi::API_ID_PPB_INSTANCE, instance, true,
149 PP_INPUTEVENT_CLASS_MOUSE |
150 PP_INPUTEVENT_CLASS_KEYBOARD |
151 PP_INPUTEVENT_CLASS_WHEEL |
152 PP_INPUTEVENT_CLASS_TOUCH));
153 }
154
155 bool GuestToEmbedderChannel::CreateGraphicsContext(
156 WebGraphicsContext3DCommandBufferImpl* context,
157 const WebKit::WebGraphicsContext3D::Attributes& attributes,
158 bool offscreen,
159 RenderViewImpl* render_view) {
160 std::vector<int32_t> attribs;
161 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
162
163 ppapi::HostResource resource;
164 DCHECK(render_view->pp_instance());
165 // TODO(fsamuel): Support child contexts.
166 bool success = Send(new PpapiHostMsg_PPBGraphics3D_Create(
167 ppapi::API_ID_PPB_GRAPHICS_3D,
168 render_view->pp_instance(),
169 attribs,
170 &resource));
171 if (!success || resource.is_null())
172 return false;
173 if (!offscreen) {
174 PP_Bool result = PP_FALSE;
175 Send(new PpapiHostMsg_PPBInstance_BindGraphics(
176 ppapi::API_ID_PPB_INSTANCE,
177 render_view->pp_instance(),
178 resource,
179 &result));
180 if (result != PP_TRUE)
181 return false;
182 }
183
184 CommandBufferProxy* command_buffer =
185 new ppapi::proxy::PpapiCommandBufferProxy(resource, this);
186 command_buffer->Initialize();
187 context->InitializeWithCommandBuffer(
188 command_buffer,
189 attributes,
190 false /* bind generates resources */);
191 render_view->set_host_resource(resource);
192 return true;
193 }
194
195 void GuestToEmbedderChannel::AddGuest(
196 PP_Instance instance,
197 RenderViewImpl* render_view) {
198 DCHECK(instance);
199 DCHECK(render_view_instances_.find(instance) == render_view_instances_.end());
200 render_view_instances_[instance] = render_view->AsWeakPtr();
201 }
202
203
204 void GuestToEmbedderChannel::RemoveGuest(PP_Instance instance) {
205 DCHECK(render_view_instances_.find(instance) != render_view_instances_.end());
206 render_view_instances_.erase(instance);
207 }
208
209 void GuestToEmbedderChannel::OnDidCreate(PP_Instance instance,
210 const std::vector<std::string>& argn,
211 const std::vector<std::string>& argv,
212 PP_Bool* result) {
213 *result = PP_TRUE;
214 }
215
216 void GuestToEmbedderChannel::OnDidDestroy(PP_Instance instance) {
217 RemoveGuest(instance);
218 }
219
220 void GuestToEmbedderChannel::OnDidChangeView(
221 PP_Instance instance,
222 const ppapi::ViewData& new_data,
223 PP_Bool flash_fullscreen) {
224 // We can't do anything with this message if we don't have a render view
225 // yet. If we do have a RenderView then we need to tell the associated
226 // WebContentsObserver to resize.
227 if (render_view_instances_.find(instance) != render_view_instances_.end()) {
228 RenderViewImpl* render_view = render_view_instances_[instance];
229 render_view->Send(
230 new BrowserPluginHostMsg_ResizeGuest(
231 render_view->GetRoutingID(),
232 new_data.rect.size.width,
233 new_data.rect.size.height));
234 }
235 }
236
237 void GuestToEmbedderChannel::OnDidChangeFocus(PP_Instance instance,
238 PP_Bool has_focus) {
239 NOTIMPLEMENTED();
240 }
241
242 void GuestToEmbedderChannel::OnHandleMessage(
243 PP_Instance instance,
244 ppapi::proxy::SerializedVarReceiveInput message_data) {
245 InstanceMap::iterator it = render_view_instances_.find(instance);
246 if (it == render_view_instances_.end())
247 return;
248
249 PP_Var received_var(message_data.Get(this));
250 DCHECK(received_var.type == PP_VARTYPE_STRING);
251 ppapi::VarTracker* tracker = ppapi::PpapiGlobals::Get()->GetVarTracker();
252 ppapi::StringVar* var = tracker->GetVar(received_var)->AsStringVar();
253 DCHECK(var);
254
255 RenderViewImpl* render_view = it->second;
256 render_view->Send(
257 new BrowserPluginHostMsg_NavigateFromGuest(
258 render_view->GetRoutingID(),
259 instance,
260 var->value()));
261 }
262
263 void GuestToEmbedderChannel::OnHandleFilteredInputEvent(
264 PP_Instance instance,
265 const ppapi::InputEventData& data,
266 PP_Bool* result) {
267 DCHECK(render_view_instances_.find(instance) != render_view_instances_.end());
268
269 RenderViewImpl* render_view = render_view_instances_[instance];
270 scoped_ptr<WebKit::WebInputEvent> web_input_event(
271 webkit::ppapi::CreateWebInputEvent(data));
272 *result = PP_FromBool(
273 render_view->GetWebView()->handleInputEvent(*web_input_event));
274 }
275
276 void GuestToEmbedderChannel::OnContextLost(PP_Instance instance) {
277 InstanceMap::iterator it = render_view_instances_.begin();
278 for (InstanceMap::iterator it = render_view_instances_.begin();
279 it != render_view_instances_.end(); ++it) {
280 it->second->GetWebView()->loseCompositorContext(1);
281 }
282 }
283
284 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698