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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 5 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
6 6
7 #include "base/metrics/sparse_histogram.h" 7 #include "base/metrics/sparse_histogram.h"
8 #include "content/browser/renderer_host/pepper/pepper_message_filter.h" 8 #include "content/browser/renderer_host/pepper/pepper_message_filter.h"
9 #include "content/browser/tracing/trace_message_filter.h" 9 #include "content/browser/tracing/trace_message_filter.h"
10 #include "content/common/pepper_renderer_instance_data.h" 10 #include "content/common/pepper_renderer_instance_data.h"
11 #include "content/public/common/process_type.h" 11 #include "content/public/common/process_type.h"
12 #include "ipc/ipc_message_macros.h" 12 #include "ipc/ipc_message_macros.h"
13 #include "ppapi/proxy/ppapi_messages.h" 13 #include "ppapi/proxy/ppapi_messages.h"
14 14
15 // Probably for moving to other file:
16 #include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
17 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h "
18 #include "ppapi/proxy/serialized_structs.h"
15 namespace content { 19 namespace content {
16 20
21 InstanceData::InstanceData(PP_Instance instance,
22 BrowserPpapiHostImpl* host,
23 IPC::Sender* renderer_sender,
24 PepperRendererInstanceData renderer_data)
25 : instance_(instance),
26 host_(host),
27 renderer_sender_(renderer_sender),
28 finished_creators_(0),
29 renderer_data_(renderer_data),
30 weak_ptr_factory_(this) {
31 }
32
33 InstanceData::InstanceData(const InstanceData& other)
34 : instance_(other.instance_),
35 host_(other.host_),
36 renderer_sender_(other.renderer_sender_),
37 finished_creators_(other.finished_creators_),
38 renderer_data_(other.renderer_data_),
39 weak_ptr_factory_(this) {
40 }
41
42 InstanceData::~InstanceData() {
43 }
44
45 void InstanceData::CreateResourceHostsFromHost(
46 int routing_id,
47 const ppapi::proxy::ResourceMessageCallParams& params,
48 const std::vector<IPC::Message>& nested_msgs) {
49 PendingHostCreator* creator = new PendingHostCreator(
50 routing_id, params.sequence(), nested_msgs.size());
51 DCHECK_EQ(0u, host_creator_map_.count(params.sequence()));
52 host_creator_map_.add(params.sequence(), make_scoped_ptr(creator));
53 for (size_t i = 0; i < nested_msgs.size(); ++i) {
54 const IPC::Message& nested_msg = nested_msgs[i];
55 scoped_ptr<ppapi::host::ResourceHost> resource_host;
56 if (host_->IsValidInstance(instance_)) {
57 if (nested_msg.type() == PpapiHostMsg_FileRef_CreateForRawFS::ID) {
58 // FileRef_CreateForRawFS is only permitted from the renderer. Because
59 // of this, we handle this message here and not in
60 // content_browser_pepper_host_factory.cc.
61 base::FilePath external_path;
62 if (ppapi::UnpackMessage<PpapiHostMsg_FileRef_CreateForRawFS>(
63 nested_msg, &external_path)) {
64 resource_host.reset(new PepperFileRefHost(
65 host_, instance_, params.pp_resource(), external_path));
66 }
67 } else if (nested_msg.type() ==
68 PpapiHostMsg_FileSystem_CreateFromRenderer::ID) {
69 // Similarly, FileSystem_CreateFromRenderer is only permitted from the
70 // renderer.
71 std::string root_url;
72 PP_FileSystemType file_system_type;
73 if (ppapi::UnpackMessage<PpapiHostMsg_FileSystem_CreateFromRenderer>(
74 nested_msg, &root_url, &file_system_type)) {
75 PepperFileSystemBrowserHost* browser_host =
76 new PepperFileSystemBrowserHost(
77 host_, instance_, params.pp_resource(), file_system_type);
78 resource_host.reset(browser_host);
79 // Open the file system resource host. This is an asynchronous
80 // operation, and we must only add the pending resource host and
81 // send the message once it completes.
82 browser_host->OpenExisting(
83 GURL(root_url),
84 base::Bind(&InstanceData::AddPendingResourceHost,
85 weak_ptr_factory_.GetWeakPtr(),
86 creator,
87 params.sequence(),
88 i,
89 base::Passed(&resource_host)));
90 // Do not fall through; the fall-through case adds the pending
91 // resource host to the list. We must do this asynchronously.
92 continue;
93 }
94 }
95 }
96
97 if (!resource_host) {
98 resource_host = host_->GetPpapiHost()->CreateResourceHost(
99 params, instance_, nested_msg);
100 }
101
102 if (resource_host.get()) {
103 AddPendingResourceHost(
104 creator, params.sequence(), i, resource_host.Pass());
105 }
106 }
107
108 if (creator->finished()) {
109 ++finished_creators_;
110 SendCompletedResourceHosts(*creator);
111 SendSyncReplyIfNecessary();
112 }
113 }
114
115 void InstanceData::GetAllPendingResourceHosts(
116 scoped_ptr<IPC::Message> reply_msg) {
117 reply_for_sync_request_ = reply_msg.Pass();
118 SendSyncReplyIfNecessary();
119 }
120
121 void InstanceData::RendererDidReceiveHosts(int sequence) {
122 HostCreatorMap::iterator iter = host_creator_map_.find(sequence);
123 DCHECK(iter != host_creator_map_.end());
124 DCHECK(iter->second->finished());
125 host_creator_map_.erase(iter);
126 DCHECK_GT(finished_creators_, 0u);
127 --finished_creators_;
128 }
129
130 void InstanceData::SendCompletedResourceHosts(
131 const PendingHostCreator& creator) {
132 // If we're building up a reply to a sync message, we don't need to send an
133 // async completion message. Just wait until we can send the reply for all
134 // pending creation requests.
135 if (!reply_for_sync_request_) {
136 renderer_sender_->Send(new PpapiHostMsg_CreateResourceHostsFromHostReply(
137 creator.routing_id(),
138 ppapi::proxy::CompletedBrowserResourceHosts(creator.sequence_id(),
139 creator.host_ids())));
140 }
141 }
142
143 void InstanceData::SendSyncReplyIfNecessary() {
144 if (host_creator_map_.size() == finished_creators_ &&
145 reply_for_sync_request_) {
146 // We're servicing a synchronous request for host creation, and we just
147 // finished the last asynchronous conversion. Now we can package up the
148 // message and send it.
149 std::vector<ppapi::proxy::CompletedBrowserResourceHosts> completed_hosts;
150 for (auto& creator_pair : host_creator_map_) {
151 completed_hosts.push_back(ppapi::proxy::CompletedBrowserResourceHosts());
152 completed_hosts.back().sequence_id = creator_pair.second->sequence_id();
153 // We're going to clear host_creator_map_ anyway, so take the vector
154 // destructively to avoid a copy.
155 creator_pair.second->TakePendingResourceHostIdsAndReset(
156 &completed_hosts.back().host_ids);
157 }
158 PpapiHostMsg_GetAllPendingResourceHosts::WriteReplyParams(
159 reply_for_sync_request_.get(),
160 completed_hosts);
161 renderer_sender_->Send(reply_for_sync_request_.release());
162 // We don't need to wait for an Ack for these; the renderer is blocked and
163 // will get these created hosts before it can make any more synchronous
164 // requests to us.
165 host_creator_map_.clear();
166 finished_creators_ = 0;
167 }
168 }
169
170 void InstanceData::AddPendingResourceHost(
171 PendingHostCreator* creator,
172 int sequence,
173 size_t index,
174 scoped_ptr<ppapi::host::ResourceHost> host) {
175 int resource_host_id =
176 host_->GetPpapiHost()->AddPendingResourceHost(host.Pass());
177 creator->AddPendingResourceHost(index, resource_host_id);
178 if (creator->finished()) {
179 ++finished_creators_;
180 SendCompletedResourceHosts(*creator);
181 SendSyncReplyIfNecessary();
182 }
183 }
184
17 // static 185 // static
18 BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess( 186 BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess(
19 IPC::Sender* sender, 187 IPC::Sender* sender,
20 ppapi::PpapiPermissions permissions, 188 ppapi::PpapiPermissions permissions,
21 base::ProcessHandle plugin_child_process, 189 base::ProcessHandle plugin_child_process,
22 IPC::ChannelProxy* channel, 190 IPC::ChannelProxy* channel,
23 int render_process_id, 191 int render_process_id,
24 int render_view_id, 192 int render_view_id,
25 const base::FilePath& profile_directory) { 193 const base::FilePath& profile_directory) {
26 // The plugin name and path shouldn't be needed for external plugins. 194 // The plugin name and path shouldn't be needed for external plugins.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 return ppapi_host_.get(); 246 return ppapi_host_.get();
79 } 247 }
80 248
81 base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const { 249 base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const {
82 // Handle should previously have been set before use. 250 // Handle should previously have been set before use.
83 DCHECK(in_process_ || plugin_process_handle_ != base::kNullProcessHandle); 251 DCHECK(in_process_ || plugin_process_handle_ != base::kNullProcessHandle);
84 return plugin_process_handle_; 252 return plugin_process_handle_;
85 } 253 }
86 254
87 bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const { 255 bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
88 return instance_map_.find(instance) != instance_map_.end(); 256 return (instance_map_.find(instance) != instance_map_.end());
89 } 257 }
90 258
91 bool BrowserPpapiHostImpl::GetRenderFrameIDsForInstance( 259 bool BrowserPpapiHostImpl::GetRenderFrameIDsForInstance(
92 PP_Instance instance, 260 PP_Instance instance,
93 int* render_process_id, 261 int* render_process_id,
94 int* render_frame_id) const { 262 int* render_frame_id) const {
95 InstanceMap::const_iterator found = instance_map_.find(instance); 263 InstanceMap::const_iterator found = instance_map_.find(instance);
96 if (found == instance_map_.end()) { 264 if (found == instance_map_.end()) {
97 *render_process_id = 0; 265 *render_process_id = 0;
98 *render_frame_id = 0; 266 *render_frame_id = 0;
99 return false; 267 return false;
100 } 268 }
101 269
102 *render_process_id = found->second.render_process_id; 270 *render_process_id = found->second.renderer_data().render_process_id;
103 *render_frame_id = found->second.render_frame_id; 271 *render_frame_id = found->second.renderer_data().render_frame_id;
104 return true; 272 return true;
105 } 273 }
106 274
107 const std::string& BrowserPpapiHostImpl::GetPluginName() { 275 const std::string& BrowserPpapiHostImpl::GetPluginName() {
108 return plugin_name_; 276 return plugin_name_;
109 } 277 }
110 278
111 const base::FilePath& BrowserPpapiHostImpl::GetPluginPath() { 279 const base::FilePath& BrowserPpapiHostImpl::GetPluginPath() {
112 return plugin_path_; 280 return plugin_path_;
113 } 281 }
114 282
115 const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() { 283 const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() {
116 return profile_data_directory_; 284 return profile_data_directory_;
117 } 285 }
118 286
119 GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) { 287 GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) {
120 InstanceMap::const_iterator found = instance_map_.find(instance); 288 InstanceMap::const_iterator found = instance_map_.find(instance);
121 if (found == instance_map_.end()) 289 if (found == instance_map_.end())
122 return GURL(); 290 return GURL();
123 return found->second.document_url; 291 return found->second.renderer_data().document_url;
124 } 292 }
125 293
126 GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) { 294 GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) {
127 InstanceMap::const_iterator found = instance_map_.find(instance); 295 InstanceMap::const_iterator found = instance_map_.find(instance);
128 if (found == instance_map_.end()) 296 if (found == instance_map_.end())
129 return GURL(); 297 return GURL();
130 return found->second.plugin_url; 298 return found->second.renderer_data().plugin_url;
131 } 299 }
132 300
133 void BrowserPpapiHostImpl::SetOnKeepaliveCallback( 301 void BrowserPpapiHostImpl::SetOnKeepaliveCallback(
134 const BrowserPpapiHost::OnKeepaliveCallback& callback) { 302 const BrowserPpapiHost::OnKeepaliveCallback& callback) {
135 on_keepalive_callback_ = callback; 303 on_keepalive_callback_ = callback;
136 } 304 }
137 305
138 void BrowserPpapiHostImpl::AddInstance( 306 void BrowserPpapiHostImpl::AddInstance(
139 PP_Instance instance, 307 PP_Instance instance,
140 const PepperRendererInstanceData& instance_data) { 308 const PepperRendererInstanceData& instance_data,
309 IPC::Sender* renderer_sender) {
141 DCHECK(instance_map_.find(instance) == instance_map_.end()); 310 DCHECK(instance_map_.find(instance) == instance_map_.end());
142 instance_map_[instance] = instance_data; 311 instance_map_.insert(InstanceMap::value_type(
312 instance,
313 InstanceData(instance, this, renderer_sender, instance_data)));
143 } 314 }
144 315
145 void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) { 316 void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) {
146 InstanceMap::iterator found = instance_map_.find(instance); 317 InstanceMap::iterator found = instance_map_.find(instance);
147 if (found == instance_map_.end()) { 318 if (found == instance_map_.end()) {
148 NOTREACHED(); 319 NOTREACHED();
149 return; 320 return;
150 } 321 }
151 instance_map_.erase(found); 322 instance_map_.erase(found);
152 } 323 }
153 324
325 PendingHostCreator::PendingHostCreator(int routing_id,
326 int sequence_id,
327 size_t nested_msgs_size)
328 : routing_id_(routing_id),
329 sequence_id_(sequence_id),
330 host_ids_(nested_msgs_size, 0),
331 completed_so_far_(0) {
332 }
333
334 PendingHostCreator::~PendingHostCreator() {
335 }
336
337 void PendingHostCreator::AddPendingResourceHost(size_t index, int host_id) {
338 DCHECK(!finished());
339 host_ids_[index] = host_id;
340 ++completed_so_far_;
341 }
342
343 void PendingHostCreator::TakePendingResourceHostIdsAndReset(
344 std::vector<int>* host_ids) {
345 DCHECK(finished());
346 host_ids->swap(host_ids_);
347 completed_so_far_ = 0;
348 }
349
350 void BrowserPpapiHostImpl::CreateResourceHostsFromHost(
351 int routing_id,
352 const ppapi::proxy::ResourceMessageCallParams& params,
353 PP_Instance instance,
354 const std::vector<IPC::Message>& nested_msgs) {
355 InstanceMap::iterator iter = instance_map_.find(instance);
356 if (iter == instance_map_.end())
357 return;
358 iter->second.CreateResourceHostsFromHost(
359 routing_id, params, nested_msgs);
360 }
361
362 bool BrowserPpapiHostImpl::GetAllPendingResourceHosts(
363 PP_Instance instance,
364 scoped_ptr<IPC::Message> reply_message) {
365 InstanceMap::iterator iter = instance_map_.find(instance);
366 if (iter == instance_map_.end())
367 return false;
368 iter->second.GetAllPendingResourceHosts(reply_message.Pass());
369 return true;
370 }
371
372 void BrowserPpapiHostImpl::RendererDidReceiveHosts(PP_Instance instance,
373 int sequence_num) {
374 InstanceMap::iterator iter = instance_map_.find(instance);
375 if (iter == instance_map_.end())
376 return;
377 iter->second.RendererDidReceiveHosts(sequence_num);
378 }
379
154 BrowserPpapiHostImpl::HostMessageFilter::HostMessageFilter( 380 BrowserPpapiHostImpl::HostMessageFilter::HostMessageFilter(
155 ppapi::host::PpapiHost* ppapi_host, 381 ppapi::host::PpapiHost* ppapi_host,
156 BrowserPpapiHostImpl* browser_ppapi_host_impl) 382 BrowserPpapiHostImpl* browser_ppapi_host_impl)
157 : ppapi_host_(ppapi_host), 383 : ppapi_host_(ppapi_host),
158 browser_ppapi_host_impl_(browser_ppapi_host_impl) {} 384 browser_ppapi_host_impl_(browser_ppapi_host_impl) {
385 }
159 386
160 bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived( 387 bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived(
161 const IPC::Message& msg) { 388 const IPC::Message& msg) {
162 // Don't forward messages if our owner object has been destroyed. 389 // Don't forward messages if our owner object has been destroyed.
163 if (!ppapi_host_) 390 if (!ppapi_host_)
164 return false; 391 return false;
165 392
166 bool handled = true; 393 bool handled = true;
167 IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl::HostMessageFilter, msg) 394 IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl::HostMessageFilter, msg)
168 // Add necessary message handlers here. 395 // Add necessary message handlers here.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // for this module together. 429 // for this module together.
203 430
204 if (on_keepalive_callback_.is_null()) 431 if (on_keepalive_callback_.is_null())
205 return; 432 return;
206 433
207 BrowserPpapiHost::OnKeepaliveInstanceData instance_data(instance_map_.size()); 434 BrowserPpapiHost::OnKeepaliveInstanceData instance_data(instance_map_.size());
208 435
209 InstanceMap::iterator instance = instance_map_.begin(); 436 InstanceMap::iterator instance = instance_map_.begin();
210 int i = 0; 437 int i = 0;
211 while (instance != instance_map_.end()) { 438 while (instance != instance_map_.end()) {
212 instance_data[i].render_process_id = instance->second.render_process_id; 439 const PepperRendererInstanceData& data = instance->second.renderer_data();
213 instance_data[i].render_frame_id = instance->second.render_frame_id; 440 instance_data[i].render_process_id = data.render_process_id;
214 instance_data[i].document_url = instance->second.document_url; 441 instance_data[i].render_frame_id = data.render_frame_id;
442 instance_data[i].document_url = data.document_url;
215 ++instance; 443 ++instance;
216 ++i; 444 ++i;
217 } 445 }
218 on_keepalive_callback_.Run(instance_data, profile_data_directory_); 446 on_keepalive_callback_.Run(instance_data, profile_data_directory_);
219 } 447 }
220 448
221 } // namespace content 449 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698