summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-05 00:41:20 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-05 00:41:20 +0000
commitdb70c13d9f08ac942e6bb839ecad2650b9101415 (patch)
treecbbb55c448cc926f95c65522ef2f452fc2586717 /ppapi
parentd129dc5c96943de51cde503eff4b86d18e05fef8 (diff)
downloadchromium_src-db70c13d9f08ac942e6bb839ecad2650b9101415.zip
chromium_src-db70c13d9f08ac942e6bb839ecad2650b9101415.tar.gz
chromium_src-db70c13d9f08ac942e6bb839ecad2650b9101415.tar.bz2
Add ability to create pending resource hosts.
Allows the host side to register a ResourceHost as pending and send an ID to the plugin, to be connected to a PluginResource at a future time. BUG= Review URL: https://chromiumcodereview.appspot.com/11414147 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171099 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/host/ppapi_host.cc33
-rw-r--r--ppapi/host/ppapi_host.h13
-rw-r--r--ppapi/host/resource_host.cc7
-rw-r--r--ppapi/host/resource_host.h15
-rw-r--r--ppapi/proxy/plugin_resource.cc14
-rw-r--r--ppapi/proxy/plugin_resource.h7
-rw-r--r--ppapi/proxy/ppapi_messages.h14
7 files changed, 102 insertions, 1 deletions
diff --git a/ppapi/host/ppapi_host.cc b/ppapi/host/ppapi_host.cc
index 436462c..6cc4db7 100644
--- a/ppapi/host/ppapi_host.cc
+++ b/ppapi/host/ppapi_host.cc
@@ -28,7 +28,8 @@ const size_t kMaxResourcesPerPlugin = 1 << 14;
PpapiHost::PpapiHost(IPC::Sender* sender,
const PpapiPermissions& perms)
: sender_(sender),
- permissions_(perms) {
+ permissions_(perms),
+ next_pending_resource_host_id_(1) {
}
PpapiHost::~PpapiHost() {
@@ -51,6 +52,8 @@ bool PpapiHost::OnMessageReceived(const IPC::Message& msg) {
OnHostMsgResourceSyncCall)
IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreated,
OnHostMsgResourceCreated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_AttachToPendingHost,
+ OnHostMsgAttachToPendingHost)
IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceDestroyed,
OnHostMsgResourceDestroyed)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -81,10 +84,21 @@ void PpapiHost::SendReply(const ReplyMessageContext& context,
void PpapiHost::SendUnsolicitedReply(PP_Resource resource,
const IPC::Message& msg) {
+ DCHECK(resource); // If this fails, host is probably pending.
proxy::ResourceMessageReplyParams params(resource, 0);
Send(new PpapiPluginMsg_ResourceReply(params, msg));
}
+int PpapiHost::AddPendingResourceHost(scoped_ptr<ResourceHost> resource_host) {
+ // The resource ID should not be assigned.
+ DCHECK(resource_host->pp_resource() == 0);
+
+ int pending_id = next_pending_resource_host_id_++;
+ pending_resource_hosts_[pending_id] =
+ linked_ptr<ResourceHost>(resource_host.release());
+ return pending_id;
+}
+
void PpapiHost::AddHostFactoryFilter(scoped_ptr<HostFactory> filter) {
host_factory_filters_.push_back(filter.release());
}
@@ -151,10 +165,27 @@ void PpapiHost::OnHostMsgResourceCreated(
return;
}
+ // Resource should have been assigned a nonzero PP_Resource.
+ DCHECK(resource_host->pp_resource());
+
resources_[params.pp_resource()] =
linked_ptr<ResourceHost>(resource_host.release());
}
+void PpapiHost::OnHostMsgAttachToPendingHost(PP_Resource pp_resource,
+ int pending_host_id) {
+ PendingHostResourceMap::iterator found =
+ pending_resource_hosts_.find(pending_host_id);
+ if (found == pending_resource_hosts_.end()) {
+ // Plugin sent a bad ID.
+ NOTREACHED();
+ return;
+ }
+ found->second->SetPPResourceForPendingHost(pp_resource);
+ resources_[pp_resource] = found->second;
+ pending_resource_hosts_.erase(found);
+}
+
void PpapiHost::OnHostMsgResourceDestroyed(PP_Resource resource) {
ResourceMap::iterator found = resources_.find(resource);
if (found == resources_.end()) {
diff --git a/ppapi/host/ppapi_host.h b/ppapi/host/ppapi_host.h
index 7210b81..c661a9b 100644
--- a/ppapi/host/ppapi_host.h
+++ b/ppapi/host/ppapi_host.h
@@ -61,6 +61,11 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
// Sends the given unsolicited reply message to the plugin.
void SendUnsolicitedReply(PP_Resource resource, const IPC::Message& msg);
+ // Adds the given host resource as a pending one (with no corresponding
+ // PluginResource object and no PP_Resource ID yet). The pending resource ID
+ // is returned. See PpapiHostMsg_AttachToPendingHost.
+ int AddPendingResourceHost(scoped_ptr<ResourceHost> resource_host);
+
// Adds the given host factory filter to the host. The PpapiHost will take
// ownership of the pointer.
void AddHostFactoryFilter(scoped_ptr<HostFactory> filter);
@@ -90,6 +95,7 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
void OnHostMsgResourceCreated(const proxy::ResourceMessageCallParams& param,
PP_Instance instance,
const IPC::Message& nested_msg);
+ void OnHostMsgAttachToPendingHost(PP_Resource resource, int pending_host_id);
void OnHostMsgResourceDestroyed(PP_Resource resource);
// Non-owning pointer.
@@ -112,6 +118,13 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
typedef std::map<PP_Resource, linked_ptr<ResourceHost> > ResourceMap;
ResourceMap resources_;
+ // Resources that have been created in the host and have not yet had the
+ // corresponding PluginResource associated with them.
+ // See PpapiHostMsg_AttachToPendingHost.
+ typedef std::map<int, linked_ptr<ResourceHost> > PendingHostResourceMap;
+ PendingHostResourceMap pending_resource_hosts_;
+ int next_pending_resource_host_id_;
+
DISALLOW_COPY_AND_ASSIGN(PpapiHost);
};
diff --git a/ppapi/host/resource_host.cc b/ppapi/host/resource_host.cc
index 4720a23..a199a97 100644
--- a/ppapi/host/resource_host.cc
+++ b/ppapi/host/resource_host.cc
@@ -4,6 +4,7 @@
#include "ppapi/host/resource_host.h"
+#include "base/logging.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/host/resource_message_filter.h"
@@ -36,6 +37,12 @@ bool ResourceHost::HandleMessage(const IPC::Message& msg,
return true;
}
+void ResourceHost::SetPPResourceForPendingHost(PP_Resource pp_resource) {
+ DCHECK(!pp_resource_);
+ pp_resource_ = pp_resource;
+ DidConnectPendingHostToResource();
+}
+
void ResourceHost::SendReply(const ReplyMessageContext& context,
const IPC::Message& msg) {
host_->SendReply(context, msg);
diff --git a/ppapi/host/resource_host.h b/ppapi/host/resource_host.h
index 763da2c..0976118 100644
--- a/ppapi/host/resource_host.h
+++ b/ppapi/host/resource_host.h
@@ -43,6 +43,14 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler {
virtual bool HandleMessage(const IPC::Message& msg,
HostMessageContext* context) OVERRIDE;
+ // Sets the PP_Resource ID when the plugin attaches to a pending resource
+ // host. This will notify subclasses by calling
+ // DidConnectPendingHostToResource.
+ //
+ // The current PP_Resource for all pending hosts should be 0. See
+ // PpapiHostMsg_AttachToPendingHost.
+ void SetPPResourceForPendingHost(PP_Resource pp_resource);
+
virtual void SendReply(const ReplyMessageContext& context,
const IPC::Message& msg) OVERRIDE;
@@ -55,6 +63,13 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler {
// ResourceHosts to easily handle messages on other threads.
void AddFilter(scoped_refptr<ResourceMessageFilter> filter);
+ // Called when this resource host is pending and the corresponding plugin has
+ // just connected to it. The host resource subclass can implement this
+ // function if it wants to do processing (typically sending queued data).
+ //
+ // The PP_Resource will be valid for this call but not before.
+ virtual void DidConnectPendingHostToResource() {}
+
private:
// The host that owns this object.
PpapiHost* host_;
diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc
index e86e090..3dd47ba 100644
--- a/ppapi/proxy/plugin_resource.cc
+++ b/ppapi/proxy/plugin_resource.cc
@@ -81,6 +81,20 @@ void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) {
new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg));
}
+void PluginResource::AttachToPendingHost(Destination dest,
+ int pending_host_id) {
+ // Connecting to a pending host is a replacement for "create".
+ if (dest == RENDERER) {
+ DCHECK(!sent_create_to_renderer_);
+ sent_create_to_renderer_ = true;
+ } else {
+ DCHECK(!sent_create_to_browser_);
+ sent_create_to_browser_ = true;
+ }
+ GetSender(dest)->Send(
+ new PpapiHostMsg_AttachToPendingHost(pp_resource(), pending_host_id));
+}
+
void PluginResource::Post(Destination dest, const IPC::Message& msg) {
ResourceMessageCallParams params(pp_resource(), GetNextSequence());
SendResourceCall(dest, params, msg);
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h
index bfd41b5..0e6d64d 100644
--- a/ppapi/proxy/plugin_resource.h
+++ b/ppapi/proxy/plugin_resource.h
@@ -62,6 +62,13 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource {
// Sends a create message to the browser or renderer for the current resource.
void SendCreate(Destination dest, const IPC::Message& msg);
+ // When the host returnes a resource to the plugin, it will create a pending
+ // ResourceHost and send an ID back to the plugin that identifies the pending
+ // object. The plugin uses this function to connect the plugin resource with
+ // the pending host resource. See also PpapiHostMsg_AttachToPendingHost. This
+ // is in lieu of sending a create message.
+ void AttachToPendingHost(Destination dest, int pending_host_id);
+
// Sends the given IPC message as a resource request to the host
// corresponding to this resource object and does not expect a reply.
void Post(Destination dest, const IPC::Message& msg);
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 271b21c..39c9bdb 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -1405,6 +1405,20 @@ IPC_MESSAGE_CONTROL3(PpapiHostMsg_ResourceCreated,
IPC_MESSAGE_CONTROL1(PpapiHostMsg_ResourceDestroyed,
PP_Resource /* resource */)
+// Most resources are created by the plugin, which then sends a ResourceCreated
+// message to create a corresponding ResourceHost in the renderer or browser
+// host process. However, some resources are first created in the host and
+// "pushed" or returned to the plugin.
+//
+// In this case, the host will create a "pending" ResourceHost object which
+// is identified by an ID. The ID is sent to the plugin process and the
+// PluginResource object is created. This message is sent from the plugin to
+// the host process to connect the PluginResource and the pending ResourceHost
+// (at which point, it's no longer pending).
+IPC_MESSAGE_CONTROL2(PpapiHostMsg_AttachToPendingHost,
+ PP_Resource /* resource */,
+ int /* pending_host_id */)
+
// A resource call is a request from the plugin to the host. It may or may not
// require a reply, depending on the params. The nested message will be
// resource-type-specific.