summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-30 05:26:52 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-30 05:26:52 +0000
commit4dec5802baac225df48fb9153d2af7621d5850e6 (patch)
treecc52ebc1c7171654b9bdbc6b394fa2c8df1ff059 /ppapi
parent250c074059ca38cbc7474d3332ba3edcf8e86e65 (diff)
downloadchromium_src-4dec5802baac225df48fb9153d2af7621d5850e6.zip
chromium_src-4dec5802baac225df48fb9153d2af7621d5850e6.tar.gz
chromium_src-4dec5802baac225df48fb9153d2af7621d5850e6.tar.bz2
Create a PPAPI host for new resource message routing.
This infrastructure will be used in the renderer and in the browser as the backing for new resources. The PpapiHost object doues the routing for the resource messages, and also has hooks for the embedder (the renderer or the browser) to create resources. This adds a content_renderer factory which currently does nothing (we'll add most of the resources here). BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10572040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145059 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/host/host_factory.h43
-rw-r--r--ppapi/host/host_message_context.h35
-rw-r--r--ppapi/host/ppapi_host.cc126
-rw-r--r--ppapi/host/ppapi_host.h78
-rw-r--r--ppapi/host/ppapi_host_export.h30
-rw-r--r--ppapi/host/resource_host.cc29
-rw-r--r--ppapi/host/resource_host.h66
-rw-r--r--ppapi/ppapi_host.gypi32
-rw-r--r--ppapi/ppapi_internal.gyp1
-rw-r--r--ppapi/proxy/dispatcher.cc4
-rw-r--r--ppapi/proxy/dispatcher.h5
-rw-r--r--ppapi/shared_impl/resource.cc6
-rw-r--r--ppapi/shared_impl/resource.h20
13 files changed, 475 insertions, 0 deletions
diff --git a/ppapi/host/host_factory.h b/ppapi/host/host_factory.h
new file mode 100644
index 0000000..d4b8ea7
--- /dev/null
+++ b/ppapi/host/host_factory.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef PPAPI_HOST_HOST_FACTORY_H_
+#define PPAPI_HOST_HOST_FACTORY_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "ppapi/c/pp_instance.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace ppapi {
+
+namespace proxy {
+class ResourceMessageCallParams;
+}
+
+namespace host {
+
+class PpapiHost;
+class ResourceHost;
+
+// A host factory creates ResourceHosts for incoming create messages from
+// the plugin. This allows us to implement the hosts at the chrome/content
+// layer without the ppapi layer knowing about the details.
+class HostFactory {
+ public:
+ virtual ~HostFactory() {}
+
+ virtual scoped_ptr<ResourceHost> CreateResourceHost(
+ PpapiHost* host,
+ const proxy::ResourceMessageCallParams& params,
+ PP_Instance instance,
+ const IPC::Message& message) = 0;
+};
+
+} // namespace host
+} // namespace ppapi
+
+#endif // PPAPI_HOST_HOST_FACTORY_H_
diff --git a/ppapi/host/host_message_context.h b/ppapi/host/host_message_context.h
new file mode 100644
index 0000000..6e0b70a
--- /dev/null
+++ b/ppapi/host/host_message_context.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef PPAPI_COMMON_HOST_MESSAGE_CONTEXT_H_
+#define PPAPI_COMMON_HOST_MESSAGE_CONTEXT_H_
+
+#include "ipc/ipc_message.h"
+#include "ppapi/host/ppapi_host_export.h"
+#include "ppapi/proxy/resource_message_params.h"
+
+namespace ppapi {
+namespace host {
+
+// This context structure provides information about incoming resource message
+// call requests when passed to resources.
+struct PPAPI_HOST_EXPORT HostMessageContext {
+ explicit HostMessageContext(const ppapi::proxy::ResourceMessageCallParams& cp)
+ : params(cp) {
+ }
+
+ // The original call parameters passed to the resource message call.
+ const ppapi::proxy::ResourceMessageCallParams& params;
+
+ // The reply message. If the params has the callback flag set, this message
+ // will be sent in reply. It is initialized to the empty message. If the
+ // handler wants to send something else, it should just assign the message
+ // it wants to this value.
+ IPC::Message reply_msg;
+};
+
+} // namespace host
+} // namespace ppapi
+
+#endif // PPAPI_COMMON_HOST_MESSAGE_CONTEXT_H_
diff --git a/ppapi/host/ppapi_host.cc b/ppapi/host/ppapi_host.cc
new file mode 100644
index 0000000..038f4e7
--- /dev/null
+++ b/ppapi/host/ppapi_host.cc
@@ -0,0 +1,126 @@
+// 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/host/ppapi_host.h"
+
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/host_factory.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/shared_impl/host_resource.h"
+
+namespace ppapi {
+namespace host {
+
+namespace {
+
+// Put a cap on the maximum number of resources so we don't explode if the
+// renderer starts spamming us.
+const size_t kMaxResourcesPerPlugin = 1 << 14;
+
+} // namespace
+
+PpapiHost::PpapiHost(IPC::Sender* sender, HostFactory* host_factory)
+ : sender_(sender),
+ host_factory_(host_factory) {
+}
+
+PpapiHost::~PpapiHost() {
+}
+
+bool PpapiHost::Send(IPC::Message* msg) {
+ return sender_->Send(msg);
+}
+
+bool PpapiHost::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PpapiHost, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCall,
+ OnHostMsgResourceCall)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreated,
+ OnHostMsgResourceCreated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceDestroyed,
+ OnHostMsgResourceDestroyed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PpapiHost::SendReply(const proxy::ResourceMessageReplyParams& params,
+ const IPC::Message& msg) {
+ Send(new PpapiPluginMsg_ResourceReply(params, msg));
+}
+
+void PpapiHost::OnHostMsgResourceCall(
+ const proxy::ResourceMessageCallParams& params,
+ const IPC::Message& nested_msg) {
+ HostMessageContext context(params);
+ proxy::ResourceMessageReplyParams reply_params(params.pp_resource(),
+ params.sequence());
+
+ ResourceHost* resource_host = GetResourceHost(params.pp_resource());
+ if (resource_host) {
+ reply_params.set_result(resource_host->OnResourceMessageReceived(
+ nested_msg, &context));
+
+ // Sanity check the resource handler.
+ if (reply_params.result() == PP_OK_COMPLETIONPENDING) {
+ // Message handler should have only returned a pending result if a
+ // response will be sent to the plugin.
+ DCHECK(params.has_callback());
+
+ // Message handler should not have written a message to be returned if
+ // completion is pending.
+ DCHECK(context.reply_msg.type() == 0);
+ } else if (!params.has_callback()) {
+ // When no response is required, the message handler should not have
+ // written a message to be returned.
+ DCHECK(context.reply_msg.type() == 0);
+ }
+ } else {
+ reply_params.set_result(PP_ERROR_BADRESOURCE);
+ }
+
+ if (params.has_callback() && reply_params.result() != PP_OK_COMPLETIONPENDING)
+ SendReply(reply_params, context.reply_msg);
+}
+
+void PpapiHost::OnHostMsgResourceCreated(
+ const proxy::ResourceMessageCallParams& params,
+ PP_Instance instance,
+ const IPC::Message& nested_msg) {
+ if (resources_.size() >= kMaxResourcesPerPlugin)
+ return;
+
+ scoped_ptr<ResourceHost> resource_host(
+ host_factory_->CreateResourceHost(this, params, instance,
+ nested_msg));
+ if (!resource_host.get()) {
+ NOTREACHED();
+ return;
+ }
+
+ resources_[params.pp_resource()] =
+ linked_ptr<ResourceHost>(resource_host.release());
+}
+
+void PpapiHost::OnHostMsgResourceDestroyed(PP_Resource resource) {
+ ResourceMap::iterator found = resources_.find(resource);
+ if (found == resources_.end()) {
+ NOTREACHED();
+ return;
+ }
+ resources_.erase(found);
+}
+
+ResourceHost* PpapiHost::GetResourceHost(PP_Resource resource) {
+ ResourceMap::iterator found = resources_.find(resource);
+ return found == resources_.end() ? NULL : found->second.get();
+}
+
+} // namespace host
+} // namespace ppapi
diff --git a/ppapi/host/ppapi_host.h b/ppapi/host/ppapi_host.h
new file mode 100644
index 0000000..eb195b8
--- /dev/null
+++ b/ppapi/host/ppapi_host.h
@@ -0,0 +1,78 @@
+// 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.
+
+#ifndef PPAPI_HOST_PPAPI_HOST_H_
+#define PPAPI_HOST_PPAPI_HOST_H_
+
+#include <map>
+
+#include "base/compiler_specific.h"
+#include "base/memory/linked_ptr.h"
+#include "ipc/ipc_listener.h"
+#include "ipc/ipc_sender.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/host/ppapi_host_export.h"
+
+namespace ppapi {
+
+namespace proxy {
+class ResourceMessageCallParams;
+class ResourceMessageReplyParams;
+}
+
+namespace host {
+
+class HostFactory;
+class ResourceHost;
+
+// The host provides routing and tracking for resource message calls that
+// come from the plugin to the host (browser or renderer), and the
+// corresponding replies.
+class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
+ public:
+ // The sender is the channel to the plugin for outgoing messages. The factory
+ // will be used to receive resource creation messages from the plugin. Both
+ // pointers are owned by the caller and must outlive this class.
+ PpapiHost(IPC::Sender* sender, HostFactory* host_factory);
+ virtual ~PpapiHost();
+
+ // Sender implementation. Forwards to the sender_.
+ virtual bool Send(IPC::Message* msg) OVERRIDE;
+
+ // Listener implementation.
+ virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
+
+ // Sends the given reply message to the plugin.
+ void SendReply(const proxy::ResourceMessageReplyParams& params,
+ const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnHostMsgResourceCall(const proxy::ResourceMessageCallParams& params,
+ const IPC::Message& nested_msg);
+ void OnHostMsgResourceCreated(const proxy::ResourceMessageCallParams& param,
+ PP_Instance instance,
+ const IPC::Message& nested_msg);
+ void OnHostMsgResourceDestroyed(PP_Resource resource);
+
+ // Returns null if the resource doesn't exist.
+ host::ResourceHost* GetResourceHost(PP_Resource resource);
+
+ // Non-owning pointer.
+ IPC::Sender* sender_;
+
+ // Non-owning pointer.
+ HostFactory* host_factory_;
+
+ typedef std::map<PP_Resource, linked_ptr<ResourceHost> > ResourceMap;
+ ResourceMap resources_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpapiHost);
+};
+
+} // namespace host
+} // namespace ppapi
+
+#endif // PPAPI_HOST_PPAPIE_HOST_H_
diff --git a/ppapi/host/ppapi_host_export.h b/ppapi/host/ppapi_host_export.h
new file mode 100644
index 0000000..90cf2ef
--- /dev/null
+++ b/ppapi/host/ppapi_host_export.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef PPAPI_HOST_PPAPI_HOST_EXPORT_H_
+#define PPAPI_HOST_PPAPI_HOST_EXPORT_H_
+#pragma once
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(PPAPI_HOST_IMPLEMENTATION)
+#define PPAPI_HOST_EXPORT __declspec(dllexport)
+#else
+#define PPAPI_HOST_EXPORT __declspec(dllimport)
+#endif // defined(PPAPI_HOST_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(PPAPI_HOST_IMPLEMENTATION)
+#define PPAPI_HOST_EXPORT __attribute__((visibility("default")))
+#else
+#define PPAPI_HOST_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define PPAPI_HOST_EXPORT
+#endif
+
+#endif // PPAPI_HOST_PPAPI_HOST_EXPORT_H_
diff --git a/ppapi/host/resource_host.cc b/ppapi/host/resource_host.cc
new file mode 100644
index 0000000..b67be08
--- /dev/null
+++ b/ppapi/host/resource_host.cc
@@ -0,0 +1,29 @@
+// 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/host/resource_host.h"
+
+#include "ppapi/c/pp_errors.h"
+
+namespace ppapi {
+namespace host {
+
+ResourceHost::ResourceHost(PpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : host_(host),
+ pp_instance_(instance),
+ pp_resource_(resource) {
+}
+
+ResourceHost::~ResourceHost() {
+}
+
+int32_t ResourceHost::OnResourceMessageReceived(const IPC::Message& msg,
+ HostMessageContext* context) {
+ return PP_ERROR_NOTSUPPORTED;
+}
+
+} // namespace host
+} // namespace ppapi
diff --git a/ppapi/host/resource_host.h b/ppapi/host/resource_host.h
new file mode 100644
index 0000000..c1e4b74
--- /dev/null
+++ b/ppapi/host/resource_host.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef PPAPI_HOST_RESOURCE_HOST_H_
+#define PPAPI_HOST_RESOURCE_HOST_H_
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/host/ppapi_host_export.h"
+#include "ppapi/shared_impl/host_resource.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace ppapi {
+namespace host {
+
+struct HostMessageContext;
+class PpapiHost;
+
+// Some (but not all) resources have a corresponding object in the host side
+// that is kept alive as long as the resource in the plugin is alive. This is
+// the base class for such objects.
+class PPAPI_HOST_EXPORT ResourceHost {
+ public:
+ ResourceHost(PpapiHost* host, PP_Instance instance, PP_Resource resource);
+ virtual ~ResourceHost();
+
+ PpapiHost* host() { return host_; }
+ PP_Instance pp_instance() const { return pp_instance_; }
+ PP_Resource pp_resource() const { return pp_resource_; }
+
+ // Handles messages associated with a given resource object. If the flags
+ // indicate that a response is required, the return value of this function
+ // will be sent as a resource message "response" along with the message
+ // specified in the reply of the context.
+ //
+ // You can do a response asynchronously by returning PP_OK_COMPLETIONPENDING.
+ // This will cause the reply to be skipped, and the class implementing this
+ // function will take responsibility for issuing the callback later.
+ //
+ // If you don't have a particular reply message, you can just ignore
+ // the reply in the message context. However, if you have a reply more than
+ // just the int32_t result code, set the reply to be the message of your
+ // choosing.
+ //
+ // The default implementation just returns PP_ERROR_NOTSUPPORTED.
+ virtual int32_t OnResourceMessageReceived(const IPC::Message& msg,
+ HostMessageContext* context);
+
+ private:
+ // The host that owns this object.
+ PpapiHost* host_;
+
+ PP_Instance pp_instance_;
+ PP_Resource pp_resource_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResourceHost);
+};
+
+} // namespace host
+} // namespace ppapi
+
+#endif // PPAPI_HOST_RESOURCE_HOST_H_
diff --git a/ppapi/ppapi_host.gypi b/ppapi/ppapi_host.gypi
new file mode 100644
index 0000000..bc99538
--- /dev/null
+++ b/ppapi/ppapi_host.gypi
@@ -0,0 +1,32 @@
+# 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.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'ppapi_host',
+ 'type': '<(component)',
+ 'dependencies': [
+ 'ppapi.gyp:ppapi_c',
+ 'ppapi_internal.gyp:ppapi_proxy',
+ 'ppapi_internal.gyp:ppapi_shared',
+ '../base/base.gyp:base',
+ '../ipc/ipc.gyp:ipc',
+ '../ui/surface/surface.gyp:surface',
+ ],
+ 'defines': [
+ 'PPAPI_HOST_IMPLEMENTATION',
+ ],
+ 'sources': [
+ 'host/host_factory.h',
+ 'host/host_message_context.h',
+ 'host/ppapi_host.cc',
+ 'host/ppapi_host.h',
+ 'host/ppapi_host_export.h',
+ 'host/resource_host.cc',
+ 'host/resource_host.h',
+ ],
+ },
+ ],
+}
diff --git a/ppapi/ppapi_internal.gyp b/ppapi/ppapi_internal.gyp
index 4ad96e3..d4f1497 100644
--- a/ppapi/ppapi_internal.gyp
+++ b/ppapi/ppapi_internal.gyp
@@ -25,6 +25,7 @@
},
'includes': [
'ppapi_sources.gypi',
+ 'ppapi_host.gypi',
'ppapi_proxy.gypi',
'ppapi_shared.gypi',
'ppapi_tests.gypi',
diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc
index 7ecd2c1..3ef2c27 100644
--- a/ppapi/proxy/dispatcher.cc
+++ b/ppapi/proxy/dispatcher.cc
@@ -25,6 +25,10 @@ Dispatcher::Dispatcher(PP_GetInterface_Func local_get_interface)
Dispatcher::~Dispatcher() {
}
+void Dispatcher::AddFilter(IPC::Listener* listener) {
+ filters_.push_back(listener);
+}
+
InterfaceProxy* Dispatcher::GetInterfaceProxy(ApiID id) {
InterfaceProxy* proxy = proxies_[id].get();
if (!proxy) {
diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h
index 9fd2461..3bd8598 100644
--- a/ppapi/proxy/dispatcher.h
+++ b/ppapi/proxy/dispatcher.h
@@ -51,6 +51,8 @@ class PPAPI_PROXY_EXPORT Dispatcher : public ProxyChannel {
// browser side.
virtual bool IsPlugin() const = 0;
+ void AddFilter(IPC::Listener* listener);
+
VarSerializationRules* serialization_rules() const {
return serialization_rules_.get();
}
@@ -96,6 +98,9 @@ class PPAPI_PROXY_EXPORT Dispatcher : public ProxyChannel {
return disallow_trusted_interfaces_;
}
+ protected:
+ std::vector<IPC::Listener*> filters_;
+
private:
friend class HostDispatcherTest;
friend class PluginDispatcherTest;
diff --git a/ppapi/shared_impl/resource.cc b/ppapi/shared_impl/resource.cc
index b8dd315..c96bc21 100644
--- a/ppapi/shared_impl/resource.cc
+++ b/ppapi/shared_impl/resource.cc
@@ -56,6 +56,12 @@ void Resource::InstanceWasDeleted() {
host_resource_ = HostResource();
}
+void Resource::OnReplyReceived(int sequence,
+ int32_t result,
+ const IPC::Message& msg) {
+ NOTREACHED();
+}
+
void Resource::Log(PP_LogLevel_Dev level, const std::string& message) {
PpapiGlobals::Get()->LogWithSource(pp_instance(), level, std::string(),
message);
diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h
index a6857543..efe40da 100644
--- a/ppapi/shared_impl/resource.h
+++ b/ppapi/shared_impl/resource.h
@@ -65,6 +65,10 @@
F(PPB_Widget_API) \
F(PPB_X509Certificate_Private_API)
+namespace IPC {
+class Message;
+}
+
namespace ppapi {
// Forward declare all the resource APIs.
@@ -161,6 +165,22 @@ class PPAPI_SHARED_EXPORT Resource : public base::RefCounted<Resource> {
// Template-based dynamic casting. See specializations below.
template <typename T> T* GetAs() { return NULL; }
+ // Called when a PpapiPluginMsg_ResourceReply reply is received for a
+ // previous CallRenderer. The sequence number is the value returned the
+ // send function for the given request. The message is the nested reply
+ // message, which may be an empty message (depending on what the host
+ // sends).
+ //
+ // The default implementation will assert (if you send a request, you should
+ // override this function).
+ //
+ // (This function would make more conceptual sense on PluginResource but we
+ // need to call this function from general code that doesn't know how to
+ // distinguish the classes.)
+ virtual void OnReplyReceived(int sequence,
+ int32_t result,
+ const IPC::Message& msg);
+
protected:
// Logs a message to the console from this resource.
void Log(PP_LogLevel_Dev level, const std::string& message);