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