Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Unified Diff: content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc

Issue 605593002: PPAPI: Support sending browser-hosted resources synchronously Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix content_browsertests Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}

Powered by Google App Engine
This is Rietveld 408576698