| Index: content/renderer/guest_to_host_channel.cc
|
| diff --git a/content/renderer/guest_to_host_channel.cc b/content/renderer/guest_to_host_channel.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5691e206ce08685b5f0beabeb8d45f8d2dac4fca
|
| --- /dev/null
|
| +++ b/content/renderer/guest_to_host_channel.cc
|
| @@ -0,0 +1,290 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/renderer/guest_to_host_channel.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/process_util.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "content/common/child_process.h"
|
| +#include "content/common/view_messages.h"
|
| +#include "content/renderer/gpu/webgraphicscontext3d_guest.h"
|
| +#include "content/renderer/guest_render_view_observer.h"
|
| +#include "content/renderer/render_thread_impl.h"
|
| +#include "gpu/command_buffer/common/buffer.h"
|
| +#include "gpu/command_buffer/common/command_buffer.h"
|
| +#include "ipc/ipc_logging.h"
|
| +#include "ppapi/c/pp_instance.h"
|
| +#include "ppapi/c/pp_bool.h"
|
| +#include "ppapi/c/pp_graphics_3d.h"
|
| +#include "ppapi/cpp/graphics_3d.h"
|
| +#include "ppapi/proxy/ppapi_command_buffer_proxy.h"
|
| +#include "ppapi/proxy/ppapi_messages.h"
|
| +#include "ppapi/proxy/serialized_var.h"
|
| +#include "ppapi/shared_impl/api_id.h"
|
| +#include "ppapi/shared_impl/host_resource.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebWidget.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):
|
| + ProxyChannel(base::GetCurrentProcessHandle()),
|
| + webview_(webview),
|
| + guest_(guest),
|
| + instance_(0),
|
| + 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, OnMsgSupportsInterface)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnMsgReserveInstanceId)
|
| + // Message handlers from ppp_instance_proxy
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate,
|
| + OnPluginMsgDidCreate)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidDestroy,
|
| + OnPluginMsgDidDestroy)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView,
|
| + OnPluginMsgDidChangeView)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus,
|
| + OnPluginMsgDidChangeFocus)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_HandleDocumentLoad,
|
| + OnPluginMsgHandleDocumentLoad)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstancePrivate_GetInstanceObject,
|
| + OnMsgGetInstanceObject)
|
| + // Message handlers from ppp_messaging_proxy
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage,
|
| + OnMsgHandleMessage)
|
| + // Message handlers from ppp_input_event_proxy
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleInputEvent,
|
| + OnMsgHandleInputEvent)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPInputEvent_HandleFilteredInputEvent,
|
| + OnMsgHandleFilteredInputEvent)
|
| + // Message handlers from ppb_graphics_3d_proxy
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
|
| + OnMsgSwapBuffersACK)
|
| + // Message handlers from ppp_graphics3d_proxy
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPGraphics3D_ContextLost,
|
| + OnMsgContextLost)
|
| + // 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) {
|
| + return ProxyChannel::Send(message);
|
| +}
|
| +
|
| +void GuestToHostChannel::OnChannelError() {
|
| + // Our host has either crashed or is telling us (rudely) to go away, so we'll
|
| + // go away.
|
| + // TODO(fsamuel): Verify all of the cleanup happens.
|
| + // This might not yet be the case.
|
| + guest_->Send(new ViewHostMsg_Close(guest_->routing_id()));
|
| +}
|
| +
|
| +WebKit::WebGraphicsContext3D* GuestToHostChannel::GetWebGraphicsContext3D() {
|
| + return context_.get();
|
| +}
|
| +
|
| +void GuestToHostChannel::IssueSwapBuffers() {
|
| + IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
|
| + ppapi::API_ID_PPB_GRAPHICS_3D, resource_);
|
| + msg->set_unblock(true);
|
| + Send(msg);
|
| +}
|
| +
|
| +bool GuestToHostChannel::BindGraphics() {
|
| + PP_Bool result = PP_FALSE;
|
| + Send(new PpapiHostMsg_PPBInstance_BindGraphics(
|
| + ppapi::API_ID_PPB_INSTANCE, instance_, resource_,
|
| + &result));
|
| + return result == PP_TRUE;
|
| +}
|
| +
|
| +bool GuestToHostChannel::InitChannel(const IPC::ChannelHandle& channel_handle) {
|
| + return ProxyChannel::InitWithChannel(&delegate_, channel_handle, false);
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgSupportsInterface(
|
| + const std::string& interface_name,
|
| + bool* result) {
|
| + // TODO(fsamuel): Does this make sense?
|
| + // We pretend that we support every interface?
|
| + *result = true;
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgSetPreferences(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::OnMsgReserveInstanceId(PP_Instance instance,
|
| + bool* usable) {
|
| + // TODO(fsamuel): Only one instance per guest, for now.
|
| + // Maybe we should DCHECK to verify this is indeed what's happening?
|
| + *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());
|
| + context_.reset(new WebGraphicsContext3DGuest(
|
| + new ppapi::proxy::PpapiCommandBufferProxy(
|
| + resource_, this), this, webview_));
|
| +
|
| + success = context_->MaybeInitializeGL();
|
| + DCHECK(success);
|
| + content::RenderThread::Get()->GetMessageLoop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&GuestRenderViewObserver::GraphicsContextCreated,
|
| + base::Unretained(guest_)));
|
| +}
|
| +
|
| +// Message handlers from ppp_instance_proxy
|
| +void GuestToHostChannel::OnPluginMsgDidCreate(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;
|
| + MessageLoop::current()->PostTask(FROM_HERE,
|
| + base::Bind(&GuestToHostChannel::RequestInputEvents,
|
| + base::Unretained(this)));
|
| + // Request a graphics context from the host renderer.
|
| + MessageLoop::current()->PostTask(FROM_HERE,
|
| + base::Bind(&GuestToHostChannel::CreateGraphicsContext,
|
| + base::Unretained(this)));
|
| + bool success = base::StringToInt(argv[2], &width_);
|
| + success |= base::StringToInt(argv[3], &height_);
|
| + DCHECK(success);
|
| + guest_->Send(new ViewHostMsg_ResizeGuest(guest_->routing_id(),
|
| + width_, height_));
|
| +
|
| +}
|
| +
|
| +void GuestToHostChannel::OnPluginMsgDidDestroy(PP_Instance instance) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void GuestToHostChannel::OnPluginMsgDidChangeView(
|
| + PP_Instance instance,
|
| + const ppapi::ViewData& new_data,
|
| + PP_Bool flash_fullscreen) {
|
| + 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 ViewHostMsg_ResizeGuest(guest_->routing_id(),
|
| + width_, height_));
|
| + }
|
| +}
|
| +
|
| +void GuestToHostChannel::OnPluginMsgDidChangeFocus(PP_Instance instance,
|
| + PP_Bool has_focus) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void GuestToHostChannel::OnPluginMsgHandleDocumentLoad(PP_Instance instance,
|
| + const ppapi::HostResource& url_loader,
|
| + PP_Bool* result) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgGetInstanceObject(
|
| + PP_Instance instance,
|
| + ppapi::proxy::SerializedVarReturnValue result) {
|
| + NOTIMPLEMENTED();
|
| + // TODO(fsamuel): We crash here during resize of the plugin
|
| + // Check failed: serialization_rules_.
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgHandleMessage(
|
| + PP_Instance instance,
|
| + ppapi::proxy::SerializedVarReceiveInput message_data) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgHandleInputEvent(
|
| + PP_Instance instance,
|
| + const ppapi::InputEventData& data) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgHandleFilteredInputEvent(
|
| + PP_Instance instance,
|
| + const ppapi::InputEventData& data,
|
| + PP_Bool* result) {
|
| + scoped_ptr<WebKit::WebInputEvent> web_input_event(
|
| + webkit::ppapi::CreateWebInputEvent(data));
|
| + if (webview_->handleInputEvent(*web_input_event))
|
| + *result = PP_TRUE;
|
| + else
|
| + *result = PP_FALSE;
|
| +}
|
| +
|
| +
|
| +void GuestToHostChannel::OnMsgSwapBuffersACK(const ppapi::HostResource& context,
|
| + int32_t pp_error) {
|
| + if (context_.get())
|
| + context_->OnSwapBuffersComplete();
|
| +}
|
| +
|
| +void GuestToHostChannel::OnMsgContextLost(PP_Instance instance) {
|
| + // Create a new graphics context
|
| + WebGraphicsContext3DGuest* old_context = context_.release();
|
| + DCHECK(old_context);
|
| + CreateGraphicsContext();
|
| +}
|
|
|