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

Side by Side Diff: content/renderer/pepper/pepper_file_io_host.cc

Issue 22646005: Do PPB_FileIO Query and Read in the plugin process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Defer buffer allocation until we read. Created 7 years, 4 months 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
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/renderer/pepper/pepper_file_io_host.h" 5 #include "content/renderer/pepper/pepper_file_io_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 23 matching lines...) Expand all
34 namespace content { 34 namespace content {
35 35
36 using ppapi::FileIOStateManager; 36 using ppapi::FileIOStateManager;
37 using ppapi::PPTimeToTime; 37 using ppapi::PPTimeToTime;
38 using ppapi::host::ReplyMessageContext; 38 using ppapi::host::ReplyMessageContext;
39 using ppapi::thunk::EnterResourceNoLock; 39 using ppapi::thunk::EnterResourceNoLock;
40 using ppapi::thunk::PPB_FileRef_API; 40 using ppapi::thunk::PPB_FileRef_API;
41 41
42 namespace { 42 namespace {
43 43
44 // The maximum size we'll support reading in one chunk. The renderer process
45 // must allocate a buffer sized according to the request of the plugin. To
46 // keep things from getting out of control, we cap the read size to this value.
47 // This should generally be OK since the API specifies that it may perform a
48 // partial read.
49 static const int32_t kMaxReadSize = 32 * 1024 * 1024; // 32MB
50
51 typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback; 44 typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback;
52 45
53 int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) { 46 int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) {
54 // On the plugin side, some callbacks expect a parameter that means different 47 // On the plugin side, some callbacks expect a parameter that means different
55 // things depending on whether is negative or not. We translate for those 48 // things depending on whether is negative or not. We translate for those
56 // callbacks here. 49 // callbacks here.
57 return pp_error == PP_OK ? byte_number : pp_error; 50 return pp_error == PP_OK ? byte_number : pp_error;
58 } 51 }
59 52
60 class QuotaCallbackTranslator : public QuotaDispatcher::Callback { 53 class QuotaCallbackTranslator : public QuotaDispatcher::Callback {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 OnHostMsgClose(NULL); 151 OnHostMsgClose(NULL);
159 ChildThread::current()->RemoveRoute(routing_id_); 152 ChildThread::current()->RemoveRoute(routing_id_);
160 } 153 }
161 154
162 int32_t PepperFileIOHost::OnResourceMessageReceived( 155 int32_t PepperFileIOHost::OnResourceMessageReceived(
163 const IPC::Message& msg, 156 const IPC::Message& msg,
164 ppapi::host::HostMessageContext* context) { 157 ppapi::host::HostMessageContext* context) {
165 IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg) 158 IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg)
166 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open, 159 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open,
167 OnHostMsgOpen) 160 OnHostMsgOpen)
168 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Query,
169 OnHostMsgQuery)
170 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch, 161 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch,
171 OnHostMsgTouch) 162 OnHostMsgTouch)
172 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Read,
173 OnHostMsgRead)
174 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write, 163 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write,
175 OnHostMsgWrite) 164 OnHostMsgWrite)
176 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength, 165 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength,
177 OnHostMsgSetLength) 166 OnHostMsgSetLength)
178 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush, 167 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush,
179 OnHostMsgFlush) 168 OnHostMsgFlush)
180 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close, 169 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close,
181 OnHostMsgClose) 170 OnHostMsgClose)
182 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillWrite, 171 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillWrite,
183 OnHostMsgWillWrite) 172 OnHostMsgWillWrite)
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 weak_factory_.GetWeakPtr(), 264 weak_factory_.GetWeakPtr(),
276 context->MakeReplyMessageContext()))); 265 context->MakeReplyMessageContext())));
277 RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( 266 RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile(
278 routing_id_, file_ref->GetSystemPath(), open_flags, message_id)); 267 routing_id_, file_ref->GetSystemPath(), open_flags, message_id));
279 } 268 }
280 269
281 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 270 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
282 return PP_OK_COMPLETIONPENDING; 271 return PP_OK_COMPLETIONPENDING;
283 } 272 }
284 273
285 int32_t PepperFileIOHost::OnHostMsgQuery(
286 ppapi::host::HostMessageContext* context) {
287 int32_t rv = state_manager_.CheckOperationState(
288 FileIOStateManager::OPERATION_EXCLUSIVE, true);
289 if (rv != PP_OK)
290 return rv;
291
292 if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
293 RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
294 file_,
295 base::Bind(&PepperFileIOHost::ExecutePlatformQueryCallback,
296 weak_factory_.GetWeakPtr(),
297 context->MakeReplyMessageContext())))
298 return PP_ERROR_FAILED;
299
300 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
301 return PP_OK_COMPLETIONPENDING;
302 }
303
304 int32_t PepperFileIOHost::OnHostMsgTouch( 274 int32_t PepperFileIOHost::OnHostMsgTouch(
305 ppapi::host::HostMessageContext* context, 275 ppapi::host::HostMessageContext* context,
306 PP_Time last_access_time, 276 PP_Time last_access_time,
307 PP_Time last_modified_time) { 277 PP_Time last_modified_time) {
308 int32_t rv = state_manager_.CheckOperationState( 278 int32_t rv = state_manager_.CheckOperationState(
309 FileIOStateManager::OPERATION_EXCLUSIVE, true); 279 FileIOStateManager::OPERATION_EXCLUSIVE, true);
310 if (rv != PP_OK) 280 if (rv != PP_OK)
311 return rv; 281 return rv;
312 282
313 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { 283 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
(...skipping 19 matching lines...) Expand all
333 PPTimeToTime(last_modified_time), 303 PPTimeToTime(last_modified_time),
334 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, 304 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
335 weak_factory_.GetWeakPtr(), 305 weak_factory_.GetWeakPtr(),
336 context->MakeReplyMessageContext()))) 306 context->MakeReplyMessageContext())))
337 return PP_ERROR_FAILED; 307 return PP_ERROR_FAILED;
338 308
339 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 309 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
340 return PP_OK_COMPLETIONPENDING; 310 return PP_OK_COMPLETIONPENDING;
341 } 311 }
342 312
343 int32_t PepperFileIOHost::OnHostMsgRead(
344 ppapi::host::HostMessageContext* context,
345 int64_t offset,
346 int32_t max_read_length) {
347 int32_t rv = state_manager_.CheckOperationState(
348 FileIOStateManager::OPERATION_READ, true);
349 if (rv != PP_OK)
350 return rv;
351
352 // Validate max_read_length before allocating below. This value is coming from
353 // the untrusted plugin.
354 if (max_read_length < 0) {
355 ReplyMessageContext reply_context = context->MakeReplyMessageContext();
356 reply_context.params.set_result(PP_ERROR_FAILED);
357 host()->SendReply(reply_context,
358 PpapiPluginMsg_FileIO_ReadReply(std::string()));
359 return PP_OK_COMPLETIONPENDING;
360 }
361
362 if (!base::FileUtilProxy::Read(
363 RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
364 file_,
365 offset,
366 max_read_length,
367 base::Bind(&PepperFileIOHost::ExecutePlatformReadCallback,
368 weak_factory_.GetWeakPtr(),
369 context->MakeReplyMessageContext())))
370 return PP_ERROR_FAILED;
371
372 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ);
373 return PP_OK_COMPLETIONPENDING;
374 }
375
376 int32_t PepperFileIOHost::OnHostMsgWrite( 313 int32_t PepperFileIOHost::OnHostMsgWrite(
377 ppapi::host::HostMessageContext* context, 314 ppapi::host::HostMessageContext* context,
378 int64_t offset, 315 int64_t offset,
379 const std::string& buffer) { 316 const std::string& buffer) {
380 int32_t rv = state_manager_.CheckOperationState( 317 int32_t rv = state_manager_.CheckOperationState(
381 FileIOStateManager::OPERATION_WRITE, true); 318 FileIOStateManager::OPERATION_WRITE, true);
382 if (rv != PP_OK) 319 if (rv != PP_OK)
383 return rv; 320 return rv;
384 321
385 if (quota_file_io_) { 322 if (quota_file_io_) {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 base::PlatformFileError error_code, 550 base::PlatformFileError error_code,
614 base::PassPlatformFile file, 551 base::PassPlatformFile file,
615 quota::QuotaLimitType quota_policy, 552 quota::QuotaLimitType quota_policy,
616 const PepperFileIOHost::NotifyCloseFileCallback& callback) { 553 const PepperFileIOHost::NotifyCloseFileCallback& callback) {
617 if (error_code == base::PLATFORM_FILE_OK) 554 if (error_code == base::PLATFORM_FILE_OK)
618 notify_close_file_callback_ = callback; 555 notify_close_file_callback_ = callback;
619 quota_policy_ = quota_policy; 556 quota_policy_ = quota_policy;
620 ExecutePlatformOpenFileCallback(reply_context, error_code, file); 557 ExecutePlatformOpenFileCallback(reply_context, error_code, file);
621 } 558 }
622 559
623 void PepperFileIOHost::ExecutePlatformQueryCallback(
624 ppapi::host::ReplyMessageContext reply_context,
625 base::PlatformFileError error_code,
626 const base::PlatformFileInfo& file_info) {
627 PP_FileInfo pp_info;
628 ppapi::PlatformFileInfoToPepperFileInfo(file_info, file_system_type_,
629 &pp_info);
630
631 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
632 reply_context.params.set_result(pp_error);
633 host()->SendReply(reply_context,
634 PpapiPluginMsg_FileIO_QueryReply(pp_info));
635 state_manager_.SetOperationFinished();
636 }
637
638 void PepperFileIOHost::ExecutePlatformReadCallback(
639 ppapi::host::ReplyMessageContext reply_context,
640 base::PlatformFileError error_code,
641 const char* data, int bytes_read) {
642 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
643
644 // Only send the amount of data in the string that was actually read.
645 std::string buffer;
646 if (pp_error == PP_OK)
647 buffer.append(data, bytes_read);
648 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_read));
649 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_ReadReply(buffer));
650 state_manager_.SetOperationFinished();
651 }
652
653 void PepperFileIOHost::ExecutePlatformWriteCallback( 560 void PepperFileIOHost::ExecutePlatformWriteCallback(
654 ppapi::host::ReplyMessageContext reply_context, 561 ppapi::host::ReplyMessageContext reply_context,
655 base::PlatformFileError error_code, 562 base::PlatformFileError error_code,
656 int bytes_written) { 563 int bytes_written) {
657 // On the plugin side, the callback expects a parameter with different meaning 564 // On the plugin side, the callback expects a parameter with different meaning
658 // depends on whether is negative or not. It is the result here. We translate 565 // depends on whether is negative or not. It is the result here. We translate
659 // for the callback. 566 // for the callback.
660 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); 567 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
661 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written)); 568 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written));
662 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); 569 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
663 state_manager_.SetOperationFinished(); 570 state_manager_.SetOperationFinished();
664 } 571 }
665 572
666 } // namespace content 573 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698