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

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

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

Powered by Google App Engine
This is Rietveld 408576698