Commit db70c13d authored by brettw@chromium.org's avatar brettw@chromium.org

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
parent d129dc5c
......@@ -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()) {
......
......@@ -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);
};
......
......@@ -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);
......
......@@ -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_;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment