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

Side by Side Diff: trunk/src/content/browser/renderer_host/pepper/pepper_file_io_host.cc

Issue 60323002: Revert 232547 "Pepper: Move FileIO host from renderer to browser." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/pepper/pepper_file_io_host.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/callback_helpers.h"
10 #include "base/files/file_util_proxy.h"
11 #include "base/memory/weak_ptr.h"
12 #include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
13 #include "content/browser/renderer_host/pepper/pepper_security_helper.h"
14 #include "content/browser/renderer_host/pepper/quota_file_io.h"
15 #include "content/common/fileapi/file_system_messages.h"
16 #include "content/common/sandbox_util.h"
17 #include "content/common/view_messages.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/content_browser_client.h"
20 #include "content/public/browser/render_process_host.h"
21 #include "content/public/browser/storage_partition.h"
22 #include "content/public/common/content_client.h"
23 #include "ppapi/c/pp_errors.h"
24 #include "ppapi/c/ppb_file_io.h"
25 #include "ppapi/host/dispatch_host_message.h"
26 #include "ppapi/host/ppapi_host.h"
27 #include "ppapi/proxy/ppapi_messages.h"
28 #include "ppapi/shared_impl/file_type_conversion.h"
29 #include "ppapi/shared_impl/time_conversion.h"
30 #include "webkit/browser/fileapi/file_observers.h"
31 #include "webkit/browser/fileapi/file_system_context.h"
32 #include "webkit/browser/fileapi/task_runner_bound_observer_list.h"
33 #include "webkit/browser/quota/quota_manager.h"
34 #include "webkit/common/fileapi/file_system_util.h"
35
36 namespace content {
37
38 using ppapi::FileIOStateManager;
39 using ppapi::PPTimeToTime;
40
41 namespace {
42
43 int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) {
44 // On the plugin side, some callbacks expect a parameter that means different
45 // things depending on whether it is negative or not. We translate for those
46 // callbacks here.
47 return pp_error == PP_OK ? byte_number : pp_error;
48 }
49
50 class QuotaFileIODelegate : public QuotaFileIO::Delegate {
51 public:
52 QuotaFileIODelegate(scoped_refptr<fileapi::FileSystemContext> context,
53 int render_process_id)
54 : context_(context),
55 weak_factory_(this) { }
56 virtual ~QuotaFileIODelegate() {}
57
58 virtual void QueryAvailableSpace(
59 const GURL& origin,
60 quota::StorageType type,
61 const AvailableSpaceCallback& callback) OVERRIDE {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
63 quota::QuotaManagerProxy* quota_manager_proxy =
64 context_->quota_manager_proxy();
65 DCHECK(quota_manager_proxy);
66 if (!quota_manager_proxy) {
67 callback.Run(0);
68 return;
69 }
70 quota::QuotaManager* qm = quota_manager_proxy->quota_manager();
71 DCHECK(qm);
72 if (!qm) {
73 callback.Run(0);
74 return;
75 }
76 qm->GetUsageAndQuotaForWebApps(
77 origin,
78 type,
79 base::Bind(&QuotaFileIODelegate::GotUsageAndQuotaForWebApps,
80 weak_factory_.GetWeakPtr(), callback));
81 }
82
83 void GotUsageAndQuotaForWebApps(const AvailableSpaceCallback& callback,
84 quota::QuotaStatusCode code,
85 int64 usage,
86 int64 quota) {
87 if (code == quota::kQuotaStatusOk)
88 callback.Run(std::max(static_cast<int64>(0), quota - usage));
89 else
90 callback.Run(0);
91 }
92
93 virtual void WillUpdateFile(const GURL& file_path) OVERRIDE {
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
95 fileapi::FileSystemURL url(context_->CrackURL(file_path));
96 if (!url.is_valid())
97 return;
98 const fileapi::UpdateObserverList* observers =
99 context_->GetUpdateObservers(url.type());
100 if (!observers)
101 return;
102 observers->Notify(&fileapi::FileUpdateObserver::OnStartUpdate,
103 MakeTuple(url));
104 }
105 virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
107 fileapi::FileSystemURL url(context_->CrackURL(file_path));
108 if (!url.is_valid())
109 return;
110 const fileapi::UpdateObserverList* observers =
111 context_->GetUpdateObservers(url.type());
112 if (!observers)
113 return;
114 observers->Notify(&fileapi::FileUpdateObserver::OnUpdate,
115 MakeTuple(url, delta));
116 observers->Notify(&fileapi::FileUpdateObserver::OnEndUpdate,
117 MakeTuple(url));
118 }
119 virtual scoped_refptr<base::MessageLoopProxy>
120 GetFileThreadMessageLoopProxy() OVERRIDE {
121 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
122 }
123 private:
124 scoped_refptr<fileapi::FileSystemContext> context_;
125 base::WeakPtrFactory<QuotaFileIODelegate> weak_factory_;
126 };
127
128 PepperFileIOHost::UIThreadStuff
129 GetUIThreadStuffForInternalFileSystems(int render_process_id) {
130 PepperFileIOHost::UIThreadStuff stuff;
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
132 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
133 if (host) {
134 stuff.resolved_render_process_id = base::GetProcId(host->GetHandle());
135 StoragePartition* storage_partition = host->GetStoragePartition();
136 if (storage_partition)
137 stuff.file_system_context = storage_partition->GetFileSystemContext();
138 }
139 return stuff;
140 }
141
142 base::ProcessId GetResolvedRenderProcessId(int render_process_id) {
143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
144 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
145 if (!host)
146 return base::kNullProcessId;
147 return base::GetProcId(host->GetHandle());
148 }
149
150 bool GetPluginAllowedToCallRequestOSFileHandle(int render_process_id,
151 const GURL& document_url) {
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
153 ContentBrowserClient* client = GetContentClient()->browser();
154 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
155 return client->IsPluginAllowedToCallRequestOSFileHandle(
156 host->GetBrowserContext(), document_url);
157 }
158
159 } // namespace
160
161 PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host,
162 PP_Instance instance,
163 PP_Resource resource)
164 : ResourceHost(host->GetPpapiHost(), instance, resource),
165 browser_ppapi_host_(host),
166 render_process_host_(NULL),
167 file_(base::kInvalidPlatformFileValue),
168 file_system_type_(PP_FILESYSTEMTYPE_INVALID),
169 quota_policy_(quota::kQuotaLimitTypeUnknown),
170 open_flags_(0),
171 weak_factory_(this) {
172 int unused;
173 if (!host->GetRenderViewIDsForInstance(instance,
174 &render_process_id_,
175 &unused)) {
176 render_process_id_ = -1;
177 }
178 file_message_loop_ = BrowserThread::GetMessageLoopProxyForThread(
179 BrowserThread::FILE);
180 }
181
182 PepperFileIOHost::~PepperFileIOHost() {
183 OnHostMsgClose(NULL);
184 }
185
186 int32_t PepperFileIOHost::OnResourceMessageReceived(
187 const IPC::Message& msg,
188 ppapi::host::HostMessageContext* context) {
189 IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg)
190 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open,
191 OnHostMsgOpen)
192 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch,
193 OnHostMsgTouch)
194 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write,
195 OnHostMsgWrite)
196 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength,
197 OnHostMsgSetLength)
198 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush,
199 OnHostMsgFlush)
200 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close,
201 OnHostMsgClose)
202 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_RequestOSFileHandle,
203 OnHostMsgRequestOSFileHandle)
204 IPC_END_MESSAGE_MAP()
205 return PP_ERROR_FAILED;
206 }
207
208 PepperFileIOHost::UIThreadStuff::UIThreadStuff() {
209 resolved_render_process_id = base::kNullProcessId;
210 }
211
212 PepperFileIOHost::UIThreadStuff::~UIThreadStuff() {
213 }
214
215 int32_t PepperFileIOHost::OnHostMsgOpen(
216 ppapi::host::HostMessageContext* context,
217 PP_Resource file_ref_resource,
218 int32_t open_flags) {
219 int32_t rv = state_manager_.CheckOperationState(
220 FileIOStateManager::OPERATION_EXCLUSIVE, false);
221 if (rv != PP_OK)
222 return rv;
223
224 int platform_file_flags = 0;
225 if (!ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags,
226 &platform_file_flags))
227 return PP_ERROR_BADARGUMENT;
228
229 ppapi::host::ResourceHost* resource_host =
230 host()->GetResourceHost(file_ref_resource);
231 if (!resource_host || !resource_host->IsFileRefHost())
232 return PP_ERROR_BADRESOURCE;
233 PepperFileRefHost* file_ref_host =
234 static_cast<PepperFileRefHost*>(resource_host);
235 if (file_ref_host->GetFileSystemType() == PP_FILESYSTEMTYPE_INVALID)
236 return PP_ERROR_FAILED;
237
238 open_flags_ = open_flags;
239 file_system_type_ = file_ref_host->GetFileSystemType();
240 file_system_url_ = file_ref_host->GetFileSystemURL();
241
242 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
243 if (!file_system_url_.is_valid())
244 return PP_ERROR_BADARGUMENT;
245 if (!CanOpenFileSystemURLWithPepperFlags(open_flags,
246 render_process_id_,
247 file_system_url_))
248 return PP_ERROR_NOACCESS;
249
250 BrowserThread::PostTaskAndReplyWithResult(
251 BrowserThread::UI,
252 FROM_HERE,
253 base::Bind(&GetUIThreadStuffForInternalFileSystems,
254 render_process_id_),
255 base::Bind(&PepperFileIOHost::GotUIThreadStuffForInternalFileSystems,
256 weak_factory_.GetWeakPtr(),
257 context->MakeReplyMessageContext(),
258 platform_file_flags));
259 } else {
260 base::FilePath path = file_ref_host->GetExternalFilePath();
261 if (!CanOpenWithPepperFlags(open_flags, render_process_id_, path))
262 return PP_ERROR_NOACCESS;
263 BrowserThread::PostTaskAndReplyWithResult(
264 BrowserThread::UI,
265 FROM_HERE,
266 base::Bind(&GetResolvedRenderProcessId, render_process_id_),
267 base::Bind(&PepperFileIOHost::GotResolvedRenderProcessId,
268 weak_factory_.GetWeakPtr(),
269 context->MakeReplyMessageContext(),
270 path,
271 platform_file_flags));
272 }
273 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
274 return PP_OK_COMPLETIONPENDING;
275 }
276
277 void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems(
278 ppapi::host::ReplyMessageContext reply_context,
279 int platform_file_flags,
280 UIThreadStuff ui_thread_stuff) {
281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
282 file_system_context_ = ui_thread_stuff.file_system_context;
283 resolved_render_process_id_ = ui_thread_stuff.resolved_render_process_id;
284 if (resolved_render_process_id_ == base::kNullProcessId ||
285 !file_system_context_.get()) {
286 reply_context.params.set_result(PP_ERROR_FAILED);
287 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply());
288 return;
289 }
290
291 if (!file_system_context_->GetFileSystemBackend(file_system_url_.type())) {
292 reply_context.params.set_result(PP_ERROR_FAILED);
293 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply());
294 return;
295 }
296 quota_policy_ = quota::kQuotaLimitTypeUnknown;
297 quota::QuotaManagerProxy* quota_manager_proxy =
298 file_system_context_->quota_manager_proxy();
299 CHECK(quota_manager_proxy);
300 CHECK(quota_manager_proxy->quota_manager());
301 if (quota_manager_proxy->quota_manager()->IsStorageUnlimited(
302 file_system_url_.origin(),
303 fileapi::FileSystemTypeToQuotaStorageType(file_system_url_.type())))
304 quota_policy_ = quota::kQuotaLimitTypeUnlimited;
305 else
306 quota_policy_ = quota::kQuotaLimitTypeLimited;
307 file_system_operation_runner_ =
308 file_system_context_->CreateFileSystemOperationRunner();
309 file_system_operation_runner_->OpenFile(
310 file_system_url_,
311 platform_file_flags,
312 base::Bind(&PepperFileIOHost::DidOpenInternalFile,
313 weak_factory_.GetWeakPtr(),
314 reply_context));
315 }
316
317 void PepperFileIOHost::DidOpenInternalFile(
318 ppapi::host::ReplyMessageContext reply_context,
319 base::PlatformFileError result,
320 base::PlatformFile file,
321 const base::Closure& on_close_callback) {
322 if (result == base::PLATFORM_FILE_OK)
323 on_close_callback_ = on_close_callback;
324 ExecutePlatformOpenFileCallback(
325 reply_context, result, base::PassPlatformFile(&file), true);
326 }
327
328 void PepperFileIOHost::GotResolvedRenderProcessId(
329 ppapi::host::ReplyMessageContext reply_context,
330 base::FilePath path,
331 int platform_file_flags,
332 base::ProcessId resolved_render_process_id) {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
334 resolved_render_process_id_ = resolved_render_process_id;
335 base::FileUtilProxy::CreateOrOpen(
336 file_message_loop_,
337 path,
338 platform_file_flags,
339 base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback,
340 weak_factory_.GetWeakPtr(),
341 reply_context));
342 }
343
344 int32_t PepperFileIOHost::OnHostMsgTouch(
345 ppapi::host::HostMessageContext* context,
346 PP_Time last_access_time,
347 PP_Time last_modified_time) {
348 int32_t rv = state_manager_.CheckOperationState(
349 FileIOStateManager::OPERATION_EXCLUSIVE, true);
350 if (rv != PP_OK)
351 return rv;
352
353 base::FileUtilProxy::StatusCallback cb =
354 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
355 weak_factory_.GetWeakPtr(),
356 context->MakeReplyMessageContext());
357
358 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
359 // We use FileSystemOperationRunner here instead of working on the
360 // opened file because it may not have been opened with enough
361 // permissions for this operation. See http://crbug.com/313426 for
362 // details.
363 file_system_operation_runner_->TouchFile(
364 file_system_url_,
365 PPTimeToTime(last_access_time),
366 PPTimeToTime(last_modified_time),
367 cb);
368 } else {
369 if (!base::FileUtilProxy::Touch(
370 file_message_loop_,
371 file_,
372 PPTimeToTime(last_access_time),
373 PPTimeToTime(last_modified_time),
374 cb))
375 return PP_ERROR_FAILED;
376 }
377 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
378 return PP_OK_COMPLETIONPENDING;
379 }
380
381 int32_t PepperFileIOHost::OnHostMsgWrite(
382 ppapi::host::HostMessageContext* context,
383 int64_t offset,
384 const std::string& buffer) {
385 int32_t rv = state_manager_.CheckOperationState(
386 FileIOStateManager::OPERATION_WRITE, true);
387 if (rv != PP_OK)
388 return rv;
389
390 QuotaFileIO::WriteCallback cb =
391 base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
392 weak_factory_.GetWeakPtr(),
393 context->MakeReplyMessageContext());
394
395 if (quota_file_io_) {
396 if (!quota_file_io_->Write(offset, buffer.c_str(), buffer.size(), cb))
397 return PP_ERROR_FAILED;
398 } else {
399 if (!base::FileUtilProxy::Write(
400 file_message_loop_,
401 file_,
402 offset,
403 buffer.c_str(),
404 buffer.size(),
405 cb))
406 return PP_ERROR_FAILED;
407 }
408
409 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE);
410 return PP_OK_COMPLETIONPENDING;
411 }
412
413 int32_t PepperFileIOHost::OnHostMsgSetLength(
414 ppapi::host::HostMessageContext* context,
415 int64_t length) {
416 int32_t rv = state_manager_.CheckOperationState(
417 FileIOStateManager::OPERATION_EXCLUSIVE, true);
418 if (rv != PP_OK)
419 return rv;
420
421 base::FileUtilProxy::StatusCallback cb =
422 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
423 weak_factory_.GetWeakPtr(),
424 context->MakeReplyMessageContext());
425
426 // TODO(teravest): Use QuotaFileIO::SetLength here.
427 // The previous implementation did not use it in the renderer, so I'll
428 // do it in a follow-up change.
429 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
430 // We use FileSystemOperationRunner here instead of working on the
431 // opened file because it may not have been opened with enough
432 // permissions for this operation. See http://crbug.com/313426 for
433 // details.
434 file_system_operation_runner_->Truncate(file_system_url_, length, cb);
435 } else {
436 if (!base::FileUtilProxy::Truncate(file_message_loop_, file_, length, cb))
437 return PP_ERROR_FAILED;
438 }
439
440 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
441 return PP_OK_COMPLETIONPENDING;
442 }
443
444 int32_t PepperFileIOHost::OnHostMsgFlush(
445 ppapi::host::HostMessageContext* context) {
446 int32_t rv = state_manager_.CheckOperationState(
447 FileIOStateManager::OPERATION_EXCLUSIVE, true);
448 if (rv != PP_OK)
449 return rv;
450
451 if (!base::FileUtilProxy::Flush(
452 file_message_loop_,
453 file_,
454 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
455 weak_factory_.GetWeakPtr(),
456 context->MakeReplyMessageContext())))
457 return PP_ERROR_FAILED;
458
459 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
460 return PP_OK_COMPLETIONPENDING;
461 }
462
463 int32_t PepperFileIOHost::OnHostMsgClose(
464 ppapi::host::HostMessageContext* context) {
465 if (file_ != base::kInvalidPlatformFileValue) {
466 base::FileUtilProxy::Close(
467 file_message_loop_,
468 file_,
469 base::Bind(&PepperFileIOHost::DidCloseFile,
470 weak_factory_.GetWeakPtr()));
471 file_ = base::kInvalidPlatformFileValue;
472 quota_file_io_.reset();
473 }
474 return PP_OK;
475 }
476
477 void PepperFileIOHost::DidCloseFile(base::PlatformFileError error) {
478 // Silently ignore if we fail to close the file.
479 if (!on_close_callback_.is_null()) {
480 on_close_callback_.Run();
481 on_close_callback_.Reset();
482 }
483 }
484
485 int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle(
486 ppapi::host::HostMessageContext* context) {
487 if (open_flags_ != PP_FILEOPENFLAG_READ &&
488 quota_policy_ != quota::kQuotaLimitTypeUnlimited)
489 return PP_ERROR_FAILED;
490
491 GURL document_url =
492 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance());
493 BrowserThread::PostTaskAndReplyWithResult(
494 BrowserThread::UI,
495 FROM_HERE,
496 base::Bind(&GetPluginAllowedToCallRequestOSFileHandle,
497 render_process_id_,
498 document_url),
499 base::Bind(&PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle,
500 weak_factory_.GetWeakPtr(),
501 context->MakeReplyMessageContext()));
502 return PP_OK_COMPLETIONPENDING;
503 }
504
505 void PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle(
506 ppapi::host::ReplyMessageContext reply_context,
507 bool plugin_allowed) {
508 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
509 if (!browser_ppapi_host_->external_plugin() ||
510 host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE) ||
511 plugin_allowed) {
512 if (!AddFileToReplyContext(open_flags_, &reply_context))
513 reply_context.params.set_result(PP_ERROR_FAILED);
514 } else {
515 reply_context.params.set_result(PP_ERROR_NOACCESS);
516 }
517 host()->SendReply(reply_context,
518 PpapiPluginMsg_FileIO_RequestOSFileHandleReply());
519 }
520
521 void PepperFileIOHost::ExecutePlatformGeneralCallback(
522 ppapi::host::ReplyMessageContext reply_context,
523 base::PlatformFileError error_code) {
524 reply_context.params.set_result(
525 ppapi::PlatformFileErrorToPepperError(error_code));
526 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
527 state_manager_.SetOperationFinished();
528 }
529
530 void PepperFileIOHost::ExecutePlatformOpenFileCallback(
531 ppapi::host::ReplyMessageContext reply_context,
532 base::PlatformFileError error_code,
533 base::PassPlatformFile file,
534 bool unused_created) {
535 int32_t pp_error = ppapi::PlatformFileErrorToPepperError(error_code);
536 if (pp_error == PP_OK)
537 state_manager_.SetOpenSucceed();
538
539 DCHECK(file_ == base::kInvalidPlatformFileValue);
540 file_ = file.ReleaseValue();
541
542 DCHECK(!quota_file_io_.get());
543 if (file_ != base::kInvalidPlatformFileValue) {
544 if (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY ||
545 file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT) {
546 quota_file_io_.reset(new QuotaFileIO(
547 new QuotaFileIODelegate(file_system_context_, render_process_id_),
548 file_, file_system_url_.ToGURL(), file_system_type_));
549 }
550 int32_t flags_to_send = open_flags_;
551 if (!host()->permissions().HasPermission(ppapi::PERMISSION_DEV)) {
552 // IMPORTANT: Clear PP_FILEOPENFLAG_WRITE and PP_FILEOPENFLAG_APPEND so
553 // the plugin can't write and so bypass our quota checks.
554 flags_to_send =
555 open_flags_ & ~(PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_APPEND);
556 }
557 if (!AddFileToReplyContext(flags_to_send, &reply_context))
558 pp_error = PP_ERROR_FAILED;
559 }
560 reply_context.params.set_result(pp_error);
561 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply());
562 state_manager_.SetOperationFinished();
563 }
564
565 void PepperFileIOHost::ExecutePlatformWriteCallback(
566 ppapi::host::ReplyMessageContext reply_context,
567 base::PlatformFileError error_code,
568 int bytes_written) {
569 // On the plugin side, the callback expects a parameter with different meaning
570 // depends on whether is negative or not. It is the result here. We translate
571 // for the callback.
572 int32_t pp_error = ppapi::PlatformFileErrorToPepperError(error_code);
573 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written));
574 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
575 state_manager_.SetOperationFinished();
576 }
577
578 bool PepperFileIOHost::AddFileToReplyContext(
579 int32_t open_flags,
580 ppapi::host::ReplyMessageContext* reply_context) const {
581 base::ProcessId plugin_process_id;
582 if (browser_ppapi_host_->in_process()) {
583 plugin_process_id = resolved_render_process_id_;
584 } else {
585 plugin_process_id = base::GetProcId(
586 browser_ppapi_host_->GetPluginProcessHandle());
587 }
588 IPC::PlatformFileForTransit transit_file = BrokerGetFileHandleForProcess(
589 file_, plugin_process_id, false);
590 if (transit_file == IPC::InvalidPlatformFileForTransit())
591 return false;
592 ppapi::proxy::SerializedHandle file_handle;
593 file_handle.set_file_handle(transit_file, open_flags);
594 reply_context->params.AppendHandle(file_handle);
595 return true;
596 }
597
598 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698