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

Unified Diff: content/renderer/browser_plugin/guest_to_embedder_channel.cc

Issue 9609008: Implemented Browser Plugin (NOT FOR REVIEW) (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Updated according to creis@'s comments Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/browser_plugin/guest_to_embedder_channel.cc
diff --git a/content/renderer/browser_plugin/guest_to_embedder_channel.cc b/content/renderer/browser_plugin/guest_to_embedder_channel.cc
new file mode 100644
index 0000000000000000000000000000000000000000..95008c9920c45b0450ef59dd0fbb95ee1806978b
--- /dev/null
+++ b/content/renderer/browser_plugin/guest_to_embedder_channel.cc
@@ -0,0 +1,276 @@
+// 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_embedder_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/browser_plugin_channel_manager.h"
+#include "content/renderer/browser_plugin/browser_plugin_var_serialization_rules.h"
+#include "content/renderer/render_thread_impl.h"
+#include "content/renderer/render_view_impl.h"
+#include "ppapi/c/pp_bool.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 "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var.h"
+#include "webkit/plugins/ppapi/event_conversion.h"
+
+namespace content {
+
+GuestToEmbedderChannel::GuestToEmbedderChannel(
+ const std::string& embedder_channel_name)
+ : Dispatcher(NULL),
+ embedder_channel_name_(embedder_channel_name) {
+ SetSerializationRules(new BrowserPluginVarSerializationRules());
+}
+
+bool GuestToEmbedderChannel::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(GuestToEmbedderChannel, message)
+ 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_DidDestroy,
+ OnDidDestroy)
+ 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()
+
+ return handled;
+}
+
+bool GuestToEmbedderChannel::Send(IPC::Message* message) {
+ // We always want guest->host messages to arrive in-order. If some sync
+ // and some async messages are sent in response to a synchronous
+ // host->guest call, the sync reply will be processed before the async
+ // reply, and everything will be confused.
+ //
+ // Allowing all async messages to unblock the renderer means more reentrancy
+ // there but gives correct ordering.
+ message->set_unblock(true);
+ return ProxyChannel::Send(message);
+}
+
+void GuestToEmbedderChannel::OnChannelError() {
+ // We cannot destroy the GuestToEmbedderChannel here because a
+ // PpapiCommandBufferProxy may still refer to this object.
+ // However, we should not be using this channel again once we get a
+ // channel error so we remove it from the channel manager.
+ RenderThreadImpl::current()->browser_plugin_channel_manager()->
+ RemoveChannelByName(embedder_channel_name_);
+}
+
+bool GuestToEmbedderChannel::IsPlugin() const {
+ return true;
+}
+
+WebGraphicsContext3DCommandBufferImpl*
+ GuestToEmbedderChannel::CreateWebGraphicsContext3D(
+ RenderViewImpl* render_view,
+ const WebKit::WebGraphicsContext3D::Attributes& attributes,
+ bool offscreen) {
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
+ new WebGraphicsContext3DCommandBufferImpl(
+ 0, GURL(), NULL,
+ render_view->AsWeakPtr()));
+
+ // Special case: RenderView initialization has not yet completed.
+ if (!render_view->guest_pp_instance())
+ return context.release();
+
+ if (CreateGraphicsContext(context.get(),
+ attributes,
+ offscreen,
+ render_view))
+ return context.release();
+
+ return NULL;
+}
+
+void GuestToEmbedderChannel::IssueSwapBuffers(
+ const ppapi::HostResource& resource) {
+ Send(new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
+ ppapi::API_ID_PPB_GRAPHICS_3D, resource));
+}
+
+bool GuestToEmbedderChannel::InitChannel(
+ const IPC::ChannelHandle& channel_handle) {
+ return ProxyChannel::InitWithChannel(&delegate_, channel_handle, false);
+}
+
+void GuestToEmbedderChannel::OnSupportsInterface(
+ const std::string& interface_name,
+ bool* result) {
+ // TODO(fsamuel): This is a hack to avoid getting GetInstanceObject messages
+ // and failing a CHECK. A more correct solution is to implement
+ // VarSerializationRules for GuestToEmbedderChannel.
+ *result = interface_name.find("PPP_Instance_Private") == std::string::npos;
+}
+
+void GuestToEmbedderChannel::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 GuestToEmbedderChannel::OnReserveInstanceId(PP_Instance instance,
+ bool* usable) {
+ *usable =
+ render_view_instances_.find(instance) == render_view_instances_.end();
+}
+
+void GuestToEmbedderChannel::RequestInputEvents(PP_Instance instance) {
+ // 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));
+}
+
+bool GuestToEmbedderChannel::CreateGraphicsContext(
+ WebGraphicsContext3DCommandBufferImpl* context,
+ const WebKit::WebGraphicsContext3D::Attributes& attributes,
+ bool offscreen,
+ RenderViewImpl* render_view) {
+ std::vector<int32_t> attribs;
+ attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
+
+ ppapi::HostResource resource;
+ DCHECK(render_view->guest_pp_instance());
+ // TODO(fsamuel): Support child contexts.
+ bool success = Send(new PpapiHostMsg_PPBGraphics3D_Create(
+ ppapi::API_ID_PPB_GRAPHICS_3D,
+ render_view->guest_pp_instance(),
+ attribs,
+ &resource));
+ if (!success || resource.is_null())
+ return false;
+ if (!offscreen) {
+ PP_Bool result = PP_FALSE;
+ Send(new PpapiHostMsg_PPBInstance_BindGraphics(
+ ppapi::API_ID_PPB_INSTANCE,
+ render_view->guest_pp_instance(),
+ resource,
+ &result));
+ if (result != PP_TRUE)
+ return false;
+ }
+
+ CommandBufferProxy* command_buffer =
+ new ppapi::proxy::PpapiCommandBufferProxy(resource, this);
+ command_buffer->Initialize();
+ context->InitializeWithCommandBuffer(
+ command_buffer,
+ attributes,
+ false /* bind generates resources */);
+ render_view->set_guest_graphics_resource(resource);
+ return true;
+}
+
+void GuestToEmbedderChannel::AddGuest(
+ PP_Instance instance,
+ RenderViewImpl* render_view) {
+ DCHECK(instance);
+ DCHECK(render_view_instances_.find(instance) == render_view_instances_.end());
+ render_view_instances_[instance] = render_view->AsWeakPtr();
+}
+
+
+void GuestToEmbedderChannel::RemoveGuest(PP_Instance instance) {
+ DCHECK(render_view_instances_.find(instance) != render_view_instances_.end());
+ render_view_instances_.erase(instance);
+}
+
+void GuestToEmbedderChannel::OnDidCreate(PP_Instance instance,
+ const std::vector<std::string>& argn,
+ const std::vector<std::string>& argv,
+ PP_Bool* result) {
+ *result = PP_TRUE;
+}
+
+void GuestToEmbedderChannel::OnDidDestroy(PP_Instance instance) {
+ RemoveGuest(instance);
+}
+
+void GuestToEmbedderChannel::OnDidChangeView(
+ PP_Instance instance,
+ const ppapi::ViewData& new_data,
+ PP_Bool flash_fullscreen) {
+ // We can't do anything with this message if we don't have a render view
+ // yet. If we do have a RenderView then we need to tell the associated
+ // WebContentsObserver to resize.
+ if (render_view_instances_.find(instance) != render_view_instances_.end()) {
+ RenderViewImpl* render_view = render_view_instances_[instance];
+ render_view->Send(
+ new BrowserPluginHostMsg_ResizeGuest(
+ render_view->GetRoutingID(),
+ new_data.rect.size.width,
+ new_data.rect.size.height));
+ }
+}
+
+void GuestToEmbedderChannel::OnDidChangeFocus(PP_Instance instance,
+ PP_Bool has_focus) {
+ NOTIMPLEMENTED();
+}
+
+void GuestToEmbedderChannel::OnHandleMessage(
+ PP_Instance instance,
+ ppapi::proxy::SerializedVarReceiveInput message_data) {
+ InstanceMap::iterator it = render_view_instances_.find(instance);
+ if (it == render_view_instances_.end())
+ return;
+
+ PP_Var received_var(message_data.Get(this));
+ DCHECK(received_var.type == PP_VARTYPE_STRING);
+ ppapi::VarTracker* tracker = ppapi::PpapiGlobals::Get()->GetVarTracker();
+ ppapi::StringVar* var = tracker->GetVar(received_var)->AsStringVar();
+ DCHECK(var);
+
+ RenderViewImpl* render_view = it->second;
+ render_view->Send(
+ new BrowserPluginHostMsg_NavigateFromGuest(
+ render_view->GetRoutingID(),
+ instance,
+ var->value()));
+}
+
+void GuestToEmbedderChannel::OnHandleFilteredInputEvent(
+ PP_Instance instance,
+ const ppapi::InputEventData& data,
+ PP_Bool* result) {
+ DCHECK(render_view_instances_.find(instance) != render_view_instances_.end());
+
+ RenderViewImpl* render_view = render_view_instances_[instance];
+ scoped_ptr<WebKit::WebInputEvent> web_input_event(
+ webkit::ppapi::CreateWebInputEvent(data));
+ *result = PP_FromBool(
+ render_view->GetWebView()->handleInputEvent(*web_input_event));
+}
+
+void GuestToEmbedderChannel::OnContextLost(PP_Instance instance) {
+ DCHECK(render_view_instances_.find(instance) != render_view_instances_.end());
+ RenderViewImpl* render_view = render_view_instances_[instance];
+ render_view->GetWebView()->loseCompositorContext(1);
+}
+
+} // namespace content
« no previous file with comments | « content/renderer/browser_plugin/guest_to_embedder_channel.h ('k') | content/renderer/pepper/pepper_plugin_delegate_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698