file_io_resource.cc revision f2477e01787aa58f445919b809d89e252beef54f
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/file_io_resource.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/task_runner_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/array_writer.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/file_ref_create_info.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/file_system_util.h" 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ppapi/shared_impl/file_type_conversion.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ppapi/shared_impl/proxy_lock.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/enter.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/ppb_file_ref_api.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::EnterResourceNoLock; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::PPB_FileIO_API; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ppapi::thunk::PPB_FileRef_API; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We must allocate a buffer sized according to the request of the plugin. To 29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// reduce the chance of out-of-memory errors, we cap the read size to 32MB. 30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This is OK since the API specifies that it may perform a partial read. 31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstatic const int32_t kMaxReadSize = 32 * 1024 * 1024; // 32MB 32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An adapter to let Read() share the same implementation with ReadToArray(). 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return user_data; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// File thread task to close the file handle. 39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid DoClose(base::PlatformFile file) { 40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::ClosePlatformFile(file); 41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace proxy { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)FileIOResource::QueryOp::QueryOp(scoped_refptr<FileHandleHolder> file_handle) 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : file_handle_(file_handle) { 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(file_handle_); 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFileIOResource::QueryOp::~QueryOp() { 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochint32_t FileIOResource::QueryOp::DoWork() { 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return base::GetPlatformFileInfo(file_handle_->raw_handle(), &file_info_) ? 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PP_OK : PP_ERROR_FAILED; 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)FileIOResource::ReadOp::ReadOp(scoped_refptr<FileHandleHolder> file_handle, 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64_t offset, 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32_t bytes_to_read) 64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : file_handle_(file_handle), 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch offset_(offset), 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bytes_to_read_(bytes_to_read) { 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(file_handle_); 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFileIOResource::ReadOp::~ReadOp() { 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochint32_t FileIOResource::ReadOp::DoWork() { 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(!buffer_.get()); 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch buffer_.reset(new char[bytes_to_read_]); 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return base::ReadPlatformFile( 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_handle_->raw_handle(), offset_, buffer_.get(), bytes_to_read_); 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileIOResource::FileIOResource(Connection connection, PP_Instance instance) 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : PluginResource(connection, instance), 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_system_type_(PP_FILESYSTEMTYPE_INVALID) { 830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) SendCreate(BROWSER, PpapiHostMsg_FileIO_Create()); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileIOResource::~FileIOResource() { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Open(PP_Resource file_ref, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t open_flags, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (enter.failed()) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_ERROR_BADRESOURCE; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PPB_FileRef_API* file_ref_api = enter.object(); 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const FileRefCreateInfo& create_info = file_ref_api->GetCreateInfo(); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!FileSystemTypeIsValid(create_info.file_system_type)) { 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch NOTREACHED(); 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return PP_ERROR_FAILED; 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, false); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system_type_ = create_info.file_system_type; 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Keep the FileSystem host alive by taking a reference to its resource. The 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // FileIO host uses the FileSystem host for running tasks. 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system_resource_ = create_info.file_system_plugin_resource; 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Take a reference on the FileRef resource while we're opening the file; we 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // don't want the plugin destroying it during the Open operation. 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_ref_ = enter.resource(); 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_OpenReply>(BROWSER, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Open( 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_ref, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open_flags), 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Query(PP_FileInfo* info, 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!info) 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return PP_ERROR_BADARGUMENT; 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!FileHandleHolder::IsValid(file_handle_)) 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return PP_ERROR_FAILED; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If the callback is blocking, perform the task on the calling thread. 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (callback->is_blocking()) { 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32_t result = PP_ERROR_FAILED; 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::PlatformFileInfo file_info; 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The plugin could release its reference to this instance when we release 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the proxy lock below. 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<FileIOResource> protect(this); 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch { 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Release the proxy lock while making a potentially slow file call. 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ProxyAutoUnlock unlock; 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (base::GetPlatformFileInfo(file_handle_->raw_handle(), &file_info)) 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result = PP_OK; 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (result == PP_OK) { 1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // This writes the file info into the plugin's PP_FileInfo struct. 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ppapi::PlatformFileInfoToPepperFileInfo(file_info, 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) file_system_type_, 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) info); 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state_manager_.SetOperationFinished(); 1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return result; 166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // For the non-blocking case, post a task to the file thread and add a 169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // completion task to write the result. 1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<QueryOp> query_op(new QueryOp(file_handle_)); 171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::PostTaskAndReplyWithResult( 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PpapiGlobals::Get()->GetFileTaskRunner(), 173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Bind(&FileIOResource::QueryOp::DoWork, query_op), 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RunWhileLocked(Bind(&TrackedCallback::Run, callback))); 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback->set_completion_task( 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Bind(&FileIOResource::OnQueryComplete, this, query_op, info)); 178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Touch(PP_Time last_access_time, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Time last_modified_time, 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Touch(last_access_time, last_modified_time), 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Read(int64_t offset, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* buffer, 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_read, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_READ, true); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_ArrayOutput output_adapter; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_adapter.GetDataBuffer = &DummyGetDataBuffer; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_adapter.user_data = buffer; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ReadValidated(offset, bytes_to_read, output_adapter, callback); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::ReadToArray(int64_t offset, 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t max_read_length, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_ArrayOutput* array_output, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(array_output); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_READ, true); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ReadValidated(offset, max_read_length, *array_output, callback); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Write(int64_t offset, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* buffer, 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_write, 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_WRITE, true); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(brettw) it would be nice to use a shared memory buffer for large 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // writes rather than having to copy to a string (which will involve a number 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of extra copies to serialize over IPC). 2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Write(offset, std::string(buffer, bytes_to_write)), 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::SetLength(int64_t length, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_SetLength(length), 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::Flush(scoped_refptr<TrackedCallback> callback) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv != PP_OK) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PpapiHostMsg_FileIO_Flush(), 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::Close() { 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (file_handle_) { 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_handle_ = NULL; 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Post(BROWSER, PpapiHostMsg_FileIO_Close()); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochint32_t FileIOResource::RequestOSFileHandle( 287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PP_FileHandle* handle, 288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_refptr<TrackedCallback> callback) { 289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32_t rv = state_manager_.CheckOperationState( 290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FileIOStateManager::OPERATION_EXCLUSIVE, true); 291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (rv != PP_OK) 292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return rv; 293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Call<PpapiPluginMsg_FileIO_RequestOSFileHandleReply>(BROWSER, 295ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PpapiHostMsg_FileIO_RequestOSFileHandle(), 296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Bind(&FileIOResource::OnPluginMsgRequestOSFileHandleComplete, this, 297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback, handle)); 298ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return PP_OK_COMPLETIONPENDING; 301ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)FileIOResource::FileHandleHolder::FileHandleHolder(PP_FileHandle file_handle) 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : raw_handle_(file_handle) { 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool FileIOResource::FileHandleHolder::IsValid( 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<FileIOResource::FileHandleHolder>& handle) { 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return handle && (handle->raw_handle() != base::kInvalidPlatformFileValue); 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)FileIOResource::FileHandleHolder::~FileHandleHolder() { 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (raw_handle_ != base::kInvalidPlatformFileValue) { 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::TaskRunner* file_task_runner = 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PpapiGlobals::Get()->GetFileTaskRunner(); 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_task_runner->PostTask(FROM_HERE, 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&DoClose, raw_handle_)); 3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t FileIOResource::ReadValidated(int64_t offset, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t bytes_to_read, 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PP_ArrayOutput& array_output, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 326ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (bytes_to_read < 0) 327ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return PP_ERROR_FAILED; 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!FileHandleHolder::IsValid(file_handle_)) 329ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return PP_ERROR_FAILED; 330ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 331ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); 332ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 333ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bytes_to_read = std::min(bytes_to_read, kMaxReadSize); 334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (callback->is_blocking()) { 3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) char* buffer = static_cast<char*>( 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) array_output.GetDataBuffer(array_output.user_data, bytes_to_read, 1)); 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32_t result = PP_ERROR_FAILED; 3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The plugin could release its reference to this instance when we release 3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the proxy lock below. 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<FileIOResource> protect(this); 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (buffer) { 342ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Release the proxy lock while making a potentially slow file call. 343ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ProxyAutoUnlock unlock; 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result = base::ReadPlatformFile( 3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) file_handle_->raw_handle(), offset, buffer, bytes_to_read); 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (result < 0) 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result = PP_ERROR_FAILED; 348ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state_manager_.SetOperationFinished(); 3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return result; 351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // For the non-blocking case, post a task to the file thread. 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<ReadOp> read_op( 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new ReadOp(file_handle_, offset, bytes_to_read)); 356ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::PostTaskAndReplyWithResult( 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PpapiGlobals::Get()->GetFileTaskRunner(), 358ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 359ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Bind(&FileIOResource::ReadOp::DoWork, read_op), 360ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RunWhileLocked(Bind(&TrackedCallback::Run, callback))); 361ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback->set_completion_task( 362ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Bind(&FileIOResource::OnReadComplete, this, read_op, array_output)); 363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochint32_t FileIOResource::OnQueryComplete(scoped_refptr<QueryOp> query_op, 368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PP_FileInfo* info, 369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32_t result) { 370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(state_manager_.get_pending_operation() == 371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FileIOStateManager::OPERATION_EXCLUSIVE); 372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (result == PP_OK) { 374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // This writes the file info into the plugin's PP_FileInfo struct. 375ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ppapi::PlatformFileInfoToPepperFileInfo(query_op->file_info(), 376ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_system_type_, 377ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch info); 378ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 379ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_manager_.SetOperationFinished(); 380ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return result; 381ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 382ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 383ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochint32_t FileIOResource::OnReadComplete(scoped_refptr<ReadOp> read_op, 384ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PP_ArrayOutput array_output, 385ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int32_t result) { 386ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(state_manager_.get_pending_operation() == 387ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FileIOStateManager::OPERATION_READ); 388ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (result >= 0) { 389ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ArrayWriter output; 390ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output.set_pp_array_output(array_output); 391ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (output.is_valid()) 392ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output.StoreArray(read_op->buffer(), result); 393ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch else 394ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = PP_ERROR_FAILED; 395ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 396ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The read operation failed. 397ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = PP_ERROR_FAILED; 398ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 399ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch state_manager_.SetOperationFinished(); 400ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return result; 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgGeneralComplete( 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback, 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ResourceMessageReplyParams& params) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE || 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.get_pending_operation() == 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_WRITE); 410ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // End this operation now, so the user's callback can execute another FileIO 411ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // operation, assuming there are no other pending operations. 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetOperationFinished(); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback->Run(params.result()); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileIOResource::OnPluginMsgOpenFileComplete( 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TrackedCallback> callback, 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ResourceMessageReplyParams& params) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE); 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Release the FileRef resource. 423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_ref_ = NULL; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.result() == PP_OK) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetOpenSucceed(); 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32_t result = params.result(); 428ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IPC::PlatformFileForTransit transit_file; 4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((result == PP_OK) && params.TakeFileHandleAtIndex(0, &transit_file)) { 4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_handle_ = new FileHandleHolder( 4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) IPC::PlatformFileForTransitToPlatformFile(transit_file)); 4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 433ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // End this operation now, so the user's callback can execute another FileIO 434ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // operation, assuming there are no other pending operations. 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_manager_.SetOperationFinished(); 436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback->Run(result); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FileIOResource::OnPluginMsgRequestOSFileHandleComplete( 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<TrackedCallback> callback, 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_FileHandle* output_handle, 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceMessageReplyParams& params) { 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(state_manager_.get_pending_operation() == 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE); 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!TrackedCallback::IsPending(callback)) { 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_manager_.SetOperationFinished(); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int32_t result = params.result(); 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC::PlatformFileForTransit transit_file; 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!params.TakeFileHandleAtIndex(0, &transit_file)) 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result = PP_ERROR_FAILED; 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *output_handle = IPC::PlatformFileForTransitToPlatformFile(transit_file); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 457ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // End this operation now, so the user's callback can execute another FileIO 458ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // operation, assuming there are no other pending operations. 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state_manager_.SetOperationFinished(); 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback->Run(result); 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace proxy 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace ppapi 465