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; ...@@ -28,7 +28,8 @@ const size_t kMaxResourcesPerPlugin = 1 << 14;
PpapiHost::PpapiHost(IPC::Sender* sender, PpapiHost::PpapiHost(IPC::Sender* sender,
const PpapiPermissions& perms) const PpapiPermissions& perms)
: sender_(sender), : sender_(sender),
permissions_(perms) { permissions_(perms),
next_pending_resource_host_id_(1) {
} }
PpapiHost::~PpapiHost() { PpapiHost::~PpapiHost() {
...@@ -51,6 +52,8 @@ bool PpapiHost::OnMessageReceived(const IPC::Message& msg) { ...@@ -51,6 +52,8 @@ bool PpapiHost::OnMessageReceived(const IPC::Message& msg) {
OnHostMsgResourceSyncCall) OnHostMsgResourceSyncCall)
IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreated, IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreated,
OnHostMsgResourceCreated) OnHostMsgResourceCreated)
IPC_MESSAGE_HANDLER(PpapiHostMsg_AttachToPendingHost,
OnHostMsgAttachToPendingHost)
IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceDestroyed, IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceDestroyed,
OnHostMsgResourceDestroyed) OnHostMsgResourceDestroyed)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
...@@ -81,10 +84,21 @@ void PpapiHost::SendReply(const ReplyMessageContext& context, ...@@ -81,10 +84,21 @@ void PpapiHost::SendReply(const ReplyMessageContext& context,
void PpapiHost::SendUnsolicitedReply(PP_Resource resource, void PpapiHost::SendUnsolicitedReply(PP_Resource resource,
const IPC::Message& msg) { const IPC::Message& msg) {
DCHECK(resource); // If this fails, host is probably pending.
proxy::ResourceMessageReplyParams params(resource, 0); proxy::ResourceMessageReplyParams params(resource, 0);
Send(new PpapiPluginMsg_ResourceReply(params, msg)); 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) { void PpapiHost::AddHostFactoryFilter(scoped_ptr<HostFactory> filter) {
host_factory_filters_.push_back(filter.release()); host_factory_filters_.push_back(filter.release());
} }
...@@ -151,10 +165,27 @@ void PpapiHost::OnHostMsgResourceCreated( ...@@ -151,10 +165,27 @@ void PpapiHost::OnHostMsgResourceCreated(
return; return;
} }
// Resource should have been assigned a nonzero PP_Resource.
DCHECK(resource_host->pp_resource());
resources_[params.pp_resource()] = resources_[params.pp_resource()] =
linked_ptr<ResourceHost>(resource_host.release()); 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) { void PpapiHost::OnHostMsgResourceDestroyed(PP_Resource resource) {
ResourceMap::iterator found = resources_.find(resource); ResourceMap::iterator found = resources_.find(resource);
if (found == resources_.end()) { if (found == resources_.end()) {
......
...@@ -61,6 +61,11 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener { ...@@ -61,6 +61,11 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
// Sends the given unsolicited reply message to the plugin. // Sends the given unsolicited reply message to the plugin.
void SendUnsolicitedReply(PP_Resource resource, const IPC::Message& msg); 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 // Adds the given host factory filter to the host. The PpapiHost will take
// ownership of the pointer. // ownership of the pointer.
void AddHostFactoryFilter(scoped_ptr<HostFactory> filter); void AddHostFactoryFilter(scoped_ptr<HostFactory> filter);
...@@ -90,6 +95,7 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener { ...@@ -90,6 +95,7 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
void OnHostMsgResourceCreated(const proxy::ResourceMessageCallParams& param, void OnHostMsgResourceCreated(const proxy::ResourceMessageCallParams& param,
PP_Instance instance, PP_Instance instance,
const IPC::Message& nested_msg); const IPC::Message& nested_msg);
void OnHostMsgAttachToPendingHost(PP_Resource resource, int pending_host_id);
void OnHostMsgResourceDestroyed(PP_Resource resource); void OnHostMsgResourceDestroyed(PP_Resource resource);
// Non-owning pointer. // Non-owning pointer.
...@@ -112,6 +118,13 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener { ...@@ -112,6 +118,13 @@ class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
typedef std::map<PP_Resource, linked_ptr<ResourceHost> > ResourceMap; typedef std::map<PP_Resource, linked_ptr<ResourceHost> > ResourceMap;
ResourceMap resources_; 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); DISALLOW_COPY_AND_ASSIGN(PpapiHost);
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ppapi/host/resource_host.h" #include "ppapi/host/resource_host.h"
#include "base/logging.h"
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/host/ppapi_host.h" #include "ppapi/host/ppapi_host.h"
#include "ppapi/host/resource_message_filter.h" #include "ppapi/host/resource_message_filter.h"
...@@ -36,6 +37,12 @@ bool ResourceHost::HandleMessage(const IPC::Message& msg, ...@@ -36,6 +37,12 @@ bool ResourceHost::HandleMessage(const IPC::Message& msg,
return true; return true;
} }
void ResourceHost::SetPPResourceForPendingHost(PP_Resource pp_resource) {
DCHECK(!pp_resource_);
pp_resource_ = pp_resource;
DidConnectPendingHostToResource();
}
void ResourceHost::SendReply(const ReplyMessageContext& context, void ResourceHost::SendReply(const ReplyMessageContext& context,
const IPC::Message& msg) { const IPC::Message& msg) {
host_->SendReply(context, msg); host_->SendReply(context, msg);
......
...@@ -43,6 +43,14 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler { ...@@ -43,6 +43,14 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler {
virtual bool HandleMessage(const IPC::Message& msg, virtual bool HandleMessage(const IPC::Message& msg,
HostMessageContext* context) OVERRIDE; 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, virtual void SendReply(const ReplyMessageContext& context,
const IPC::Message& msg) OVERRIDE; const IPC::Message& msg) OVERRIDE;
...@@ -55,6 +63,13 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler { ...@@ -55,6 +63,13 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler {
// ResourceHosts to easily handle messages on other threads. // ResourceHosts to easily handle messages on other threads.
void AddFilter(scoped_refptr<ResourceMessageFilter> filter); 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: private:
// The host that owns this object. // The host that owns this object.
PpapiHost* host_; PpapiHost* host_;
......
...@@ -81,6 +81,20 @@ void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) { ...@@ -81,6 +81,20 @@ void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) {
new PpapiHostMsg_ResourceCreated(params, pp_instance(), 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) { void PluginResource::Post(Destination dest, const IPC::Message& msg) {
ResourceMessageCallParams params(pp_resource(), GetNextSequence()); ResourceMessageCallParams params(pp_resource(), GetNextSequence());
SendResourceCall(dest, params, msg); SendResourceCall(dest, params, msg);
......
...@@ -62,6 +62,13 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource { ...@@ -62,6 +62,13 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource {
// Sends a create message to the browser or renderer for the current resource. // Sends a create message to the browser or renderer for the current resource.
void SendCreate(Destination dest, const IPC::Message& msg); 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 // Sends the given IPC message as a resource request to the host
// corresponding to this resource object and does not expect a reply. // corresponding to this resource object and does not expect a reply.
void Post(Destination dest, const IPC::Message& msg); void Post(Destination dest, const IPC::Message& msg);
......
...@@ -1405,6 +1405,20 @@ IPC_MESSAGE_CONTROL3(PpapiHostMsg_ResourceCreated, ...@@ -1405,6 +1405,20 @@ IPC_MESSAGE_CONTROL3(PpapiHostMsg_ResourceCreated,
IPC_MESSAGE_CONTROL1(PpapiHostMsg_ResourceDestroyed, IPC_MESSAGE_CONTROL1(PpapiHostMsg_ResourceDestroyed,
PP_Resource /* resource */) 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 // 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 // require a reply, depending on the params. The nested message will be
// resource-type-specific. // 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