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

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

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