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_host_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/guest_render_view_observer.h" | |
10 #include "content/renderer/render_thread_impl.h" | |
11 #include "content/renderer/render_view_impl.h" | |
12 #include "ipc/ipc_message_macros.h" | |
13 #include "ppapi/c/pp_graphics_3d.h" | |
14 #include "ppapi/proxy/ppapi_command_buffer_proxy.h" | |
15 #include "ppapi/proxy/ppapi_messages.h" | |
16 #include "ppapi/shared_impl/api_id.h" | |
17 #include "webkit/plugins/ppapi/event_conversion.h" | |
18 | |
19 base::MessageLoopProxy* | |
20 GuestToHostChannel::ProxyChannelDelegateImpl::GetIPCMessageLoop() { | |
21 DCHECK(ChildProcess::current()) << "Must be in the renderer."; | |
22 return ChildProcess::current()->io_message_loop_proxy(); | |
23 } | |
24 | |
25 base::WaitableEvent* | |
26 GuestToHostChannel::ProxyChannelDelegateImpl::GetShutdownEvent() { | |
27 DCHECK(ChildProcess::current()) << "Must be in the renderer."; | |
28 return ChildProcess::current()->GetShutDownEvent(); | |
29 } | |
30 | |
31 GuestToHostChannel::GuestToHostChannel(GuestRenderViewObserver* guest, | |
32 WebKit::WebView* webview): | |
jam
2012/04/06 21:05:23
per the style guide, this should be
: ProxyCha
Fady Samuel
2012/04/06 22:46:32
Done.
| |
33 ProxyChannel(base::GetCurrentProcessHandle()), | |
34 webview_(webview), | |
35 guest_(guest), | |
36 instance_(0), | |
37 context_(NULL), | |
38 width_(0), | |
39 height_(0) { | |
40 } | |
41 | |
42 bool GuestToHostChannel::OnMessageReceived(const IPC::Message& message) { | |
43 bool handled = true; | |
44 bool msg_is_ok = true; | |
45 IPC_BEGIN_MESSAGE_MAP_EX(GuestToHostChannel, message, msg_is_ok) | |
46 IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnSupportsInterface) | |
47 IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnSetPreferences) | |
48 IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnReserveInstanceId) | |
49 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate, | |
50 OnDidCreate) | |
51 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView, | |
52 OnDidChangeView) | |
53 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus, | |
54 OnDidChangeFocus) | |
55 IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage, | |
56 OnHandleMessage) | |
57 IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent, | |
58 OnHandleFilteredInputEvent) | |
59 IPC_MESSAGE_HANDLER(PpapiMsg_PPPGraphics3D_ContextLost, | |
60 OnContextLost) | |
61 // Have the super handle all other messages. | |
62 IPC_MESSAGE_UNHANDLED(handled = false) | |
63 IPC_END_MESSAGE_MAP() | |
64 | |
65 if (!msg_is_ok) { | |
66 // The message had a handler, but its deserialization failed. | |
67 // Kill the renderer to avoid potential spoofing attacks. | |
68 CHECK(false) << "Unable to deserialize message in ProxyChannel."; | |
69 } | |
70 return handled; | |
71 } | |
72 | |
73 bool GuestToHostChannel::Send(IPC::Message* message) { | |
74 message->set_unblock(true); | |
jam
2012/04/06 21:05:23
are you sure you need this?
Fady Samuel
2012/04/06 22:46:32
Yes, I believe so. Lots of weird things failing if
piman
2012/04/06 23:19:26
Actually, yes. We need pepper->renderer messages t
Fady Samuel
2012/04/11 22:06:34
Done.
| |
75 return ProxyChannel::Send(message); | |
76 } | |
77 | |
78 void GuestToHostChannel::OnChannelError() { | |
79 // Cleanup should happen in BrowserPluginWebContentsObserver now. | |
80 } | |
81 | |
82 WebGraphicsContext3DCommandBufferImpl* | |
83 GuestToHostChannel::GetWebGraphicsContext3D( | |
jam
2012/04/06 21:05:23
nit: the convention is when you have to put the fu
Fady Samuel
2012/04/06 22:46:32
Done.
| |
84 const WebKit::WebGraphicsContext3D::Attributes& attributes) { | |
85 attributes_ = attributes; | |
86 context_= new WebGraphicsContext3DCommandBufferImpl( | |
piman
2012/04/06 23:19:26
As mentioned in my comment in render_view_impl.cc,
Fady Samuel
2012/04/11 22:06:34
Done. This required some significant refactoring h
| |
87 0, GURL(), NULL, | |
88 static_cast<RenderViewImpl*>(guest_->render_view())->AsWeakPtr()); | |
89 return context_; | |
90 } | |
91 | |
92 void GuestToHostChannel::IssueSwapBuffers() { | |
93 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers( | |
94 ppapi::API_ID_PPB_GRAPHICS_3D, resource_); | |
95 Send(msg); | |
jam
2012/04/06 21:05:23
nit: just Send(new Papi...)
Fady Samuel
2012/04/06 22:46:32
Done.
| |
96 } | |
97 | |
98 bool GuestToHostChannel::InitChannel(const IPC::ChannelHandle& channel_handle) { | |
99 return ProxyChannel::InitWithChannel(&delegate_, channel_handle, false); | |
100 } | |
101 | |
102 void GuestToHostChannel::OnSupportsInterface( | |
103 const std::string& interface_name, | |
104 bool* result) { | |
105 | |
106 // TODO: This is a hack to avoid getting GetInstanceObject messages | |
107 // and failing a CHECK. A more correct solution is to implement | |
108 // VarSerializationRules for GuestToHostChannel. | |
109 if (interface_name.find("PPP_Instance_Private") != std::string::npos) | |
piman
2012/04/06 23:19:26
*result = !(interface_name.find("PPP_Instance_Priv
Fady Samuel
2012/04/11 22:06:34
Fixed. I do mention this above. This is currently
| |
110 *result = false; | |
111 else | |
112 *result = true; | |
113 } | |
114 | |
115 void GuestToHostChannel::OnSetPreferences(const ppapi::Preferences& prefs) { | |
116 // TODO(fsamuel): Do we care about these preferences? | |
117 // These look like some font stuff from WebPreferences. | |
118 // Perhaps this should be plumbed into our associated RenderView? | |
119 NOTIMPLEMENTED(); | |
120 } | |
121 | |
122 void GuestToHostChannel::OnReserveInstanceId(PP_Instance instance, | |
123 bool* usable) { | |
124 // TODO(fsamuel): Only one instance per guest, for now. | |
125 // If we wish to support "live thumbnails" of guests this may | |
126 // change in the future. | |
127 DCHECK(!instance_); | |
128 *usable = true; | |
129 } | |
130 | |
131 void GuestToHostChannel::RequestInputEvents() { | |
132 // Request receipt of input events | |
133 Send(new PpapiHostMsg_PPBInstance_RequestInputEvents( | |
134 ppapi::API_ID_PPB_INSTANCE, instance_, true, | |
135 PP_INPUTEVENT_CLASS_MOUSE | | |
136 PP_INPUTEVENT_CLASS_KEYBOARD | | |
137 PP_INPUTEVENT_CLASS_WHEEL | | |
138 PP_INPUTEVENT_CLASS_TOUCH)); | |
139 } | |
140 | |
141 void GuestToHostChannel::CreateGraphicsContext() { | |
142 std::vector<int32_t> attribs; | |
143 attribs.push_back(PP_GRAPHICS3DATTRIB_WIDTH); | |
144 attribs.push_back(webview_->size().width); | |
145 attribs.push_back(PP_GRAPHICS3DATTRIB_HEIGHT); | |
146 attribs.push_back(webview_->size().height); | |
147 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); | |
148 | |
149 // Reset the HostResource if it's already set. | |
150 resource_ = ppapi::HostResource(); | |
151 bool success = Send(new PpapiHostMsg_PPBGraphics3D_Create( | |
152 ppapi::API_ID_PPB_GRAPHICS_3D, instance_, attribs, &resource_)); | |
153 DCHECK(success && !resource_.is_null()); | |
piman
2012/04/06 23:19:26
You won't get a resource if accelerated compositin
Fady Samuel
2012/04/11 22:06:34
Done.
| |
154 PP_Bool result = PP_FALSE; | |
155 Send(new PpapiHostMsg_PPBInstance_BindGraphics( | |
156 ppapi::API_ID_PPB_INSTANCE, instance_, resource_, | |
157 &result)); | |
158 DCHECK(result == PP_TRUE); | |
159 | |
160 CommandBufferProxy* command_buffer = | |
161 new ppapi::proxy::PpapiCommandBufferProxy(resource_, this); | |
162 command_buffer->Initialize(); | |
163 context_->InitializeWithCommandBuffer( | |
164 command_buffer, | |
jam
2012/04/06 21:05:23
nit: here and below, this is odd indentation
Fady Samuel
2012/04/06 22:46:32
Done.
| |
165 attributes_, | |
166 false /* bind generates resources */); | |
167 | |
168 content::RenderThread::Get()->GetMessageLoop()->PostTask( | |
169 FROM_HERE, | |
170 base::Bind(&RenderViewImpl::OnGuestReady, | |
171 base::Unretained( | |
piman
2012/04/06 23:19:26
Unretained? What guarantees that the lifetime of t
Fady Samuel
2012/04/11 22:06:34
Done.
| |
172 static_cast<RenderViewImpl*>(guest_->render_view())))); | |
piman
2012/04/06 23:19:26
again, scary static_cast...
Fady Samuel
2012/04/11 22:06:34
Done.
| |
173 } | |
174 | |
175 // Message handlers from ppp_instance_proxy | |
jam
2012/04/06 21:05:23
nit: this comment is redundant (see the style guid
Fady Samuel
2012/04/06 22:46:32
Done.
| |
176 void GuestToHostChannel::OnDidCreate(PP_Instance instance, | |
177 const std::vector<std::string>& argn, | |
178 const std::vector<std::string>& argv, | |
179 PP_Bool* result) { | |
180 // Creation is always successful if we've gotten this far. | |
181 *result = PP_TRUE; | |
182 // Request input events from the host renderer after we reply to this message. | |
183 instance_ = instance; | |
184 // Request input events from the host renderer. | |
jam
2012/04/06 21:05:23
ditto and below (comments shouldn't describe what
Fady Samuel
2012/04/06 22:46:32
Done.
| |
185 RequestInputEvents(); | |
186 // Request a graphics context from the host renderer. | |
187 CreateGraphicsContext(); | |
piman
2012/04/06 23:19:26
Do you need to create now?
In particular, at this
Fady Samuel
2012/04/11 22:06:34
Done.
| |
188 } | |
189 | |
190 void GuestToHostChannel::OnDidChangeView( | |
191 PP_Instance instance, | |
192 const ppapi::ViewData& new_data, | |
193 PP_Bool flash_fullscreen) { | |
194 // If size has changed, let the browser process know. | |
jam
2012/04/06 21:05:23
ditto
Fady Samuel
2012/04/06 22:46:32
Done.
| |
195 if (new_data.rect.size.width != width_ || | |
196 new_data.rect.size.height != height_) { | |
197 width_ = new_data.rect.size.width; | |
198 height_ = new_data.rect.size.height; | |
199 guest_->Send( | |
200 new BrowserPluginHostMsg_ResizeGuest(guest_->routing_id(), | |
201 width_, height_)); | |
piman
2012/04/06 23:19:26
I'm a bit confused about the entire architecture,
Fady Samuel
2012/04/11 22:06:34
I'm worried about the implications of the browser
| |
202 } | |
203 } | |
204 | |
205 void GuestToHostChannel::OnDidChangeFocus(PP_Instance instance, | |
206 PP_Bool has_focus) { | |
207 NOTIMPLEMENTED(); | |
208 } | |
209 | |
210 void GuestToHostChannel::OnHandleMessage( | |
211 PP_Instance instance, | |
212 ppapi::proxy::SerializedVarReceiveInput message_data) { | |
213 // TODO(fsamuel): API messages to the browser plugin should probably | |
214 // be handled here. | |
215 NOTIMPLEMENTED(); | |
216 } | |
217 | |
218 void GuestToHostChannel::OnHandleFilteredInputEvent( | |
219 PP_Instance instance, | |
220 const ppapi::InputEventData& data, | |
221 PP_Bool* result) { | |
222 // We only support one instance per channel at this point in time. | |
223 DCHECK(instance == instance_); | |
224 scoped_ptr<WebKit::WebInputEvent> web_input_event( | |
225 webkit::ppapi::CreateWebInputEvent(data)); | |
226 if (webview_->handleInputEvent(*web_input_event)) | |
227 *result = PP_TRUE; | |
piman
2012/04/06 23:19:26
Use PP_FromBool (in ppapi/c/pp_bool.h)?
Fady Samuel
2012/04/11 22:06:34
Done.
| |
228 else | |
229 *result = PP_FALSE; | |
230 } | |
231 | |
232 void GuestToHostChannel::OnContextLost(PP_Instance instance) { | |
233 DCHECK(instance == instance_); | |
234 ppapi::proxy::PpapiCommandBufferProxy* command_buffer = | |
235 static_cast<ppapi::proxy::PpapiCommandBufferProxy*>( | |
236 context_->GetCommandBufferProxy()); | |
237 DCHECK(command_buffer); | |
jam
2012/04/06 21:05:23
nit this isn't useful. in release builds it does n
Fady Samuel
2012/04/06 22:46:32
Done.
piman
2012/04/06 23:19:26
Actually, I disagree with that. If ReportChannelEr
Fady Samuel
2012/04/11 22:06:34
Done.
| |
238 context_= GetWebGraphicsContext3D(attributes_); | |
239 command_buffer->ReportChannelError(); | |
240 | |
241 // Create a new graphics context | |
jam
2012/04/06 21:05:23
ditto
Fady Samuel
2012/04/06 22:46:32
Done.
| |
242 CreateGraphicsContext(); | |
243 } | |
OLD | NEW |