| Index: content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
|
| diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
|
| index 130245e6022e95266a6e5831463c6f68effa34e5..bd09cccd0abb288f701ec4ebdcd21225d8244475 100644
|
| --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
|
| +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
|
| @@ -12,8 +12,176 @@
|
| #include "ipc/ipc_message_macros.h"
|
| #include "ppapi/proxy/ppapi_messages.h"
|
|
|
| +// Probably for moving to other file:
|
| +#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
|
| +#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
|
| +#include "ppapi/proxy/serialized_structs.h"
|
| namespace content {
|
|
|
| +InstanceData::InstanceData(PP_Instance instance,
|
| + BrowserPpapiHostImpl* host,
|
| + IPC::Sender* renderer_sender,
|
| + PepperRendererInstanceData renderer_data)
|
| + : instance_(instance),
|
| + host_(host),
|
| + renderer_sender_(renderer_sender),
|
| + finished_creators_(0),
|
| + renderer_data_(renderer_data),
|
| + weak_ptr_factory_(this) {
|
| +}
|
| +
|
| +InstanceData::InstanceData(const InstanceData& other)
|
| + : instance_(other.instance_),
|
| + host_(other.host_),
|
| + renderer_sender_(other.renderer_sender_),
|
| + finished_creators_(other.finished_creators_),
|
| + renderer_data_(other.renderer_data_),
|
| + weak_ptr_factory_(this) {
|
| +}
|
| +
|
| +InstanceData::~InstanceData() {
|
| +}
|
| +
|
| +void InstanceData::CreateResourceHostsFromHost(
|
| + int routing_id,
|
| + const ppapi::proxy::ResourceMessageCallParams& params,
|
| + const std::vector<IPC::Message>& nested_msgs) {
|
| + PendingHostCreator* creator = new PendingHostCreator(
|
| + routing_id, params.sequence(), nested_msgs.size());
|
| + DCHECK_EQ(0u, host_creator_map_.count(params.sequence()));
|
| + host_creator_map_.add(params.sequence(), make_scoped_ptr(creator));
|
| + for (size_t i = 0; i < nested_msgs.size(); ++i) {
|
| + const IPC::Message& nested_msg = nested_msgs[i];
|
| + scoped_ptr<ppapi::host::ResourceHost> resource_host;
|
| + if (host_->IsValidInstance(instance_)) {
|
| + if (nested_msg.type() == PpapiHostMsg_FileRef_CreateForRawFS::ID) {
|
| + // FileRef_CreateForRawFS is only permitted from the renderer. Because
|
| + // of this, we handle this message here and not in
|
| + // content_browser_pepper_host_factory.cc.
|
| + base::FilePath external_path;
|
| + if (ppapi::UnpackMessage<PpapiHostMsg_FileRef_CreateForRawFS>(
|
| + nested_msg, &external_path)) {
|
| + resource_host.reset(new PepperFileRefHost(
|
| + host_, instance_, params.pp_resource(), external_path));
|
| + }
|
| + } else if (nested_msg.type() ==
|
| + PpapiHostMsg_FileSystem_CreateFromRenderer::ID) {
|
| + // Similarly, FileSystem_CreateFromRenderer is only permitted from the
|
| + // renderer.
|
| + std::string root_url;
|
| + PP_FileSystemType file_system_type;
|
| + if (ppapi::UnpackMessage<PpapiHostMsg_FileSystem_CreateFromRenderer>(
|
| + nested_msg, &root_url, &file_system_type)) {
|
| + PepperFileSystemBrowserHost* browser_host =
|
| + new PepperFileSystemBrowserHost(
|
| + host_, instance_, params.pp_resource(), file_system_type);
|
| + resource_host.reset(browser_host);
|
| + // Open the file system resource host. This is an asynchronous
|
| + // operation, and we must only add the pending resource host and
|
| + // send the message once it completes.
|
| + browser_host->OpenExisting(
|
| + GURL(root_url),
|
| + base::Bind(&InstanceData::AddPendingResourceHost,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + creator,
|
| + params.sequence(),
|
| + i,
|
| + base::Passed(&resource_host)));
|
| + // Do not fall through; the fall-through case adds the pending
|
| + // resource host to the list. We must do this asynchronously.
|
| + continue;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (!resource_host) {
|
| + resource_host = host_->GetPpapiHost()->CreateResourceHost(
|
| + params, instance_, nested_msg);
|
| + }
|
| +
|
| + if (resource_host.get()) {
|
| + AddPendingResourceHost(
|
| + creator, params.sequence(), i, resource_host.Pass());
|
| + }
|
| + }
|
| +
|
| + if (creator->finished()) {
|
| + ++finished_creators_;
|
| + SendCompletedResourceHosts(*creator);
|
| + SendSyncReplyIfNecessary();
|
| + }
|
| +}
|
| +
|
| +void InstanceData::GetAllPendingResourceHosts(
|
| + scoped_ptr<IPC::Message> reply_msg) {
|
| + reply_for_sync_request_ = reply_msg.Pass();
|
| + SendSyncReplyIfNecessary();
|
| +}
|
| +
|
| +void InstanceData::RendererDidReceiveHosts(int sequence) {
|
| + HostCreatorMap::iterator iter = host_creator_map_.find(sequence);
|
| + DCHECK(iter != host_creator_map_.end());
|
| + DCHECK(iter->second->finished());
|
| + host_creator_map_.erase(iter);
|
| + DCHECK_GT(finished_creators_, 0u);
|
| + --finished_creators_;
|
| +}
|
| +
|
| +void InstanceData::SendCompletedResourceHosts(
|
| + const PendingHostCreator& creator) {
|
| + // If we're building up a reply to a sync message, we don't need to send an
|
| + // async completion message. Just wait until we can send the reply for all
|
| + // pending creation requests.
|
| + if (!reply_for_sync_request_) {
|
| + renderer_sender_->Send(new PpapiHostMsg_CreateResourceHostsFromHostReply(
|
| + creator.routing_id(),
|
| + ppapi::proxy::CompletedBrowserResourceHosts(creator.sequence_id(),
|
| + creator.host_ids())));
|
| + }
|
| +}
|
| +
|
| +void InstanceData::SendSyncReplyIfNecessary() {
|
| + if (host_creator_map_.size() == finished_creators_ &&
|
| + reply_for_sync_request_) {
|
| + // We're servicing a synchronous request for host creation, and we just
|
| + // finished the last asynchronous conversion. Now we can package up the
|
| + // message and send it.
|
| + std::vector<ppapi::proxy::CompletedBrowserResourceHosts> completed_hosts;
|
| + for (auto& creator_pair : host_creator_map_) {
|
| + completed_hosts.push_back(ppapi::proxy::CompletedBrowserResourceHosts());
|
| + completed_hosts.back().sequence_id = creator_pair.second->sequence_id();
|
| + // We're going to clear host_creator_map_ anyway, so take the vector
|
| + // destructively to avoid a copy.
|
| + creator_pair.second->TakePendingResourceHostIdsAndReset(
|
| + &completed_hosts.back().host_ids);
|
| + }
|
| + PpapiHostMsg_GetAllPendingResourceHosts::WriteReplyParams(
|
| + reply_for_sync_request_.get(),
|
| + completed_hosts);
|
| + renderer_sender_->Send(reply_for_sync_request_.release());
|
| + // We don't need to wait for an Ack for these; the renderer is blocked and
|
| + // will get these created hosts before it can make any more synchronous
|
| + // requests to us.
|
| + host_creator_map_.clear();
|
| + finished_creators_ = 0;
|
| + }
|
| +}
|
| +
|
| +void InstanceData::AddPendingResourceHost(
|
| + PendingHostCreator* creator,
|
| + int sequence,
|
| + size_t index,
|
| + scoped_ptr<ppapi::host::ResourceHost> host) {
|
| + int resource_host_id =
|
| + host_->GetPpapiHost()->AddPendingResourceHost(host.Pass());
|
| + creator->AddPendingResourceHost(index, resource_host_id);
|
| + if (creator->finished()) {
|
| + ++finished_creators_;
|
| + SendCompletedResourceHosts(*creator);
|
| + SendSyncReplyIfNecessary();
|
| + }
|
| +}
|
| +
|
| // static
|
| BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess(
|
| IPC::Sender* sender,
|
| @@ -85,7 +253,7 @@ base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const {
|
| }
|
|
|
| bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
|
| - return instance_map_.find(instance) != instance_map_.end();
|
| + return (instance_map_.find(instance) != instance_map_.end());
|
| }
|
|
|
| bool BrowserPpapiHostImpl::GetRenderFrameIDsForInstance(
|
| @@ -99,8 +267,8 @@ bool BrowserPpapiHostImpl::GetRenderFrameIDsForInstance(
|
| return false;
|
| }
|
|
|
| - *render_process_id = found->second.render_process_id;
|
| - *render_frame_id = found->second.render_frame_id;
|
| + *render_process_id = found->second.renderer_data().render_process_id;
|
| + *render_frame_id = found->second.renderer_data().render_frame_id;
|
| return true;
|
| }
|
|
|
| @@ -120,14 +288,14 @@ GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) {
|
| InstanceMap::const_iterator found = instance_map_.find(instance);
|
| if (found == instance_map_.end())
|
| return GURL();
|
| - return found->second.document_url;
|
| + return found->second.renderer_data().document_url;
|
| }
|
|
|
| GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) {
|
| InstanceMap::const_iterator found = instance_map_.find(instance);
|
| if (found == instance_map_.end())
|
| return GURL();
|
| - return found->second.plugin_url;
|
| + return found->second.renderer_data().plugin_url;
|
| }
|
|
|
| void BrowserPpapiHostImpl::SetOnKeepaliveCallback(
|
| @@ -137,9 +305,12 @@ void BrowserPpapiHostImpl::SetOnKeepaliveCallback(
|
|
|
| void BrowserPpapiHostImpl::AddInstance(
|
| PP_Instance instance,
|
| - const PepperRendererInstanceData& instance_data) {
|
| + const PepperRendererInstanceData& instance_data,
|
| + IPC::Sender* renderer_sender) {
|
| DCHECK(instance_map_.find(instance) == instance_map_.end());
|
| - instance_map_[instance] = instance_data;
|
| + instance_map_.insert(InstanceMap::value_type(
|
| + instance,
|
| + InstanceData(instance, this, renderer_sender, instance_data)));
|
| }
|
|
|
| void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) {
|
| @@ -151,11 +322,67 @@ void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) {
|
| instance_map_.erase(found);
|
| }
|
|
|
| +PendingHostCreator::PendingHostCreator(int routing_id,
|
| + int sequence_id,
|
| + size_t nested_msgs_size)
|
| + : routing_id_(routing_id),
|
| + sequence_id_(sequence_id),
|
| + host_ids_(nested_msgs_size, 0),
|
| + completed_so_far_(0) {
|
| +}
|
| +
|
| +PendingHostCreator::~PendingHostCreator() {
|
| +}
|
| +
|
| +void PendingHostCreator::AddPendingResourceHost(size_t index, int host_id) {
|
| + DCHECK(!finished());
|
| + host_ids_[index] = host_id;
|
| + ++completed_so_far_;
|
| +}
|
| +
|
| +void PendingHostCreator::TakePendingResourceHostIdsAndReset(
|
| + std::vector<int>* host_ids) {
|
| + DCHECK(finished());
|
| + host_ids->swap(host_ids_);
|
| + completed_so_far_ = 0;
|
| +}
|
| +
|
| +void BrowserPpapiHostImpl::CreateResourceHostsFromHost(
|
| + int routing_id,
|
| + const ppapi::proxy::ResourceMessageCallParams& params,
|
| + PP_Instance instance,
|
| + const std::vector<IPC::Message>& nested_msgs) {
|
| + InstanceMap::iterator iter = instance_map_.find(instance);
|
| + if (iter == instance_map_.end())
|
| + return;
|
| + iter->second.CreateResourceHostsFromHost(
|
| + routing_id, params, nested_msgs);
|
| +}
|
| +
|
| +bool BrowserPpapiHostImpl::GetAllPendingResourceHosts(
|
| + PP_Instance instance,
|
| + scoped_ptr<IPC::Message> reply_message) {
|
| + InstanceMap::iterator iter = instance_map_.find(instance);
|
| + if (iter == instance_map_.end())
|
| + return false;
|
| + iter->second.GetAllPendingResourceHosts(reply_message.Pass());
|
| + return true;
|
| +}
|
| +
|
| +void BrowserPpapiHostImpl::RendererDidReceiveHosts(PP_Instance instance,
|
| + int sequence_num) {
|
| + InstanceMap::iterator iter = instance_map_.find(instance);
|
| + if (iter == instance_map_.end())
|
| + return;
|
| + iter->second.RendererDidReceiveHosts(sequence_num);
|
| +}
|
| +
|
| BrowserPpapiHostImpl::HostMessageFilter::HostMessageFilter(
|
| ppapi::host::PpapiHost* ppapi_host,
|
| BrowserPpapiHostImpl* browser_ppapi_host_impl)
|
| : ppapi_host_(ppapi_host),
|
| - browser_ppapi_host_impl_(browser_ppapi_host_impl) {}
|
| + browser_ppapi_host_impl_(browser_ppapi_host_impl) {
|
| +}
|
|
|
| bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived(
|
| const IPC::Message& msg) {
|
| @@ -209,9 +436,10 @@ void BrowserPpapiHostImpl::OnKeepalive() {
|
| InstanceMap::iterator instance = instance_map_.begin();
|
| int i = 0;
|
| while (instance != instance_map_.end()) {
|
| - instance_data[i].render_process_id = instance->second.render_process_id;
|
| - instance_data[i].render_frame_id = instance->second.render_frame_id;
|
| - instance_data[i].document_url = instance->second.document_url;
|
| + const PepperRendererInstanceData& data = instance->second.renderer_data();
|
| + instance_data[i].render_process_id = data.render_process_id;
|
| + instance_data[i].render_frame_id = data.render_frame_id;
|
| + instance_data[i].document_url = data.document_url;
|
| ++instance;
|
| ++i;
|
| }
|
|
|