Chromium Code Reviews| Index: content/renderer/browser_plugin/guest_to_host_channel.cc |
| diff --git a/content/renderer/browser_plugin/guest_to_host_channel.cc b/content/renderer/browser_plugin/guest_to_host_channel.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..22e560cbbc59c8f28cc76b6beeec0d6f0c89c1b3 |
| --- /dev/null |
| +++ b/content/renderer/browser_plugin/guest_to_host_channel.cc |
| @@ -0,0 +1,243 @@ |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/renderer/browser_plugin/guest_to_host_channel.h" |
| + |
| +#include "base/process_util.h" |
| +#include "content/common/browser_plugin_messages.h" |
| +#include "content/common/child_process.h" |
| +#include "content/renderer/browser_plugin/guest_render_view_observer.h" |
| +#include "content/renderer/render_thread_impl.h" |
| +#include "content/renderer/render_view_impl.h" |
| +#include "ipc/ipc_message_macros.h" |
| +#include "ppapi/c/pp_graphics_3d.h" |
| +#include "ppapi/proxy/ppapi_command_buffer_proxy.h" |
| +#include "ppapi/proxy/ppapi_messages.h" |
| +#include "ppapi/shared_impl/api_id.h" |
| +#include "webkit/plugins/ppapi/event_conversion.h" |
| + |
| +base::MessageLoopProxy* |
| + GuestToHostChannel::ProxyChannelDelegateImpl::GetIPCMessageLoop() { |
| + DCHECK(ChildProcess::current()) << "Must be in the renderer."; |
| + return ChildProcess::current()->io_message_loop_proxy(); |
| +} |
| + |
| +base::WaitableEvent* |
| + GuestToHostChannel::ProxyChannelDelegateImpl::GetShutdownEvent() { |
| + DCHECK(ChildProcess::current()) << "Must be in the renderer."; |
| + return ChildProcess::current()->GetShutDownEvent(); |
| +} |
| + |
| +GuestToHostChannel::GuestToHostChannel(GuestRenderViewObserver* guest, |
| + 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.
|
| + ProxyChannel(base::GetCurrentProcessHandle()), |
| + webview_(webview), |
| + guest_(guest), |
| + instance_(0), |
| + context_(NULL), |
| + width_(0), |
| + height_(0) { |
| +} |
| + |
| +bool GuestToHostChannel::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = true; |
| + bool msg_is_ok = true; |
| + IPC_BEGIN_MESSAGE_MAP_EX(GuestToHostChannel, message, msg_is_ok) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnSupportsInterface) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnSetPreferences) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnReserveInstanceId) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate, |
| + OnDidCreate) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView, |
| + OnDidChangeView) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus, |
| + OnDidChangeFocus) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage, |
| + OnHandleMessage) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent, |
| + OnHandleFilteredInputEvent) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPGraphics3D_ContextLost, |
| + OnContextLost) |
| + // Have the super handle all other messages. |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + |
| + if (!msg_is_ok) { |
| + // The message had a handler, but its deserialization failed. |
| + // Kill the renderer to avoid potential spoofing attacks. |
| + CHECK(false) << "Unable to deserialize message in ProxyChannel."; |
| + } |
| + return handled; |
| +} |
| + |
| +bool GuestToHostChannel::Send(IPC::Message* message) { |
| + 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.
|
| + return ProxyChannel::Send(message); |
| +} |
| + |
| +void GuestToHostChannel::OnChannelError() { |
| + // Cleanup should happen in BrowserPluginWebContentsObserver now. |
| +} |
| + |
| +WebGraphicsContext3DCommandBufferImpl* |
| +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.
|
| + const WebKit::WebGraphicsContext3D::Attributes& attributes) { |
| + attributes_ = attributes; |
| + 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
|
| + 0, GURL(), NULL, |
| + static_cast<RenderViewImpl*>(guest_->render_view())->AsWeakPtr()); |
| + return context_; |
| +} |
| + |
| +void GuestToHostChannel::IssueSwapBuffers() { |
| + IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers( |
| + ppapi::API_ID_PPB_GRAPHICS_3D, resource_); |
| + Send(msg); |
|
jam
2012/04/06 21:05:23
nit: just Send(new Papi...)
Fady Samuel
2012/04/06 22:46:32
Done.
|
| +} |
| + |
| +bool GuestToHostChannel::InitChannel(const IPC::ChannelHandle& channel_handle) { |
| + return ProxyChannel::InitWithChannel(&delegate_, channel_handle, false); |
| +} |
| + |
| +void GuestToHostChannel::OnSupportsInterface( |
| + const std::string& interface_name, |
| + bool* result) { |
| + |
| + // TODO: This is a hack to avoid getting GetInstanceObject messages |
| + // and failing a CHECK. A more correct solution is to implement |
| + // VarSerializationRules for GuestToHostChannel. |
| + 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
|
| + *result = false; |
| + else |
| + *result = true; |
| +} |
| + |
| +void GuestToHostChannel::OnSetPreferences(const ppapi::Preferences& prefs) { |
| + // TODO(fsamuel): Do we care about these preferences? |
| + // These look like some font stuff from WebPreferences. |
| + // Perhaps this should be plumbed into our associated RenderView? |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void GuestToHostChannel::OnReserveInstanceId(PP_Instance instance, |
| + bool* usable) { |
| + // TODO(fsamuel): Only one instance per guest, for now. |
| + // If we wish to support "live thumbnails" of guests this may |
| + // change in the future. |
| + DCHECK(!instance_); |
| + *usable = true; |
| +} |
| + |
| +void GuestToHostChannel::RequestInputEvents() { |
| + // Request receipt of input events |
| + Send(new PpapiHostMsg_PPBInstance_RequestInputEvents( |
| + ppapi::API_ID_PPB_INSTANCE, instance_, true, |
| + PP_INPUTEVENT_CLASS_MOUSE | |
| + PP_INPUTEVENT_CLASS_KEYBOARD | |
| + PP_INPUTEVENT_CLASS_WHEEL | |
| + PP_INPUTEVENT_CLASS_TOUCH)); |
| +} |
| + |
| +void GuestToHostChannel::CreateGraphicsContext() { |
| + std::vector<int32_t> attribs; |
| + attribs.push_back(PP_GRAPHICS3DATTRIB_WIDTH); |
| + attribs.push_back(webview_->size().width); |
| + attribs.push_back(PP_GRAPHICS3DATTRIB_HEIGHT); |
| + attribs.push_back(webview_->size().height); |
| + attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); |
| + |
| + // Reset the HostResource if it's already set. |
| + resource_ = ppapi::HostResource(); |
| + bool success = Send(new PpapiHostMsg_PPBGraphics3D_Create( |
| + ppapi::API_ID_PPB_GRAPHICS_3D, instance_, attribs, &resource_)); |
| + 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.
|
| + PP_Bool result = PP_FALSE; |
| + Send(new PpapiHostMsg_PPBInstance_BindGraphics( |
| + ppapi::API_ID_PPB_INSTANCE, instance_, resource_, |
| + &result)); |
| + DCHECK(result == PP_TRUE); |
| + |
| + CommandBufferProxy* command_buffer = |
| + new ppapi::proxy::PpapiCommandBufferProxy(resource_, this); |
| + command_buffer->Initialize(); |
| + context_->InitializeWithCommandBuffer( |
| + 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.
|
| + attributes_, |
| + false /* bind generates resources */); |
| + |
| + content::RenderThread::Get()->GetMessageLoop()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&RenderViewImpl::OnGuestReady, |
| + 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.
|
| + 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.
|
| +} |
| + |
| +// 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.
|
| +void GuestToHostChannel::OnDidCreate(PP_Instance instance, |
| + const std::vector<std::string>& argn, |
| + const std::vector<std::string>& argv, |
| + PP_Bool* result) { |
| + // Creation is always successful if we've gotten this far. |
| + *result = PP_TRUE; |
| + // Request input events from the host renderer after we reply to this message. |
| + instance_ = instance; |
| + // 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.
|
| + RequestInputEvents(); |
| + // Request a graphics context from the host renderer. |
| + 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.
|
| +} |
| + |
| +void GuestToHostChannel::OnDidChangeView( |
| + PP_Instance instance, |
| + const ppapi::ViewData& new_data, |
| + PP_Bool flash_fullscreen) { |
| + // 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.
|
| + if (new_data.rect.size.width != width_ || |
| + new_data.rect.size.height != height_) { |
| + width_ = new_data.rect.size.width; |
| + height_ = new_data.rect.size.height; |
| + guest_->Send( |
| + new BrowserPluginHostMsg_ResizeGuest(guest_->routing_id(), |
| + 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
|
| + } |
| +} |
| + |
| +void GuestToHostChannel::OnDidChangeFocus(PP_Instance instance, |
| + PP_Bool has_focus) { |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void GuestToHostChannel::OnHandleMessage( |
| + PP_Instance instance, |
| + ppapi::proxy::SerializedVarReceiveInput message_data) { |
| + // TODO(fsamuel): API messages to the browser plugin should probably |
| + // be handled here. |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void GuestToHostChannel::OnHandleFilteredInputEvent( |
| + PP_Instance instance, |
| + const ppapi::InputEventData& data, |
| + PP_Bool* result) { |
| + // We only support one instance per channel at this point in time. |
| + DCHECK(instance == instance_); |
| + scoped_ptr<WebKit::WebInputEvent> web_input_event( |
| + webkit::ppapi::CreateWebInputEvent(data)); |
| + if (webview_->handleInputEvent(*web_input_event)) |
| + *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.
|
| + else |
| + *result = PP_FALSE; |
| +} |
| + |
| +void GuestToHostChannel::OnContextLost(PP_Instance instance) { |
| + DCHECK(instance == instance_); |
| + ppapi::proxy::PpapiCommandBufferProxy* command_buffer = |
| + static_cast<ppapi::proxy::PpapiCommandBufferProxy*>( |
| + context_->GetCommandBufferProxy()); |
| + 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.
|
| + context_= GetWebGraphicsContext3D(attributes_); |
| + command_buffer->ReportChannelError(); |
| + |
| + // Create a new graphics context |
|
jam
2012/04/06 21:05:23
ditto
Fady Samuel
2012/04/06 22:46:32
Done.
|
| + CreateGraphicsContext(); |
| +} |