summaryrefslogtreecommitdiff
path: root/chromium/ppapi/proxy/ppp_instance_proxy.cc
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/ppapi/proxy/ppp_instance_proxy.cc
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/ppapi/proxy/ppp_instance_proxy.cc')
-rw-r--r--chromium/ppapi/proxy/ppp_instance_proxy.cc256
1 files changed, 256 insertions, 0 deletions
diff --git a/chromium/ppapi/proxy/ppp_instance_proxy.cc b/chromium/ppapi/proxy/ppp_instance_proxy.cc
new file mode 100644
index 00000000000..a7a0699508b
--- /dev/null
+++ b/chromium/ppapi/proxy/ppp_instance_proxy.cc
@@ -0,0 +1,256 @@
+// 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 "ppapi/proxy/ppp_instance_proxy.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/c/ppb_fullscreen.h"
+#include "ppapi/c/ppp_instance.h"
+#include "ppapi/proxy/host_dispatcher.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_globals.h"
+#include "ppapi/proxy/plugin_proxy_delegate.h"
+#include "ppapi/proxy/plugin_resource_tracker.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/url_loader_resource.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/ppb_view_shared.h"
+#include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/scoped_pp_resource.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_flash_fullscreen_api.h"
+#include "ppapi/thunk/ppb_view_api.h"
+
+namespace ppapi {
+namespace proxy {
+
+using thunk::EnterInstanceAPINoLock;
+using thunk::EnterInstanceNoLock;
+using thunk::EnterResourceNoLock;
+using thunk::PPB_Flash_Fullscreen_API;
+using thunk::PPB_Instance_API;
+using thunk::PPB_View_API;
+
+namespace {
+
+#if !defined(OS_NACL)
+PP_Bool DidCreate(PP_Instance instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ std::vector<std::string> argn_vect;
+ std::vector<std::string> argv_vect;
+ for (uint32_t i = 0; i < argc; i++) {
+ argn_vect.push_back(std::string(argn[i]));
+ argv_vect.push_back(std::string(argv[i]));
+ }
+
+ PP_Bool result = PP_FALSE;
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidCreate(API_ID_PPP_INSTANCE, instance,
+ argn_vect, argv_vect, &result));
+ return result;
+}
+
+void DidDestroy(PP_Instance instance) {
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidDestroy(API_ID_PPP_INSTANCE, instance));
+}
+
+void DidChangeView(PP_Instance instance, PP_Resource view_resource) {
+ HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
+
+ EnterResourceNoLock<PPB_View_API> enter_view(view_resource, false);
+ if (enter_view.failed()) {
+ NOTREACHED();
+ return;
+ }
+
+ PP_Bool flash_fullscreen = PP_FALSE;
+ EnterInstanceNoLock enter_instance(instance);
+ if (!enter_instance.failed())
+ flash_fullscreen = enter_instance.functions()->FlashIsFullscreen(instance);
+ dispatcher->Send(new PpapiMsg_PPPInstance_DidChangeView(
+ API_ID_PPP_INSTANCE, instance, enter_view.object()->GetData(),
+ flash_fullscreen));
+}
+
+void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidChangeFocus(API_ID_PPP_INSTANCE,
+ instance, has_focus));
+}
+
+PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) {
+ // This should never get called. Out-of-process document loads are handled
+ // specially.
+ NOTREACHED();
+ return PP_FALSE;
+}
+
+static const PPP_Instance_1_1 instance_interface = {
+ &DidCreate,
+ &DidDestroy,
+ &DidChangeView,
+ &DidChangeFocus,
+ &HandleDocumentLoad
+};
+#endif // !defined(OS_NACL)
+
+} // namespace
+
+PPP_Instance_Proxy::PPP_Instance_Proxy(Dispatcher* dispatcher)
+ : InterfaceProxy(dispatcher) {
+ if (dispatcher->IsPlugin()) {
+ // The PPP_Instance proxy works by always proxying the 1.1 version of the
+ // interface, and then detecting in the plugin process which one to use.
+ // PPP_Instance_Combined handles dispatching to whatever interface is
+ // supported.
+ //
+ // This means that if the plugin supports either 1.0 or 1.1 version of
+ // the interface, we want to say it supports the 1.1 version since we'll
+ // convert it here. This magic conversion code is hardcoded into
+ // PluginDispatcher::OnMsgSupportsInterface.
+ combined_interface_.reset(PPP_Instance_Combined::Create(
+ base::Bind(dispatcher->local_get_interface())));
+ }
+}
+
+PPP_Instance_Proxy::~PPP_Instance_Proxy() {
+}
+
+#if !defined(OS_NACL)
+// static
+const PPP_Instance* PPP_Instance_Proxy::GetInstanceInterface() {
+ return &instance_interface;
+}
+#endif // !defined(OS_NACL)
+
+bool PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ if (!dispatcher()->IsPlugin())
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PPP_Instance_Proxy, msg)
+ 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_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PPP_Instance_Proxy::OnPluginMsgDidCreate(
+ PP_Instance instance,
+ const std::vector<std::string>& argn,
+ const std::vector<std::string>& argv,
+ PP_Bool* result) {
+ *result = PP_FALSE;
+ if (argn.size() != argv.size())
+ return;
+
+ // Set up the routing associating this new instance with the dispatcher we
+ // just got the message from. This must be done before calling into the
+ // plugin so it can in turn call PPAPI functions.
+ PluginDispatcher* plugin_dispatcher =
+ static_cast<PluginDispatcher*>(dispatcher());
+ plugin_dispatcher->DidCreateInstance(instance);
+ PpapiGlobals::Get()->GetResourceTracker()->DidCreateInstance(instance);
+
+ // Make sure the arrays always have at least one element so we can take the
+ // address below.
+ std::vector<const char*> argn_array(
+ std::max(static_cast<size_t>(1), argn.size()));
+ std::vector<const char*> argv_array(
+ std::max(static_cast<size_t>(1), argn.size()));
+ for (size_t i = 0; i < argn.size(); i++) {
+ argn_array[i] = argn[i].c_str();
+ argv_array[i] = argv[i].c_str();
+ }
+
+ DCHECK(combined_interface_.get());
+ *result = combined_interface_->DidCreate(instance,
+ static_cast<uint32_t>(argn.size()),
+ &argn_array[0], &argv_array[0]);
+}
+
+void PPP_Instance_Proxy::OnPluginMsgDidDestroy(PP_Instance instance) {
+ combined_interface_->DidDestroy(instance);
+
+ PpapiGlobals* globals = PpapiGlobals::Get();
+ globals->GetResourceTracker()->DidDeleteInstance(instance);
+ globals->GetVarTracker()->DidDeleteInstance(instance);
+
+ static_cast<PluginDispatcher*>(dispatcher())->DidDestroyInstance(instance);
+}
+
+void PPP_Instance_Proxy::OnPluginMsgDidChangeView(
+ PP_Instance instance,
+ const ViewData& new_data,
+ PP_Bool flash_fullscreen) {
+ PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
+ if (!dispatcher)
+ return;
+ InstanceData* data = dispatcher->GetInstanceData(instance);
+ if (!data)
+ return;
+ data->view = new_data;
+
+#if !defined(OS_NACL)
+ EnterInstanceAPINoLock<PPB_Flash_Fullscreen_API> enter(instance);
+ if (!enter.failed())
+ enter.functions()->SetLocalIsFullscreen(instance, flash_fullscreen);
+#endif // !defined(OS_NACL)
+
+ ScopedPPResource resource(
+ ScopedPPResource::PassRef(),
+ (new PPB_View_Shared(OBJECT_IS_PROXY,
+ instance, new_data))->GetReference());
+
+ combined_interface_->DidChangeView(instance, resource,
+ &new_data.rect,
+ &new_data.clip_rect);
+}
+
+void PPP_Instance_Proxy::OnPluginMsgDidChangeFocus(PP_Instance instance,
+ PP_Bool has_focus) {
+ combined_interface_->DidChangeFocus(instance, has_focus);
+}
+
+void PPP_Instance_Proxy::OnPluginMsgHandleDocumentLoad(
+ PP_Instance instance,
+ int pending_loader_host_id,
+ const URLResponseInfoData& data) {
+ PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
+ if (!dispatcher)
+ return;
+ Connection connection(PluginGlobals::Get()->GetBrowserSender(),
+ dispatcher);
+
+ scoped_refptr<URLLoaderResource> loader_resource(
+ new URLLoaderResource(connection, instance,
+ pending_loader_host_id, data));
+
+ PP_Resource loader_pp_resource = loader_resource->GetReference();
+ if (!combined_interface_->HandleDocumentLoad(instance, loader_pp_resource))
+ loader_resource->Close();
+ // We don't pass a ref into the plugin, if it wants one, it will have taken
+ // an additional one.
+ PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
+ loader_pp_resource);
+}
+
+} // namespace proxy
+} // namespace ppapi