diff options
27 files changed, 1263 insertions, 1571 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 929523f..3a81b1e 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -174,6 +174,8 @@ 'renderer/pepper/pepper_device_enumeration_host_helper.h', 'renderer/pepper/pepper_file_chooser_host.cc', 'renderer/pepper/pepper_file_chooser_host.h', + 'renderer/pepper/pepper_file_io_host.cc', + 'renderer/pepper/pepper_file_io_host.h', 'renderer/pepper/pepper_flash_clipboard_host.cc', 'renderer/pepper/pepper_flash_clipboard_host.h', 'renderer/pepper/pepper_graphics_2d_host.cc', diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc index 23d957e..2c6ee1e 100644 --- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc +++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "content/renderer/pepper/pepper_audio_input_host.h" #include "content/renderer/pepper/pepper_file_chooser_host.h" +#include "content/renderer/pepper/pepper_file_io_host.h" #include "content/renderer/pepper/pepper_flash_clipboard_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "content/renderer/pepper/pepper_video_capture_host.h" @@ -54,6 +55,9 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( case PpapiHostMsg_WebSocket_Create::ID: return scoped_ptr<ResourceHost>(new PepperWebSocketHost( host_, instance, params.pp_resource())); + case PpapiHostMsg_FileIO_Create::ID: + return scoped_ptr<ResourceHost>(new PepperFileIOHost( + host_, instance, params.pp_resource())); } // Dev interfaces. diff --git a/content/renderer/pepper/pepper_file_io_host.cc b/content/renderer/pepper/pepper_file_io_host.cc new file mode 100644 index 0000000..88c05c9 --- /dev/null +++ b/content/renderer/pepper/pepper_file_io_host.cc @@ -0,0 +1,566 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/pepper/pepper_file_io_host.h" + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/file_util_proxy.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_type_conversion.h" +#include "ppapi/shared_impl/time_conversion.h" +#include "ppapi/thunk/enter.h" +#include "webkit/fileapi/file_system_callback_dispatcher.h" +#include "webkit/plugins/ppapi/file_callbacks.h" +#include "webkit/plugins/ppapi/host_globals.h" +#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" +#include "webkit/plugins/ppapi/ppb_file_ref_impl.h" +#include "webkit/plugins/ppapi/quota_file_io.h" + +namespace content { + +using ppapi::FileIOStateManager; +using ppapi::PPTimeToTime; +using ppapi::TimeToPPTime; +using ppapi::host::ReplyMessageContext; +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_FileRef_API; +using webkit::ppapi::PPB_FileRef_Impl; +using webkit::ppapi::PluginDelegate; + +namespace { + +// The maximum size we'll support reading in one chunk. The renderer process +// must allocate a buffer sized according to the request of the plugin. To +// keep things from getting out of control, we cap the read size to this value. +// This should generally be OK since the API specifies that it may perform a +// partial read. +static const int32_t kMaxReadSize = 32 * 1024 * 1024; // 32MB + +typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback; + +class PlatformGeneralCallbackTranslator + : public fileapi::FileSystemCallbackDispatcher { + public: + explicit PlatformGeneralCallbackTranslator( + const PlatformGeneralCallback& callback) + : callback_(callback) {} + + virtual ~PlatformGeneralCallbackTranslator() {} + + virtual void DidSucceed() OVERRIDE { + callback_.Run(base::PLATFORM_FILE_OK); + } + + virtual void DidReadMetadata(const base::PlatformFileInfo& file_info, + const FilePath& platform_path) OVERRIDE { + NOTREACHED(); + } + + virtual void DidReadDirectory( + const std::vector<base::FileUtilProxy::Entry>& entries, + bool has_more) OVERRIDE { + NOTREACHED(); + } + + virtual void DidOpenFileSystem(const std::string& name, + const GURL& root) OVERRIDE { + NOTREACHED(); + } + + virtual void DidFail(base::PlatformFileError error_code) OVERRIDE { + callback_.Run(error_code); + } + + virtual void DidWrite(int64 bytes, bool complete) OVERRIDE { + NOTREACHED(); + } + + virtual void DidOpenFile(base::PlatformFile file) OVERRIDE { + NOTREACHED(); + } + + private: + PlatformGeneralCallback callback_; +}; + +int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) { + // On the plugin side, some callbacks expect a parameter that means different + // things depending on whether is negative or not. We translate for those + // callbacks here. + return pp_error == PP_OK ? byte_number : pp_error; +} + +} // namespace + +PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + file_(base::kInvalidPlatformFileValue), + file_system_type_(PP_FILESYSTEMTYPE_INVALID), + is_running_in_process_(host->IsRunningInProcess()), + weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + // TODO(victorhsieh): eliminate plugin_delegate_ as it's no longer needed. + webkit::ppapi::PluginInstance* plugin_instance = + webkit::ppapi::HostGlobals::Get()->GetInstance(instance); + plugin_delegate_ = plugin_instance ? plugin_instance->delegate() : NULL; +} + +PepperFileIOHost::~PepperFileIOHost() { + OnHostMsgClose(NULL); +} + +int32_t PepperFileIOHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open, + OnHostMsgOpen) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Query, + OnHostMsgQuery) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch, + OnHostMsgTouch) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Read, + OnHostMsgRead) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write, + OnHostMsgWrite) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength, + OnHostMsgSetLength) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush, + OnHostMsgFlush) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close, + OnHostMsgClose) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillWrite, + OnHostMsgWillWrite) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillSetLength, + OnHostMsgWillSetLength) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_GetOSFileDescriptor, + OnHostMsgGetOSFileDescriptor) + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFileIOHost::OnHostMsgOpen( + ppapi::host::HostMessageContext* context, + PP_Resource file_ref_resource, + int32_t open_flags) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, false); + if (rv != PP_OK) + return rv; + + int flags = 0; + if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, &flags)) + return PP_ERROR_BADARGUMENT; + + EnterResourceNoLock<PPB_FileRef_API> enter(file_ref_resource, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; + + PPB_FileRef_API* file_ref_api = enter.object(); + PP_FileSystemType type = file_ref_api->GetFileSystemType(); + if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && + type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && + type != PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; + file_system_type_ = type; + + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api); + if (file_ref->HasValidFileSystem()) { + file_system_url_ = file_ref->GetFileSystemURL(); + if (!plugin_delegate_->AsyncOpenFileSystemURL( + file_system_url_, flags, + base::Bind( + &PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + } else { + if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; + if (!plugin_delegate_->AsyncOpenFile( + file_ref->GetSystemPath(), flags, + base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + } + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgQuery( + ppapi::host::HostMessageContext* context) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( + plugin_delegate_->GetFileThreadMessageLoopProxy(), file_, + base::Bind(&PepperFileIOHost::ExecutePlatformQueryCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgTouch( + ppapi::host::HostMessageContext* context, + PP_Time last_access_time, + PP_Time last_modified_time) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { + if (!plugin_delegate_->Touch( + file_system_url_, + PPTimeToTime(last_access_time), + PPTimeToTime(last_modified_time), + new PlatformGeneralCallbackTranslator( + base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext())))) + return PP_ERROR_FAILED; + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; + } + + // TODO(nhiroki): fix a failure of FileIO.Touch for an external filesystem on + // Mac and Linux due to sandbox restrictions (http://crbug.com/101128). + if (!base::FileUtilProxy::Touch( + plugin_delegate_->GetFileThreadMessageLoopProxy(), + file_, PPTimeToTime(last_access_time), + PPTimeToTime(last_modified_time), + base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgRead( + ppapi::host::HostMessageContext* context, + int64_t offset, + int32_t max_read_length) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_READ, true); + if (rv != PP_OK) + return rv; + + // Validate max_read_length before allocating below. This value is coming from + // the untrusted plugin. + if (max_read_length < 0) { + ReplyMessageContext reply_context = context->MakeReplyMessageContext(); + reply_context.params.set_result(PP_ERROR_FAILED); + host()->SendReply(reply_context, + PpapiPluginMsg_FileIO_ReadReply(std::string())); + return PP_OK_COMPLETIONPENDING; + } + + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + if (!base::FileUtilProxy::Read( + plugin_delegate_->GetFileThreadMessageLoopProxy(), file_, offset, + max_read_length, + base::Bind(&PepperFileIOHost::ExecutePlatformReadCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgWrite( + ppapi::host::HostMessageContext* context, + int64_t offset, + const std::string& buffer) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_WRITE, true); + if (rv != PP_OK) + return rv; + + if (quota_file_io_.get()) { + if (!quota_file_io_->Write( + offset, buffer.c_str(), buffer.size(), + base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + } else { + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + if (!base::FileUtilProxy::Write( + plugin_delegate_->GetFileThreadMessageLoopProxy(), file_, offset, + buffer.c_str(), buffer.size(), + base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + } + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgSetLength( + ppapi::host::HostMessageContext* context, + int64_t length) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { + if (!plugin_delegate_->SetLength( + file_system_url_, length, + new PlatformGeneralCallbackTranslator( + base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext())))) + return PP_ERROR_FAILED; + } else { + // TODO(nhiroki): fix a failure of FileIO.SetLength for an external + // filesystem on Mac due to sandbox restrictions (http://crbug.com/156077). + if (!base::FileUtilProxy::Truncate( + plugin_delegate_->GetFileThreadMessageLoopProxy(), file_, length, + base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + } + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgFlush( + ppapi::host::HostMessageContext* context) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + if (!plugin_delegate_) + return PP_ERROR_FAILED; + + if (!base::FileUtilProxy::Flush( + plugin_delegate_->GetFileThreadMessageLoopProxy(), file_, + base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgClose( + ppapi::host::HostMessageContext* context) { + if (file_ != base::kInvalidPlatformFileValue && plugin_delegate_) { + base::FileUtilProxy::Close( + plugin_delegate_->GetFileThreadMessageLoopProxy(), + file_, + base::ResetAndReturn(¬ify_close_file_callback_)); + file_ = base::kInvalidPlatformFileValue; + quota_file_io_.reset(); + } + return PP_OK; +} + +int32_t PepperFileIOHost::OnHostMsgWillWrite( + ppapi::host::HostMessageContext* context, + int64_t offset, + int32_t bytes_to_write) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + if (!quota_file_io_.get()) + return PP_OK; + + if (!quota_file_io_->WillWrite( + offset, bytes_to_write, + base::Bind(&PepperFileIOHost::ExecutePlatformWillWriteCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgWillSetLength( + ppapi::host::HostMessageContext* context, + int64_t length) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + if (!quota_file_io_.get()) + return PP_OK; + + if (!quota_file_io_->WillSetLength( + length, + base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext()))) + return PP_ERROR_FAILED; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFileIOHost::OnHostMsgGetOSFileDescriptor( + ppapi::host::HostMessageContext* context) { + if (!is_running_in_process_) + return PP_ERROR_FAILED; + int32_t fd = +#if defined(OS_POSIX) + file_; +#elif defined(OS_WIN) + reinterpret_cast<uintptr_t>(file_); +#else + -1; // Platform not supported. +#endif + // TODO(victorhsieh): Pass the file handle in the reply params once this works + // in-process. + host()->SendReply(context->MakeReplyMessageContext(), + PpapiPluginMsg_FileIO_GetOSFileDescriptorReply(fd)); + return PP_OK_COMPLETIONPENDING; +} + +void PepperFileIOHost::ExecutePlatformGeneralCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code) { + reply_context.params.set_result( + ::ppapi::PlatformFileErrorToPepperError(error_code)); + host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); + state_manager_.SetOperationFinished(); +} + +void PepperFileIOHost::ExecutePlatformOpenFileCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code, + base::PassPlatformFile file) { + int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); + if (pp_error == PP_OK) + state_manager_.SetOpenSucceed(); + + DCHECK(file_ == base::kInvalidPlatformFileValue); + file_ = file.ReleaseValue(); + + DCHECK(!quota_file_io_.get()); + if (file_ != base::kInvalidPlatformFileValue && + (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY || + file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT)) { + quota_file_io_.reset(new webkit::ppapi::QuotaFileIO( + pp_instance(), file_, file_system_url_, file_system_type_)); + } + + reply_context.params.set_result(pp_error); + host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply()); + state_manager_.SetOperationFinished(); +} + +void PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code, + base::PassPlatformFile file, + const PluginDelegate::NotifyCloseFileCallback& callback) { + if (error_code == base::PLATFORM_FILE_OK) + notify_close_file_callback_ = callback; + ExecutePlatformOpenFileCallback(reply_context, error_code, file); +} + +void PepperFileIOHost::ExecutePlatformQueryCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code, + const base::PlatformFileInfo& file_info) { + PP_FileInfo pp_info; + pp_info.size = file_info.size; + pp_info.creation_time = TimeToPPTime(file_info.creation_time); + pp_info.last_access_time = TimeToPPTime(file_info.last_accessed); + pp_info.last_modified_time = TimeToPPTime(file_info.last_modified); + pp_info.system_type = file_system_type_; + if (file_info.is_directory) + pp_info.type = PP_FILETYPE_DIRECTORY; + else + pp_info.type = PP_FILETYPE_REGULAR; + + int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); + reply_context.params.set_result(pp_error); + host()->SendReply(reply_context, + PpapiPluginMsg_FileIO_QueryReply(pp_info)); + state_manager_.SetOperationFinished(); +} + +void PepperFileIOHost::ExecutePlatformReadCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code, + const char* data, int bytes_read) { + int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); + + // Only send the amount of data in the string that was actually read. + std::string buffer; + if (pp_error == PP_OK) + buffer.append(data, bytes_read); + reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_read)); + host()->SendReply(reply_context, PpapiPluginMsg_FileIO_ReadReply(buffer)); + state_manager_.SetOperationFinished(); +} + +void PepperFileIOHost::ExecutePlatformWriteCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code, + int bytes_written) { + int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); + reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written)); + host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); + state_manager_.SetOperationFinished(); +} + +void PepperFileIOHost::ExecutePlatformWillWriteCallback( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error_code, + int bytes_written) { + // On the plugin side, the callback expects a parameter with different meaning + // depends on whether is negative or not. It is the result here. We translate + // for the callback. + int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); + reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written)); + host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); + state_manager_.SetOperationFinished(); +} + +} // namespace content + diff --git a/content/renderer/pepper/pepper_file_io_host.h b/content/renderer/pepper/pepper_file_io_host.h new file mode 100644 index 0000000..b66cb6f --- /dev/null +++ b/content/renderer/pepper/pepper_file_io_host.h @@ -0,0 +1,129 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/weak_ptr.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/shared_impl/file_io_state_manager.h" +#include "ppapi/thunk/ppb_file_ref_api.h" +#include "webkit/plugins/ppapi/plugin_delegate.h" + +using ppapi::host::ReplyMessageContext; +using webkit::ppapi::PluginDelegate; + +namespace webkit { +namespace ppapi { +class QuotaFileIO; +} // namespace ppapi +} // namespace webkit + +namespace content { + +class PepperFileIOHost : public ppapi::host::ResourceHost, + public base::SupportsWeakPtr<PepperFileIOHost> { + public: + PepperFileIOHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + virtual ~PepperFileIOHost(); + + // ppapi::host::ResourceHost override. + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + private: + int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context, + PP_Resource file_ref_resource, + int32_t open_flags); + int32_t OnHostMsgQuery(ppapi::host::HostMessageContext* context); + int32_t OnHostMsgTouch(ppapi::host::HostMessageContext* context, + PP_Time last_access_time, + PP_Time last_modified_time); + int32_t OnHostMsgRead(ppapi::host::HostMessageContext* context, + int64_t offset, + int32_t bytes_to_read); + int32_t OnHostMsgWrite(ppapi::host::HostMessageContext* context, + int64_t offset, + const std::string& buffer); + int32_t OnHostMsgSetLength(ppapi::host::HostMessageContext* context, + int64_t length); + int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context); + int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context); + // Trusted API. + int32_t OnHostMsgGetOSFileDescriptor( + ppapi::host::HostMessageContext* context); + int32_t OnHostMsgWillWrite(ppapi::host::HostMessageContext* context, + int64_t offset, + int32_t bytes_to_write); + int32_t OnHostMsgWillSetLength(ppapi::host::HostMessageContext* context, + int64_t length); + + // Callback handlers. These mostly convert the PlatformFileError to the + // PP_Error code and send back the reply. Note that the argument + // ReplyMessageContext is copied so that we have a closure containing all + // necessary information to reply. + void ExecutePlatformGeneralCallback(ReplyMessageContext reply_context, + base::PlatformFileError error_code); + void ExecutePlatformOpenFileCallback(ReplyMessageContext reply_context, + base::PlatformFileError error_code, + base::PassPlatformFile file); + void ExecutePlatformOpenFileSystemURLCallback( + ReplyMessageContext reply_context, + base::PlatformFileError error_code, + base::PassPlatformFile file, + const PluginDelegate::NotifyCloseFileCallback& callback); + void ExecutePlatformQueryCallback(ReplyMessageContext reply_context, + base::PlatformFileError error_code, + const base::PlatformFileInfo& file_info); + void ExecutePlatformReadCallback(ReplyMessageContext reply_context, + base::PlatformFileError error_code, + const char* data, int bytes_read); + void ExecutePlatformWriteCallback(ReplyMessageContext reply_context, + base::PlatformFileError error_code, + int bytes_written); + void ExecutePlatformWillWriteCallback(ReplyMessageContext reply_context, + base::PlatformFileError error_code, + int bytes_written); + + // TODO(victorhsieh): eliminate plugin_delegate_ as it's no longer needed. + webkit::ppapi::PluginDelegate* plugin_delegate_; // Not owned. + + base::PlatformFile file_; + + // The file system type specified in the Open() call. This will be + // PP_FILESYSTEMTYPE_INVALID before open was called. This value does not + // indicate that the open command actually succeeded. + PP_FileSystemType file_system_type_; + + // Valid only for PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}. + GURL file_system_url_; + + // Callback function for notifying when the file handle is closed. + PluginDelegate::NotifyCloseFileCallback notify_close_file_callback_; + + // Pointer to a QuotaFileIO instance, which is valid only while a file + // of type PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY} is opened. + scoped_ptr<webkit::ppapi::QuotaFileIO> quota_file_io_; + + bool is_running_in_process_; + + base::WeakPtrFactory<PepperFileIOHost> weak_factory_; + + ppapi::FileIOStateManager state_manager_; + + DISALLOW_COPY_AND_ASSIGN(PepperFileIOHost); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_FILE_IO_HOST_H_ + diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.cc b/content/renderer/pepper/pepper_in_process_resource_creation.cc index 3d6d12b..5976b68 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.cc +++ b/content/renderer/pepper/pepper_in_process_resource_creation.cc @@ -15,6 +15,7 @@ #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/browser_font_resource_trusted.h" #include "ppapi/proxy/file_chooser_resource.h" +#include "ppapi/proxy/file_io_resource.h" #include "ppapi/proxy/graphics_2d_resource.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/printing_resource.h" @@ -68,6 +69,13 @@ PP_Resource PepperInProcessResourceCreation::CreateFileChooser( instance, mode, accept_types))->GetReference(); } +PP_Resource PepperInProcessResourceCreation::CreateFileIO( + PP_Instance instance) { + return (new ppapi::proxy::FileIOResource( + host_impl_->in_process_router()->GetPluginConnection(), + instance))->GetReference(); +} + PP_Resource PepperInProcessResourceCreation::CreateGraphics2D( PP_Instance instance, const PP_Size& size, diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.h b/content/renderer/pepper/pepper_in_process_resource_creation.h index 8972d83..93df2af 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.h +++ b/content/renderer/pepper/pepper_in_process_resource_creation.h @@ -49,6 +49,7 @@ class PepperInProcessResourceCreation PP_Instance instance, PP_FileChooserMode_Dev mode, const char* accept_types) OVERRIDE; + virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateGraphics2D( PP_Instance pp_instance, const PP_Size& size, diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index e8cb024..156c969 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -85,7 +85,6 @@ #include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" -#include "webkit/plugins/ppapi/ppb_file_io_impl.h" #include "webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h" #include "webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h" #include "webkit/plugins/ppapi/ppb_udp_socket_private_impl.h" diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index ef4e834b..552dcf3 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -53,6 +53,8 @@ 'proxy/flash_menu_resource.h', 'proxy/flash_resource.cc', 'proxy/flash_resource.h', + 'proxy/file_io_resource.cc', + 'proxy/file_io_resource.h', 'proxy/gamepad_resource.cc', 'proxy/gamepad_resource.h', 'proxy/host_dispatcher.cc', @@ -91,8 +93,6 @@ 'proxy/ppb_buffer_proxy.h', 'proxy/ppb_core_proxy.cc', 'proxy/ppb_core_proxy.h', - 'proxy/ppb_file_io_proxy.cc', - 'proxy/ppb_file_io_proxy.h', 'proxy/ppb_file_ref_proxy.cc', 'proxy/ppb_file_ref_proxy.h', 'proxy/ppb_file_system_proxy.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index ad03525..12f0e87 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -24,6 +24,8 @@ 'shared_impl/array_writer.h', 'shared_impl/callback_tracker.cc', 'shared_impl/callback_tracker.h', + 'shared_impl/file_io_state_manager.cc', + 'shared_impl/file_io_state_manager.h', 'shared_impl/file_path.cc', 'shared_impl/file_path.h', 'shared_impl/file_type_conversion.cc', @@ -51,8 +53,6 @@ 'shared_impl/ppb_crypto_shared.cc', 'shared_impl/ppb_device_ref_shared.cc', 'shared_impl/ppb_device_ref_shared.h', - 'shared_impl/ppb_file_io_shared.cc', - 'shared_impl/ppb_file_io_shared.h', 'shared_impl/ppb_file_ref_shared.cc', 'shared_impl/ppb_file_ref_shared.h', 'shared_impl/ppb_gamepad_shared.cc', diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc new file mode 100644 index 0000000..77105a1 --- /dev/null +++ b/ppapi/proxy/file_io_resource.cc @@ -0,0 +1,291 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/file_io_resource.h" + +#include "base/bind.h" +#include "ipc/ipc_message.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/array_writer.h" +#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/resource_tracker.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_file_ref_api.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_FileIO_API; +using ppapi::thunk::PPB_FileRef_API; + +namespace { + +// An adapter to let Read() share the same implementation with ReadToArray(). +void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { + return user_data; +} + +} // namespace + +namespace ppapi { +namespace proxy { + +FileIOResource::FileIOResource(Connection connection, PP_Instance instance) + : PluginResource(connection, instance) { + SendCreate(RENDERER, PpapiHostMsg_FileIO_Create()); +} + +FileIOResource::~FileIOResource() { +} + +PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { + return this; +} + +int32_t FileIOResource::Open(PP_Resource file_ref, + int32_t open_flags, + scoped_refptr<TrackedCallback> callback) { + EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; + + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, false); + if (rv != PP_OK) + return rv; + + Call<PpapiPluginMsg_FileIO_OpenReply>(RENDERER, + PpapiHostMsg_FileIO_Open( + enter.resource()->host_resource().host_resource(), + open_flags), + base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, + callback)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::Query(PP_FileInfo* info, + scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + Call<PpapiPluginMsg_FileIO_QueryReply>(RENDERER, + PpapiHostMsg_FileIO_Query(), + base::Bind(&FileIOResource::OnPluginMsgQueryComplete, this, + callback, info)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::Touch(PP_Time last_access_time, + PP_Time last_modified_time, + scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, + PpapiHostMsg_FileIO_Touch(last_access_time, last_modified_time), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::Read(int64_t offset, + char* buffer, + int32_t bytes_to_read, + scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_READ, true); + if (rv != PP_OK) + return rv; + + PP_ArrayOutput output_adapter; + output_adapter.GetDataBuffer = &DummyGetDataBuffer; + output_adapter.user_data = buffer; + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); + return ReadValidated(offset, bytes_to_read, output_adapter, callback); +} + +int32_t FileIOResource::ReadToArray(int64_t offset, + int32_t max_read_length, + PP_ArrayOutput* array_output, + scoped_refptr<TrackedCallback> callback) { + DCHECK(array_output); + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_READ, true); + if (rv != PP_OK) + return rv; + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); + return ReadValidated(offset, max_read_length, *array_output, callback); +} + +int32_t FileIOResource::Write(int64_t offset, + const char* buffer, + int32_t bytes_to_write, + scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_WRITE, true); + if (rv != PP_OK) + return rv; + + // TODO(brettw) it would be nice to use a shared memory buffer for large + // writes rather than having to copy to a string (which will involve a number + // of extra copies to serialize over IPC). + Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, + PpapiHostMsg_FileIO_Write(offset, std::string(buffer, bytes_to_write)), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::SetLength(int64_t length, + scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, + PpapiHostMsg_FileIO_SetLength(length), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::Flush(scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, + PpapiHostMsg_FileIO_Flush(), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +void FileIOResource::Close() { + Post(RENDERER, PpapiHostMsg_FileIO_Close()); +} + +int32_t FileIOResource::GetOSFileDescriptor() { + int32_t file_descriptor; + // Only available when running in process. + SyncCall<PpapiPluginMsg_FileIO_GetOSFileDescriptorReply>( + RENDERER, PpapiHostMsg_FileIO_GetOSFileDescriptor(), &file_descriptor); + return file_descriptor; +} + +int32_t FileIOResource::WillWrite(int64_t offset, + int32_t bytes_to_write, + scoped_refptr<TrackedCallback> callback) { + Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, + PpapiHostMsg_FileIO_WillWrite(offset, bytes_to_write), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::WillSetLength(int64_t length, + scoped_refptr<TrackedCallback> callback) { + Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, + PpapiHostMsg_FileIO_WillSetLength(length), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileIOResource::ReadValidated(int64_t offset, + int32_t bytes_to_read, + const PP_ArrayOutput& array_output, + scoped_refptr<TrackedCallback> callback) { + Call<PpapiPluginMsg_FileIO_ReadReply>(RENDERER, + PpapiHostMsg_FileIO_Read(offset, bytes_to_read), + base::Bind(&FileIOResource::OnPluginMsgReadComplete, this, + callback, array_output)); + return PP_OK_COMPLETIONPENDING; +} + +void FileIOResource::OnPluginMsgGeneralComplete( + scoped_refptr<TrackedCallback> callback, + const ResourceMessageReplyParams& params) { + DCHECK(state_manager_.get_pending_operation() == + FileIOStateManager::OPERATION_EXCLUSIVE || + state_manager_.get_pending_operation() == + FileIOStateManager::OPERATION_WRITE); + // End the operation now. The callback may perform another file operation. + state_manager_.SetOperationFinished(); + callback->Run(params.result()); +} + +void FileIOResource::OnPluginMsgOpenFileComplete( + scoped_refptr<TrackedCallback> callback, + const ResourceMessageReplyParams& params) { + DCHECK(state_manager_.get_pending_operation() == + FileIOStateManager::OPERATION_EXCLUSIVE); + if (params.result() == PP_OK) + state_manager_.SetOpenSucceed(); + // End the operation now. The callback may perform another file operation. + state_manager_.SetOperationFinished(); + callback->Run(params.result()); +} + +void FileIOResource::OnPluginMsgQueryComplete( + scoped_refptr<TrackedCallback> callback, + PP_FileInfo* output_info, + const ResourceMessageReplyParams& params, + const PP_FileInfo& info) { + DCHECK(state_manager_.get_pending_operation() == + FileIOStateManager::OPERATION_EXCLUSIVE); + *output_info = info; + // End the operation now. The callback may perform another file operation. + state_manager_.SetOperationFinished(); + callback->Run(params.result()); +} + +void FileIOResource::OnPluginMsgReadComplete( + scoped_refptr<TrackedCallback> callback, + PP_ArrayOutput array_output, + const ResourceMessageReplyParams& params, + const std::string& data) { + DCHECK(state_manager_.get_pending_operation() == + FileIOStateManager::OPERATION_READ); + + // The result code should contain the data size if it's positive. + int32_t result = params.result(); + DCHECK((result < 0 && data.size() == 0) || + result == static_cast<int32_t>(data.size())); + + ArrayWriter output; + output.set_pp_array_output(array_output); + if (output.is_valid()) + output.StoreArray(data.data(), std::max(0, result)); + else + result = PP_ERROR_FAILED; + + // End the operation now. The callback may perform another file operation. + state_manager_.SetOperationFinished(); + callback->Run(result); +} + +} // namespace proxy +} // namespace ppapi + diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h new file mode 100644 index 0000000..f5a1aa8 --- /dev/null +++ b/ppapi/proxy/file_io_resource.h @@ -0,0 +1,95 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PROXY_FILE_IO_RESOURCE_H_ +#define PPAPI_PROXY_FILE_IO_RESOURCE_H_ + +#include <string> + +#include "ppapi/proxy/connection.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/ppapi_proxy_export.h" +#include "ppapi/shared_impl/file_io_state_manager.h" +#include "ppapi/thunk/ppb_file_io_api.h" + +namespace ppapi { + +class TrackedCallback; + +namespace proxy { + +class PPAPI_PROXY_EXPORT FileIOResource + : public PluginResource, + public thunk::PPB_FileIO_API { + public: + FileIOResource(Connection connection, PP_Instance instance); + virtual ~FileIOResource(); + + // Resource overrides. + virtual thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE; + + // PPB_FileIO_API implementation. + virtual int32_t Open(PP_Resource file_ref, + int32_t open_flags, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Query(PP_FileInfo* info, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Touch(PP_Time last_access_time, + PP_Time last_modified_time, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Read(int64_t offset, + char* buffer, + int32_t bytes_to_read, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t ReadToArray(int64_t offset, + int32_t max_read_length, + PP_ArrayOutput* array_output, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Write(int64_t offset, + const char* buffer, + int32_t bytes_to_write, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t SetLength(int64_t length, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual void Close() OVERRIDE; + virtual int32_t GetOSFileDescriptor() OVERRIDE; + virtual int32_t WillWrite(int64_t offset, + int32_t bytes_to_write, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t WillSetLength( + int64_t length, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + + private: + int32_t ReadValidated(int64_t offset, + int32_t bytes_to_read, + const PP_ArrayOutput& array_output, + scoped_refptr<TrackedCallback> callback); + + // Handlers of reply messages. Note that all of them have a callback + // parameters bound when call to the host. + void OnPluginMsgGeneralComplete(scoped_refptr<TrackedCallback> callback, + const ResourceMessageReplyParams& params); + void OnPluginMsgOpenFileComplete(scoped_refptr<TrackedCallback> callback, + const ResourceMessageReplyParams& params); + void OnPluginMsgQueryComplete(scoped_refptr<TrackedCallback> callback, + PP_FileInfo* output_info_, + const ResourceMessageReplyParams& params, + const PP_FileInfo& info); + void OnPluginMsgReadComplete(scoped_refptr<TrackedCallback> callback, + PP_ArrayOutput array_output, + const ResourceMessageReplyParams& params, + const std::string& data); + + FileIOStateManager state_manager_; + + DISALLOW_COPY_AND_ASSIGN(FileIOResource); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_ + diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index 51fe853..1cb27d1 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -81,7 +81,6 @@ #include "ppapi/proxy/ppb_broker_proxy.h" #include "ppapi/proxy/ppb_buffer_proxy.h" #include "ppapi/proxy/ppb_core_proxy.h" -#include "ppapi/proxy/ppb_file_io_proxy.h" #include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/proxy/ppb_file_system_proxy.h" #include "ppapi/proxy/ppb_flash_message_loop_proxy.h" diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index e893053..b4666e4 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -430,22 +430,6 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, ppapi::proxy::SerializedHandle /* socket_handle */, ppapi::proxy::SerializedHandle /* handle */) -// PPB_FileIO. -IPC_MESSAGE_ROUTED2(PpapiMsg_PPBFileIO_GeneralComplete, - ppapi::HostResource /* file_io */, - int32_t /* result */) -IPC_MESSAGE_ROUTED2(PpapiMsg_PPBFileIO_OpenFileComplete, - ppapi::HostResource /* file_io */, - int32_t /* result */) -IPC_MESSAGE_ROUTED3(PpapiMsg_PPBFileIO_QueryComplete, - ppapi::HostResource /* file_io */, - int32_t /* result */, - PP_FileInfo /* info */) -IPC_MESSAGE_ROUTED3(PpapiMsg_PPBFileIO_ReadComplete, - ppapi::HostResource /* file_io */, - int32_t /* result */, - std::string /* data */) - // PPB_FileRef. IPC_MESSAGE_ROUTED3( PpapiMsg_PPBFileRef_CallbackComplete, @@ -804,43 +788,6 @@ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_AddRefResource, IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_ReleaseResource, ppapi::HostResource) -// PPB_FileIO. -IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBFileIO_Create, - PP_Instance /* instance */, - ppapi::HostResource /* result */) -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileIO_Open, - ppapi::HostResource /* host_resource */, - ppapi::HostResource /* file_ref_resource */, - int32_t /* open_flags */) -IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBFileIO_Close, - ppapi::HostResource /* host_resource */) -IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBFileIO_Query, - ppapi::HostResource /* host_resource */) -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileIO_Touch, - ppapi::HostResource /* host_resource */, - PP_Time /* last_access_time */, - PP_Time /* last_modified_time */) -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileIO_Read, - ppapi::HostResource /* host_resource */, - int64_t /* offset */, - int32_t /* bytes_to_read */) -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileIO_Write, - ppapi::HostResource /* host_resource */, - int64_t /* offset */, - std::string /* data */) -IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBFileIO_SetLength, - ppapi::HostResource /* host_resource */, - int64_t /* length */) -IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBFileIO_Flush, - ppapi::HostResource /* host_resource */) -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileIO_WillWrite, - ppapi::HostResource /* host_resource */, - int64_t /* offset */, - int32_t /* bytes_to_write */) -IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBFileIO_WillSetLength, - ppapi::HostResource /* host_resource */, - int64_t /* length */) - // PPB_FileRef. IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFileRef_Create, ppapi::HostResource /* file_system */, @@ -1400,6 +1347,38 @@ IPC_MESSAGE_CONTROL4(PpapiHostMsg_FileChooser_Show, IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileChooser_ShowReply, std::vector<ppapi::PPB_FileRef_CreateInfo> /* files */) +// FileIO +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Create) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Open, + PP_Resource /* file_ref_resource */, + int32_t /* open_flags */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_OpenReply) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Close) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Query) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileIO_QueryReply, PP_FileInfo /* info */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Touch, + PP_Time /* last_access_time */, + PP_Time /* last_modified_time */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Read, + int64_t /* offset */, + int32_t /* bytes_to_read */) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileIO_ReadReply, std::string /* data */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Write, + int64_t /* offset */, + std::string /* data */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_SetLength, + int64_t /* length */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Flush) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_WillWrite, + int64_t /* offset */, + int32_t /* bytes_to_write */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_WillSetLength, + int64_t /* length */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_GetOSFileDescriptor) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileIO_GetOSFileDescriptorReply, + int32_t /* file descriptor */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_GeneralReply) + // Flash device ID. IPC_MESSAGE_CONTROL0(PpapiHostMsg_FlashDeviceID_Create) IPC_MESSAGE_CONTROL0(PpapiHostMsg_FlashDeviceID_GetDeviceID) diff --git a/ppapi/proxy/ppb_file_io_proxy.cc b/ppapi/proxy/ppb_file_io_proxy.cc deleted file mode 100644 index 002efdf..0000000 --- a/ppapi/proxy/ppb_file_io_proxy.cc +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ppapi/proxy/ppb_file_io_proxy.h" - -#include "ppapi/c/pp_errors.h" -#include "ppapi/proxy/enter_proxy.h" -#include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/proxy/ppb_file_ref_proxy.h" -#include "ppapi/shared_impl/ppapi_globals.h" -#include "ppapi/shared_impl/ppb_file_io_shared.h" -#include "ppapi/shared_impl/resource.h" -#include "ppapi/shared_impl/resource_tracker.h" - -using ppapi::thunk::PPB_FileIO_API; -using ppapi::thunk::PPB_FileRef_API; - -namespace ppapi { -namespace proxy { - -namespace { - -// The maximum size we'll support reading in one chunk. The renderer process -// must allocate a buffer sized according to the request of the plugin. To -// keep things from getting out of control, we cap the read size to this value. -// This should generally be OK since the API specifies that it may perform a -// partial read. -static const int32_t kMaxReadSize = 33554432; // 32MB - -#if !defined(OS_NACL) -typedef EnterHostFromHostResourceForceCallback<PPB_FileIO_API> EnterHostFileIO; -#endif -typedef EnterPluginFromHostResource<PPB_FileIO_API> EnterPluginFileIO; - -class FileIO : public PPB_FileIO_Shared { - public: - explicit FileIO(const HostResource& host_resource); - virtual ~FileIO(); - - // PPB_FileIO_API implementation (not provided by FileIOImpl). - virtual void Close() OVERRIDE; - virtual int32_t GetOSFileDescriptor() OVERRIDE; - virtual int32_t WillWrite(int64_t offset, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t WillSetLength( - int64_t length, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - - private: - // FileIOImpl overrides. - virtual int32_t OpenValidated( - PP_Resource file_ref_resource, - PPB_FileRef_API* file_ref_api, - int32_t open_flags, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t QueryValidated( - PP_FileInfo* info, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t TouchValidated( - PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t ReadValidated( - int64_t offset, - const PP_ArrayOutput& output_array_buffer, - int32_t max_read_length, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t WriteValidated( - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t SetLengthValidated( - int64_t length, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t FlushValidated( - scoped_refptr<TrackedCallback> callback) OVERRIDE; - - PluginDispatcher* GetDispatcher() const { - return PluginDispatcher::GetForResource(this); - } - - static const ApiID kApiID = API_ID_PPB_FILE_IO; - - DISALLOW_IMPLICIT_CONSTRUCTORS(FileIO); -}; - -FileIO::FileIO(const HostResource& host_resource) - : PPB_FileIO_Shared(host_resource) { -} - -FileIO::~FileIO() { - Close(); -} - -void FileIO::Close() { - if (file_open_) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Close(kApiID, - host_resource())); - } -} - -int32_t FileIO::GetOSFileDescriptor() { - return -1; -} - -int32_t FileIO::WillWrite(int64_t offset, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_WillWrite( - kApiID, host_resource(), offset, bytes_to_write)); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::WillSetLength(int64_t length, - scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_WillSetLength( - kApiID, host_resource(), length)); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::OpenValidated(PP_Resource file_ref_resource, - PPB_FileRef_API* file_ref_api, - int32_t open_flags, - scoped_refptr<TrackedCallback> callback) { - Resource* file_ref_object = - PpapiGlobals::Get()->GetResourceTracker()->GetResource(file_ref_resource); - - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Open( - kApiID, host_resource(), file_ref_object->host_resource(), open_flags)); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::QueryValidated(PP_FileInfo* info, - scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Query( - kApiID, host_resource())); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, info); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::TouchValidated(PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Touch( - kApiID, host_resource(), last_access_time, last_modified_time)); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::ReadValidated(int64_t offset, - const PP_ArrayOutput& output_array_buffer, - int32_t max_read_length, - scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Read( - kApiID, host_resource(), offset, max_read_length)); - RegisterCallback(OPERATION_READ, callback, &output_array_buffer, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::WriteValidated(int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - // TODO(brettw) it would be nice to use a shared memory buffer for large - // writes rather than having to copy to a string (which will involve a number - // of extra copies to serialize over IPC). - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Write( - kApiID, host_resource(), offset, std::string(buffer, bytes_to_write))); - RegisterCallback(OPERATION_WRITE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::SetLengthValidated(int64_t length, - scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_SetLength( - kApiID, host_resource(), length)); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t FileIO::FlushValidated(scoped_refptr<TrackedCallback> callback) { - GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Flush( - kApiID, host_resource())); - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -} // namespace - -// ----------------------------------------------------------------------------- - -PPB_FileIO_Proxy::PPB_FileIO_Proxy(Dispatcher* dispatcher) - : InterfaceProxy(dispatcher), - callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { -} - -PPB_FileIO_Proxy::~PPB_FileIO_Proxy() { -} - -// static -PP_Resource PPB_FileIO_Proxy::CreateProxyResource(PP_Instance instance) { - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return 0; - - HostResource result; - dispatcher->Send(new PpapiHostMsg_PPBFileIO_Create(kApiID, instance, - &result)); - if (result.is_null()) - return 0; - return (new FileIO(result))->GetReference(); -} - -bool PPB_FileIO_Proxy::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PPB_FileIO_Proxy, msg) - #if !defined(OS_NACL) - // Plugin -> host message. - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Create, OnHostMsgCreate) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Open, OnHostMsgOpen) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Close, OnHostMsgClose) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Query, OnHostMsgQuery) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Touch, OnHostMsgTouch) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Read, OnHostMsgRead) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Write, OnHostMsgWrite) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_SetLength, OnHostMsgSetLength) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Flush, OnHostMsgFlush) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_WillWrite, OnHostMsgWillWrite) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_WillSetLength, - OnHostMsgWillSetLength) -#endif // !defined(OS_NACL) - // Host -> plugin messages. - IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_GeneralComplete, - OnPluginMsgGeneralComplete) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_OpenFileComplete, - OnPluginMsgOpenFileComplete) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_QueryComplete, - OnPluginMsgQueryComplete) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_ReadComplete, - OnPluginMsgReadComplete) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -#if !defined(OS_NACL) -void PPB_FileIO_Proxy::OnHostMsgCreate(PP_Instance instance, - HostResource* result) { - thunk::EnterResourceCreation enter(instance); - if (enter.succeeded()) { - result->SetHostResource(instance, - enter.functions()->CreateFileIO(instance)); - } -} - -void PPB_FileIO_Proxy::OnHostMsgOpen(const HostResource& host_resource, - const HostResource& file_ref_resource, - int32_t open_flags) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::OpenFileCallbackCompleteInHost, host_resource); - if (enter.succeeded()) { - enter.SetResult(enter.object()->Open( - file_ref_resource.host_resource(), open_flags, enter.callback())); - } -} - -void PPB_FileIO_Proxy::OnHostMsgClose(const HostResource& host_resource) { - EnterHostFromHostResource<PPB_FileIO_API> enter(host_resource); - if (enter.succeeded()) - enter.object()->Close(); -} - -void PPB_FileIO_Proxy::OnHostMsgQuery(const HostResource& host_resource) { - // The callback will take charge of deleting the FileInfo. The contents must - // be defined so we don't send garbage to the plugin in the failure case. - PP_FileInfo* info = new PP_FileInfo; - memset(info, 0, sizeof(PP_FileInfo)); - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::QueryCallbackCompleteInHost, - host_resource, info); - if (enter.succeeded()) - enter.SetResult(enter.object()->Query(info, enter.callback())); -} - -void PPB_FileIO_Proxy::OnHostMsgTouch(const HostResource& host_resource, - PP_Time last_access_time, - PP_Time last_modified_time) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost, - host_resource); - if (enter.succeeded()) { - enter.SetResult(enter.object()->Touch(last_access_time, last_modified_time, - enter.callback())); - } -} - -void PPB_FileIO_Proxy::OnHostMsgRead(const HostResource& host_resource, - int64_t offset, - int32_t bytes_to_read) { - // Validate bytes_to_read before allocating below. This value is coming from - // the untrusted plugin. - bytes_to_read = std::min(bytes_to_read, kMaxReadSize); - if (bytes_to_read < 0) { - ReadCallbackCompleteInHost(PP_ERROR_FAILED, host_resource, - new std::string()); - return; - } - - // The callback will take charge of deleting the string. - std::string* dest = new std::string; - dest->resize(bytes_to_read); - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::ReadCallbackCompleteInHost, - host_resource, dest); - if (enter.succeeded()) { - enter.SetResult(enter.object()->Read(offset, - bytes_to_read > 0 ? &(*dest)[0] : NULL, - bytes_to_read, enter.callback())); - } -} - -void PPB_FileIO_Proxy::OnHostMsgWrite(const HostResource& host_resource, - int64_t offset, - const std::string& data) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost, - host_resource); - if (enter.succeeded()) { - enter.SetResult(enter.object()->Write(offset, data.data(), data.size(), - enter.callback())); - } -} - -void PPB_FileIO_Proxy::OnHostMsgSetLength(const HostResource& host_resource, - int64_t length) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost, - host_resource); - if (enter.succeeded()) - enter.SetResult(enter.object()->SetLength(length, enter.callback())); -} - -void PPB_FileIO_Proxy::OnHostMsgFlush(const HostResource& host_resource) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost, - host_resource); - if (enter.succeeded()) - enter.SetResult(enter.object()->Flush(enter.callback())); -} - -void PPB_FileIO_Proxy::OnHostMsgWillWrite(const HostResource& host_resource, - int64_t offset, - int32_t bytes_to_write) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost, - host_resource); - if (enter.succeeded()) { - enter.SetResult(enter.object()->WillWrite(offset, bytes_to_write, - enter.callback())); - } -} - -void PPB_FileIO_Proxy::OnHostMsgWillSetLength(const HostResource& host_resource, - int64_t length) { - EnterHostFileIO enter(host_resource, callback_factory_, - &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost, - host_resource); - if (enter.succeeded()) - enter.SetResult(enter.object()->WillSetLength(length, enter.callback())); -} -#endif // !defined(OS_NACL) - -void PPB_FileIO_Proxy::OnPluginMsgGeneralComplete( - const HostResource& host_resource, - int32_t result) { - EnterPluginFileIO enter(host_resource); - if (enter.succeeded()) - static_cast<FileIO*>(enter.object())->ExecuteGeneralCallback(result); -} - -void PPB_FileIO_Proxy::OnPluginMsgOpenFileComplete( - const HostResource& host_resource, - int32_t result) { - EnterPluginFileIO enter(host_resource); - if (enter.succeeded()) - static_cast<FileIO*>(enter.object())->ExecuteOpenFileCallback(result); -} - -void PPB_FileIO_Proxy::OnPluginMsgQueryComplete( - const HostResource& host_resource, - int32_t result, - const PP_FileInfo& info) { - EnterPluginFileIO enter(host_resource); - if (enter.succeeded()) - static_cast<FileIO*>(enter.object())->ExecuteQueryCallback(result, info); -} - -void PPB_FileIO_Proxy::OnPluginMsgReadComplete( - const HostResource& host_resource, - int32_t result, - const std::string& data) { - EnterPluginFileIO enter(host_resource); - if (enter.succeeded()) { - // The result code should contain the data size if it's positive. - DCHECK((result < 0 && data.size() == 0) || - result == static_cast<int32_t>(data.size())); - static_cast<FileIO*>(enter.object())->ExecuteReadCallback(result, - data.data()); - } -} - -#if !defined(OS_NACL) -void PPB_FileIO_Proxy::GeneralCallbackCompleteInHost( - int32_t pp_error, - const HostResource& host_resource) { - Send(new PpapiMsg_PPBFileIO_GeneralComplete(kApiID, host_resource, pp_error)); -} - -void PPB_FileIO_Proxy::OpenFileCallbackCompleteInHost( - int32_t pp_error, - const HostResource& host_resource) { - Send(new PpapiMsg_PPBFileIO_OpenFileComplete(kApiID, host_resource, - pp_error)); -} - -void PPB_FileIO_Proxy::QueryCallbackCompleteInHost( - int32_t pp_error, - const HostResource& host_resource, - PP_FileInfo* info) { - Send(new PpapiMsg_PPBFileIO_QueryComplete(kApiID, host_resource, pp_error, - *info)); - delete info; -} - -void PPB_FileIO_Proxy::ReadCallbackCompleteInHost( - int32_t pp_error, - const HostResource& host_resource, - std::string* data) { - // Only send the amount of data in the string that was actually read. - if (pp_error >= 0) { - DCHECK(pp_error <= static_cast<int32_t>(data->size())); - data->resize(pp_error); - } - Send(new PpapiMsg_PPBFileIO_ReadComplete(kApiID, host_resource, pp_error, - *data)); - delete data; -} -#endif // !defined(OS_NACL) - -} // namespace proxy -} // namespace ppapi diff --git a/ppapi/proxy/ppb_file_io_proxy.h b/ppapi/proxy/ppb_file_io_proxy.h deleted file mode 100644 index 10e5313..0000000 --- a/ppapi/proxy/ppb_file_io_proxy.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PPAPI_PROXY_PPB_FILE_IO_PROXY_H_ -#define PPAPI_PROXY_PPB_FILE_IO_PROXY_H_ - -#include <string> - -#include "base/basictypes.h" -#include "ppapi/c/pp_file_info.h" -#include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_completion_callback_factory.h" -#include "ppapi/utility/completion_callback_factory.h" - -namespace ppapi { - -class HostResource; -namespace proxy { - -class PPB_FileIO_Proxy : public InterfaceProxy { - public: - explicit PPB_FileIO_Proxy(Dispatcher* dispatcher); - virtual ~PPB_FileIO_Proxy(); - - static PP_Resource CreateProxyResource(PP_Instance instance); - - // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); - - static const ApiID kApiID = API_ID_PPB_FILE_IO; - - private: - // Plugin -> Host message handlers. - void OnHostMsgCreate(PP_Instance instance, HostResource* result); - void OnHostMsgOpen(const HostResource& host_resource, - const HostResource& file_ref_resource, - int32_t open_flags); - void OnHostMsgClose(const HostResource& host_resource); - void OnHostMsgQuery(const HostResource& host_resource); - void OnHostMsgTouch(const HostResource& host_resource, - PP_Time last_access_time, - PP_Time last_modified_time); - void OnHostMsgRead(const HostResource& host_resource, - int64_t offset, - int32_t bytes_to_read); - void OnHostMsgWrite(const HostResource& host_resource, - int64_t offset, - const std::string& data); - void OnHostMsgSetLength(const HostResource& host_resource, - int64_t length); - void OnHostMsgFlush(const HostResource& host_resource); - void OnHostMsgWillWrite(const HostResource& host_resource, - int64_t offset, - int32_t bytes_to_write); - void OnHostMsgWillSetLength(const HostResource& host_resource, - int64_t length); - - // Host -> Plugin message handlers. - void OnPluginMsgGeneralComplete(const HostResource& host_resource, - int32_t result); - void OnPluginMsgOpenFileComplete(const HostResource& host_resource, - int32_t result); - void OnPluginMsgQueryComplete(const HostResource& host_resource, - int32_t result, - const PP_FileInfo& info); - void OnPluginMsgReadComplete(const HostResource& host_resource, - int32_t result, - const std::string& data); - void OnPluginMsgWriteComplete(const HostResource& host_resource, - int32_t result); - - // Host-side callback handlers. These convert the callbacks to an IPC message - // to the plugin. - void GeneralCallbackCompleteInHost(int32_t pp_error, - const HostResource& host_resource); - void OpenFileCallbackCompleteInHost(int32_t pp_error, - const HostResource& host_resource); - void QueryCallbackCompleteInHost(int32_t pp_error, - const HostResource& host_resource, - PP_FileInfo* info); - void ReadCallbackCompleteInHost(int32_t pp_error, - const HostResource& host_resource, - std::string* data); - ProxyCompletionCallbackFactory<PPB_FileIO_Proxy> callback_factory_; - - DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Proxy); -}; - -} // namespace proxy -} // namespace ppapi - -#endif // PPAPI_PROXY_PPB_FILE_IO_PROXY_H_ diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 90a23bb8..e3f1b79 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -11,6 +11,7 @@ #include "ppapi/proxy/browser_font_resource_trusted.h" #include "ppapi/proxy/connection.h" #include "ppapi/proxy/file_chooser_resource.h" +#include "ppapi/proxy/file_io_resource.h" #include "ppapi/proxy/flash_device_id_resource.h" #include "ppapi/proxy/flash_font_file_resource.h" #include "ppapi/proxy/flash_menu_resource.h" @@ -22,7 +23,6 @@ #include "ppapi/proxy/ppb_audio_proxy.h" #include "ppapi/proxy/ppb_broker_proxy.h" #include "ppapi/proxy/ppb_buffer_proxy.h" -#include "ppapi/proxy/ppb_file_io_proxy.h" #include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/proxy/ppb_file_system_proxy.h" #include "ppapi/proxy/ppb_flash_message_loop_proxy.h" @@ -69,7 +69,7 @@ InterfaceProxy* ResourceCreationProxy::Create(Dispatcher* dispatcher) { } PP_Resource ResourceCreationProxy::CreateFileIO(PP_Instance instance) { - return PPB_FileIO_Proxy::CreateProxyResource(instance); + return (new FileIOResource(GetConnection(), instance))->GetReference(); } PP_Resource ResourceCreationProxy::CreateFileRef(PP_Resource file_system, diff --git a/ppapi/shared_impl/file_io_state_manager.cc b/ppapi/shared_impl/file_io_state_manager.cc new file mode 100644 index 0000000..9c9b6ea --- /dev/null +++ b/ppapi/shared_impl/file_io_state_manager.cc @@ -0,0 +1,56 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/shared_impl/file_io_state_manager.h" + +#include "base/logging.h" +#include "ppapi/c/pp_errors.h" + +namespace ppapi { + +FileIOStateManager::FileIOStateManager() + : num_pending_ops_(0), + pending_op_(OPERATION_NONE), + file_open_(false) { +} + +FileIOStateManager::~FileIOStateManager() { +} + +void FileIOStateManager::SetOpenSucceed() { + file_open_ = true; +} + +int32_t FileIOStateManager::CheckOperationState(OperationType new_op, + bool should_be_open) { + if (should_be_open) { + if (!file_open_) + return PP_ERROR_FAILED; + } else { + if (file_open_) + return PP_ERROR_FAILED; + } + + if (pending_op_ != OPERATION_NONE && + (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE)) + return PP_ERROR_INPROGRESS; + + return PP_OK; +} + +void FileIOStateManager::SetPendingOperation(OperationType new_op) { + DCHECK(pending_op_ == OPERATION_NONE || + (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == new_op)); + pending_op_ = new_op; + num_pending_ops_++; +} + +void FileIOStateManager::SetOperationFinished() { + DCHECK_GT(num_pending_ops_, 0); + if (--num_pending_ops_ == 0) + pending_op_ = OPERATION_NONE; +} + +} // namespace ppapi + diff --git a/ppapi/shared_impl/file_io_state_manager.h b/ppapi/shared_impl/file_io_state_manager.h new file mode 100644 index 0000000..7b5f926 --- /dev/null +++ b/ppapi/shared_impl/file_io_state_manager.h @@ -0,0 +1,69 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_ +#define PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/shared_impl/ppapi_shared_export.h" + +namespace ppapi { + +// FileIOStateManager is a helper class that maintains the state of operations. +// For example, some operations are mutually exclusive, meaning that an +// operation could be rejected because of the current pending operation. Also, +// most of the operations only work when the file has been opened. +class PPAPI_SHARED_EXPORT FileIOStateManager { + public: + FileIOStateManager(); + ~FileIOStateManager(); + + enum OperationType { + // There is no pending operation right now. + OPERATION_NONE, + + // If there are pending reads, any other kind of async operation is not + // allowed. + OPERATION_READ, + + // If there are pending writes, any other kind of async operation is not + // allowed. + OPERATION_WRITE, + + // If there is a pending operation that is neither read nor write, no + // further async operation is allowed. + OPERATION_EXCLUSIVE + }; + + OperationType get_pending_operation() const { return pending_op_; } + + void SetOpenSucceed(); + + // Called at the beginning of each operation. It is responsible to make sure + // that state is correct. For example, some operations are only valid after + // the file is opened, or operations might need to run exclusively. + // + // It returns |PP_OK| on success, or |PP_ERROR_...| for various reasons. + int32_t CheckOperationState(OperationType new_op, bool should_be_open); + + // Marks the state of current operations as started or finished. + void SetPendingOperation(OperationType op); + void SetOperationFinished(); + + private: + int num_pending_ops_; + OperationType pending_op_; + + // Set to true when the file has been successfully opened. + bool file_open_; + + DISALLOW_COPY_AND_ASSIGN(FileIOStateManager); +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_ + diff --git a/ppapi/shared_impl/ppb_file_io_shared.cc b/ppapi/shared_impl/ppb_file_io_shared.cc deleted file mode 100644 index 42a8d32..0000000 --- a/ppapi/shared_impl/ppb_file_io_shared.cc +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ppapi/shared_impl/ppb_file_io_shared.h" - -#include <string.h> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/shared_impl/array_writer.h" -#include "ppapi/shared_impl/file_type_conversion.h" -#include "ppapi/shared_impl/time_conversion.h" -#include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_file_ref_api.h" - -namespace ppapi { - -using thunk::EnterResourceNoLock; -using thunk::PPB_FileIO_API; -using thunk::PPB_FileRef_API; - -namespace { - -// An adapter to let Read() share the same implementation with ReadToArray(). -void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { - return user_data; -} - -} // namespace - -PPB_FileIO_Shared::CallbackEntry::CallbackEntry() - : info(NULL) { -} - -PPB_FileIO_Shared::CallbackEntry::CallbackEntry(const CallbackEntry& entry) - : callback(entry.callback), - read_buffer(entry.read_buffer), - info(entry.info) { -} - -PPB_FileIO_Shared::CallbackEntry::~CallbackEntry() { -} - -PPB_FileIO_Shared::PPB_FileIO_Shared(PP_Instance instance) - : Resource(OBJECT_IS_IMPL, instance), - file_system_type_(PP_FILESYSTEMTYPE_INVALID), - file_open_(false), - pending_op_(OPERATION_NONE) { -} - -PPB_FileIO_Shared::PPB_FileIO_Shared(const HostResource& host_resource) - : Resource(OBJECT_IS_PROXY, host_resource), - file_system_type_(PP_FILESYSTEMTYPE_INVALID), - file_open_(false), - pending_op_(OPERATION_NONE) { -} - -PPB_FileIO_Shared::~PPB_FileIO_Shared() { -} - -thunk::PPB_FileIO_API* PPB_FileIO_Shared::AsPPB_FileIO_API() { - return this; -} - -int32_t PPB_FileIO_Shared::Open(PP_Resource file_ref, - int32_t open_flags, - scoped_refptr<TrackedCallback> callback) { - EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); - if (enter.failed()) - return PP_ERROR_BADRESOURCE; - - int32_t rv = CommonCallValidation(false, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - - PP_FileSystemType type = enter.object()->GetFileSystemType(); - if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && - type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && - type != PP_FILESYSTEMTYPE_EXTERNAL) - return PP_ERROR_FAILED; - file_system_type_ = type; - - return OpenValidated(file_ref, enter.object(), open_flags, callback); -} - -int32_t PPB_FileIO_Shared::Query(PP_FileInfo* info, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - if (!info) - return PP_ERROR_BADARGUMENT; - return QueryValidated(info, callback); -} - -int32_t PPB_FileIO_Shared::Touch(PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - return TouchValidated(last_access_time, last_modified_time, callback); -} - -int32_t PPB_FileIO_Shared::Read(int64_t offset, - char* buffer, - int32_t bytes_to_read, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_READ); - if (rv != PP_OK) - return rv; - PP_ArrayOutput buffer_adapter = { &DummyGetDataBuffer, buffer }; - return ReadValidated(offset, buffer_adapter, bytes_to_read, callback); -} - -int32_t PPB_FileIO_Shared::ReadToArray( - int64_t offset, - int32_t max_read_length, - PP_ArrayOutput* output_array_buffer, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_READ); - if (rv != PP_OK) - return rv; - if (!output_array_buffer) - return PP_ERROR_BADARGUMENT; - return ReadValidated(offset, *output_array_buffer, max_read_length, callback); -} - -int32_t PPB_FileIO_Shared::Write(int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_WRITE); - if (rv != PP_OK) - return rv; - return WriteValidated(offset, buffer, bytes_to_write, callback); -} - -int32_t PPB_FileIO_Shared::SetLength(int64_t length, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - return SetLengthValidated(length, callback); -} - -int32_t PPB_FileIO_Shared::Flush(scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - return FlushValidated(callback); -} - -void PPB_FileIO_Shared::ExecuteGeneralCallback(int32_t pp_error) { - RunAndRemoveFirstPendingCallback(pp_error); -} - -void PPB_FileIO_Shared::ExecuteOpenFileCallback(int32_t pp_error) { - if (pp_error == PP_OK) - file_open_ = true; - ExecuteGeneralCallback(pp_error); -} - -void PPB_FileIO_Shared::ExecuteQueryCallback(int32_t pp_error, - const PP_FileInfo& info) { - if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty() || - !callbacks_.front().info) { - NOTREACHED(); - return; - } - *callbacks_.front().info = info; - RunAndRemoveFirstPendingCallback(pp_error); -} - -void PPB_FileIO_Shared::ExecuteReadCallback(int32_t pp_error_or_bytes, - const char* data) { - if (pending_op_ != OPERATION_READ || callbacks_.empty()) { - NOTREACHED(); - return; - } - - // The result code contains the number of bytes if it's positive. - ArrayWriter output; - output.set_pp_array_output(callbacks_.front().read_buffer); - if (output.is_valid()) { - output.StoreArray(data, std::max(0, pp_error_or_bytes)); - } - - // Always issue the callback. - RunAndRemoveFirstPendingCallback(pp_error_or_bytes); -} - -int32_t PPB_FileIO_Shared::CommonCallValidation(bool should_be_open, - OperationType new_op) { - // Only asynchronous operation is supported. - if (should_be_open) { - if (!file_open_) - return PP_ERROR_FAILED; - } else { - if (file_open_) - return PP_ERROR_FAILED; - } - - if (pending_op_ != OPERATION_NONE && - (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE)) { - return PP_ERROR_INPROGRESS; - } - - return PP_OK; -} - -void PPB_FileIO_Shared::RegisterCallback( - OperationType op, - scoped_refptr<TrackedCallback> callback, - const PP_ArrayOutput* read_buffer, - PP_FileInfo* info) { - DCHECK(pending_op_ == OPERATION_NONE || - (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == op)); - - CallbackEntry entry; - entry.callback = callback; - if (read_buffer) - entry.read_buffer = *read_buffer; - entry.info = info; - callbacks_.push_back(entry); - - pending_op_ = op; -} - -void PPB_FileIO_Shared::RunAndRemoveFirstPendingCallback(int32_t result) { - DCHECK(!callbacks_.empty()); - - CallbackEntry front = callbacks_.front(); - callbacks_.pop_front(); - if (callbacks_.empty()) - pending_op_ = OPERATION_NONE; - - front.callback->Run(result); -} - -} // namespace ppapi diff --git a/ppapi/shared_impl/ppb_file_io_shared.h b/ppapi/shared_impl/ppb_file_io_shared.h deleted file mode 100644 index 2c39c8d..0000000 --- a/ppapi/shared_impl/ppb_file_io_shared.h +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_ -#define PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_ - -#include <deque> - -#include "base/compiler_specific.h" -#include "ppapi/shared_impl/ppapi_shared_export.h" -#include "ppapi/shared_impl/resource.h" -#include "ppapi/shared_impl/tracked_callback.h" -#include "ppapi/thunk/ppb_file_io_api.h" - -namespace ppapi { - -namespace thunk { -class PPB_FileRef_API; -} - -class PPAPI_SHARED_EXPORT PPB_FileIO_Shared : public Resource, - public thunk::PPB_FileIO_API { - public: - PPB_FileIO_Shared(PP_Instance instance); - PPB_FileIO_Shared(const HostResource& host_resource); - ~PPB_FileIO_Shared(); - - // Resource overrides. - virtual thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE; - - // PPB_FileIO_API implementation. - virtual int32_t Open(PP_Resource file_ref, - int32_t open_flags, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t Query(PP_FileInfo* info, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t Touch(PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t Read(int64_t offset, - char* buffer, - int32_t bytes_to_read, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t ReadToArray(int64_t offset, - int32_t max_read_length, - PP_ArrayOutput* output_array_buffer, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t Write(int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t SetLength(int64_t length, - scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE; - - // Callback handler for different types of operations. - void ExecuteGeneralCallback(int32_t pp_error); - void ExecuteOpenFileCallback(int32_t pp_error); - void ExecuteQueryCallback(int32_t pp_error, const PP_FileInfo& info); - void ExecuteReadCallback(int32_t pp_error_or_bytes, const char* data); - - protected: - struct CallbackEntry { - CallbackEntry(); - CallbackEntry(const CallbackEntry& entry); - ~CallbackEntry(); - - scoped_refptr<TrackedCallback> callback; - - // Output buffer used only by |Read()|. - PP_ArrayOutput read_buffer; - - // Pointer back to the caller's PP_FileInfo structure for Query operations. - // NULL for non-query operations. Not owned. - PP_FileInfo* info; - }; - - enum OperationType { - // There is no pending operation right now. - OPERATION_NONE, - - // If there are pending reads, any other kind of async operation is not - // allowed. - OPERATION_READ, - - // If there are pending writes, any other kind of async operation is not - // allowed. - OPERATION_WRITE, - - // If there is a pending operation that is neither read nor write, no - // further async operation is allowed. - OPERATION_EXCLUSIVE - }; - - // Validated versions of the FileIO API. Subclasses in the proxy and impl - // implement these so the common error checking stays here. - virtual int32_t OpenValidated(PP_Resource file_ref_resource, - thunk::PPB_FileRef_API* file_ref_api, - int32_t open_flags, - scoped_refptr<TrackedCallback> callback) = 0; - virtual int32_t QueryValidated(PP_FileInfo* info, - scoped_refptr<TrackedCallback> callback) = 0; - virtual int32_t TouchValidated(PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr<TrackedCallback> callback) = 0; - virtual int32_t ReadValidated(int64_t offset, - const PP_ArrayOutput& buffer, - int32_t max_read_length, - scoped_refptr<TrackedCallback> callback) = 0; - virtual int32_t WriteValidated(int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) = 0; - virtual int32_t SetLengthValidated( - int64_t length, - scoped_refptr<TrackedCallback> callback) = 0; - virtual int32_t FlushValidated(scoped_refptr<TrackedCallback> callback) = 0; - - // Called for every "Validated" function. - // - // This verifies that the callback is valid and that no callback is already - // pending, or it is a read(write) request and currently the pending - // operations are reads(writes). - // - // Returns |PP_OK| to indicate that everything is valid or |PP_ERROR_...| if - // the call should be aborted and that code returned to the plugin. - int32_t CommonCallValidation(bool should_be_open, OperationType new_op); - - // Sets up a pending callback. This should only be called once it is certain - // that |PP_OK_COMPLETIONPENDING| will be returned. - // - // |read_buffer| is only used by read operations, |info| is used only by - // query operations. - void RegisterCallback(OperationType op, - scoped_refptr<TrackedCallback> callback, - const PP_ArrayOutput* read_buffer, - PP_FileInfo* info); - - // Pops the oldest callback from the queue and runs it. - void RunAndRemoveFirstPendingCallback(int32_t result); - - // The file system type specified in the Open() call. This will be - // PP_FILESYSTEMTYPE_INVALID before open was called. This value does not - // indicate that the open command actually succeeded. - PP_FileSystemType file_system_type_; - - // Set to true when the file has been successfully opened. - bool file_open_; - - std::deque<CallbackEntry> callbacks_; - OperationType pending_op_; - - DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Shared); -}; - -} // namespace ppapi - -#endif // PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_ diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h index e1c53ec..12c0fdf 100644 --- a/ppapi/thunk/interfaces_ppb_private.h +++ b/ppapi/thunk/interfaces_ppb_private.h @@ -35,9 +35,6 @@ PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_6, PPB_FileChooserTrusted_0_6) PROXIED_IFACE(PPB_FileRef, PPB_FILEREFPRIVATE_INTERFACE_0_1, PPB_FileRefPrivate_0_1) -// This uses the FileIO API which is declared in the public stable file. -PROXIED_IFACE(PPB_FileIO, PPB_FILEIOTRUSTED_INTERFACE_0_4, - PPB_FileIOTrusted_0_4) PROXIED_IFACE(PPB_Instance, PPB_FLASHFULLSCREEN_INTERFACE_0_1, PPB_FlashFullscreen_0_1) PROXIED_IFACE(PPB_Instance, PPB_FLASHFULLSCREEN_INTERFACE_1_0, @@ -45,6 +42,8 @@ PROXIED_IFACE(PPB_Instance, PPB_FLASHFULLSCREEN_INTERFACE_1_0, PROXIED_IFACE(NoAPIName, PPB_TALK_PRIVATE_INTERFACE_1_0, PPB_Talk_Private_1_0) +// This uses the FileIO API which is declared in the public stable file. +PROXIED_IFACE(NoAPIName, PPB_FILEIOTRUSTED_INTERFACE_0_4, PPB_FileIOTrusted_0_4) // Hack to keep font working. The Font 0.6 API is binary compatible with // BrowserFont 1.0, so just map the string to the same thing. diff --git a/ppapi/thunk/interfaces_ppb_public_stable.h b/ppapi/thunk/interfaces_ppb_public_stable.h index c7ae59b6..3bf9479 100644 --- a/ppapi/thunk/interfaces_ppb_public_stable.h +++ b/ppapi/thunk/interfaces_ppb_public_stable.h @@ -19,7 +19,6 @@ // that exist in the webkit/plugins/ppapi/*_impl.h, but not in the proxy. PROXIED_API(PPB_Audio) PROXIED_API(PPB_Core) -PROXIED_API(PPB_FileIO) PROXIED_API(PPB_FileRef) PROXIED_API(PPB_FileSystem) PROXIED_API(PPB_Graphics3D) @@ -48,8 +47,6 @@ UNPROXIED_API(PPB_AudioConfig) // interface string. // Note: Core is special and is registered manually. PROXIED_IFACE(PPB_Audio, PPB_AUDIO_INTERFACE_1_0, PPB_Audio_1_0) -PROXIED_IFACE(PPB_FileIO, PPB_FILEIO_INTERFACE_1_0, PPB_FileIO_1_0) -PROXIED_IFACE(PPB_FileIO, PPB_FILEIO_INTERFACE_1_1, PPB_FileIO_1_1) PROXIED_IFACE(PPB_FileRef, PPB_FILEREF_INTERFACE_1_0, PPB_FileRef_1_0) PROXIED_IFACE(PPB_FileSystem, PPB_FILESYSTEM_INTERFACE_1_0, PPB_FileSystem_1_0) PROXIED_IFACE(PPB_Graphics3D, PPB_GRAPHICS_3D_INTERFACE_1_0, PPB_Graphics3D_1_0) @@ -57,6 +54,8 @@ PROXIED_IFACE(PPB_ImageData, PPB_IMAGEDATA_INTERFACE_1_0, PPB_ImageData_1_0) PROXIED_IFACE(PPB_Instance, PPB_CONSOLE_INTERFACE_1_0, PPB_Console_1_0) PROXIED_IFACE(PPB_Instance, PPB_GAMEPAD_INTERFACE_1_0, PPB_Gamepad_1_0) PROXIED_IFACE(PPB_Instance, PPB_INSTANCE_INTERFACE_1_0, PPB_Instance_1_0) +PROXIED_IFACE(NoAPIName, PPB_FILEIO_INTERFACE_1_0, PPB_FileIO_1_0) +PROXIED_IFACE(NoAPIName, PPB_FILEIO_INTERFACE_1_1, PPB_FileIO_1_1) PROXIED_IFACE(NoAPIName, PPB_GRAPHICS_2D_INTERFACE_1_0, PPB_Graphics2D_1_0) PROXIED_IFACE(NoAPIName, PPB_INPUT_EVENT_INTERFACE_1_0, PPB_InputEvent_1_0) PROXIED_IFACE(NoAPIName, PPB_KEYBOARD_INPUT_EVENT_INTERFACE_1_0, diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 2e660e8..86930a3 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -211,8 +211,6 @@ '../plugins/ppapi/ppb_buffer_impl.h', '../plugins/ppapi/ppb_directory_reader_impl.cc', '../plugins/ppapi/ppb_directory_reader_impl.h', - '../plugins/ppapi/ppb_file_io_impl.cc', - '../plugins/ppapi/ppb_file_io_impl.h', '../plugins/ppapi/ppb_file_ref_impl.cc', '../plugins/ppapi/ppb_file_ref_impl.h', '../plugins/ppapi/ppb_file_system_impl.cc', diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.cc b/webkit/plugins/ppapi/ppb_file_io_impl.cc deleted file mode 100644 index 6167a8c..0000000 --- a/webkit/plugins/ppapi/ppb_file_io_impl.cc +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/plugins/ppapi/ppb_file_io_impl.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/callback_helpers.h" -#include "base/file_util.h" -#include "base/file_util_proxy.h" -#include "base/message_loop_proxy.h" -#include "base/platform_file.h" -#include "base/logging.h" -#include "base/time.h" -#include "ppapi/c/ppb_file_io.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" -#include "ppapi/c/pp_completion_callback.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/shared_impl/file_type_conversion.h" -#include "ppapi/shared_impl/time_conversion.h" -#include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_file_ref_api.h" -#include "webkit/plugins/ppapi/common.h" -#include "webkit/plugins/ppapi/file_callbacks.h" -#include "webkit/plugins/ppapi/plugin_module.h" -#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" -#include "webkit/plugins/ppapi/ppb_directory_reader_impl.h" -#include "webkit/plugins/ppapi/ppb_file_ref_impl.h" -#include "webkit/plugins/ppapi/ppb_file_system_impl.h" -#include "webkit/plugins/ppapi/quota_file_io.h" -#include "webkit/plugins/ppapi/resource_helper.h" - -using ppapi::PPTimeToTime; -using ppapi::TimeToPPTime; -using ppapi::TrackedCallback; -using ppapi::thunk::PPB_FileRef_API; - -namespace webkit { -namespace ppapi { - -namespace { - -typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback; - -class PlatformGeneralCallbackTranslator - : public fileapi::FileSystemCallbackDispatcher { - public: - PlatformGeneralCallbackTranslator( - const PlatformGeneralCallback& callback) - : callback_(callback) {} - - virtual ~PlatformGeneralCallbackTranslator() {} - - virtual void DidSucceed() OVERRIDE { - callback_.Run(base::PLATFORM_FILE_OK); - } - - virtual void DidReadMetadata( - const base::PlatformFileInfo& file_info, - const FilePath& platform_path) OVERRIDE { - NOTREACHED(); - } - - virtual void DidReadDirectory( - const std::vector<base::FileUtilProxy::Entry>& entries, - bool has_more) OVERRIDE { - NOTREACHED(); - } - - virtual void DidOpenFileSystem(const std::string& name, - const GURL& root) OVERRIDE { - NOTREACHED(); - } - - virtual void DidFail(base::PlatformFileError error_code) OVERRIDE { - callback_.Run(error_code); - } - - virtual void DidWrite(int64 bytes, bool complete) OVERRIDE { - NOTREACHED(); - } - - virtual void DidOpenFile(base::PlatformFile file) OVERRIDE { - NOTREACHED(); - } - - private: - PlatformGeneralCallback callback_; -}; - -} // namespace - -PPB_FileIO_Impl::PPB_FileIO_Impl(PP_Instance instance) - : ::ppapi::PPB_FileIO_Shared(instance), - file_(base::kInvalidPlatformFileValue), - ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { -} - -PPB_FileIO_Impl::~PPB_FileIO_Impl() { - Close(); -} - -int32_t PPB_FileIO_Impl::OpenValidated( - PP_Resource file_ref_resource, - PPB_FileRef_API* file_ref_api, - int32_t open_flags, - scoped_refptr<TrackedCallback> callback) { - PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api); - - int flags = 0; - if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, &flags)) - return PP_ERROR_BADARGUMENT; - - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_BADARGUMENT; - - if (file_ref->HasValidFileSystem()) { - file_system_url_ = file_ref->GetFileSystemURL(); - if (!plugin_delegate->AsyncOpenFileSystemURL( - file_system_url_, flags, - base::Bind( - &PPB_FileIO_Impl::ExecutePlatformOpenFileSystemURLCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - } else { - if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) - return PP_ERROR_FAILED; - if (!plugin_delegate->AsyncOpenFile( - file_ref->GetSystemPath(), flags, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformOpenFileCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - } - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::QueryValidated( - PP_FileInfo* info, - scoped_refptr<TrackedCallback> callback) { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_FAILED; - - if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( - plugin_delegate->GetFileThreadMessageLoopProxy(), file_, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformQueryCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, info); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::TouchValidated( - PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr<TrackedCallback> callback) { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_FAILED; - - if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { - if (!plugin_delegate->Touch( - file_system_url_, - PPTimeToTime(last_access_time), - PPTimeToTime(last_modified_time), - new PlatformGeneralCallbackTranslator( - base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback, - weak_factory_.GetWeakPtr())))) - return PP_ERROR_FAILED; - } else { - // TODO(nhiroki): fix a failure of FileIO.Touch for an external filesystem - // on Mac and Linux due to sandbox restrictions (http://crbug.com/101128). - if (!base::FileUtilProxy::Touch( - plugin_delegate->GetFileThreadMessageLoopProxy(), - file_, PPTimeToTime(last_access_time), - PPTimeToTime(last_modified_time), - base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - } - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::ReadValidated( - int64_t offset, - const PP_ArrayOutput& output_array_buffer, - int32_t max_read_length, - scoped_refptr<TrackedCallback> callback) { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_FAILED; - - if (!base::FileUtilProxy::Read( - plugin_delegate->GetFileThreadMessageLoopProxy(), file_, offset, - max_read_length, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformReadCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - - RegisterCallback(OPERATION_READ, callback, &output_array_buffer, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::WriteValidated( - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_FAILED; - - if (quota_file_io_.get()) { - if (!quota_file_io_->Write( - offset, buffer, bytes_to_write, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformWriteCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - } else { - if (!base::FileUtilProxy::Write( - plugin_delegate->GetFileThreadMessageLoopProxy(), file_, offset, - buffer, bytes_to_write, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformWriteCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - } - - RegisterCallback(OPERATION_WRITE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::SetLengthValidated( - int64_t length, - scoped_refptr<TrackedCallback> callback) { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_FAILED; - - if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { - if (!plugin_delegate->SetLength( - file_system_url_, length, - new PlatformGeneralCallbackTranslator( - base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback, - weak_factory_.GetWeakPtr())))) - return PP_ERROR_FAILED; - } else { - // TODO(nhiroki): fix a failure of FileIO.SetLength for an external - // filesystem on Mac due to sandbox restrictions (http://crbug.com/156077). - if (!base::FileUtilProxy::Truncate( - plugin_delegate->GetFileThreadMessageLoopProxy(), file_, length, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - } - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::FlushValidated( - scoped_refptr<TrackedCallback> callback) { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (!plugin_delegate) - return PP_ERROR_FAILED; - - if (!base::FileUtilProxy::Flush( - plugin_delegate->GetFileThreadMessageLoopProxy(), file_, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -void PPB_FileIO_Impl::Close() { - PluginDelegate* plugin_delegate = GetPluginDelegate(); - if (file_ != base::kInvalidPlatformFileValue && plugin_delegate) { - base::FileUtilProxy::Close( - plugin_delegate->GetFileThreadMessageLoopProxy(), - file_, - base::ResetAndReturn(¬ify_close_file_callback_)); - file_ = base::kInvalidPlatformFileValue; - quota_file_io_.reset(); - } - // TODO(viettrungluu): Check what happens to the callback (probably the - // wrong thing). May need to post abort here. crbug.com/69457 -} - -int32_t PPB_FileIO_Impl::GetOSFileDescriptor() { -#if defined(OS_POSIX) - return file_; -#elif defined(OS_WIN) - return reinterpret_cast<uintptr_t>(file_); -#else -#error "Platform not supported." -#endif -} - -int32_t PPB_FileIO_Impl::WillWrite(int64_t offset, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - - if (!quota_file_io_.get()) - return PP_OK; - - if (!quota_file_io_->WillWrite( - offset, bytes_to_write, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformWillWriteCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PPB_FileIO_Impl::WillSetLength( - int64_t length, - scoped_refptr<TrackedCallback> callback) { - int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE); - if (rv != PP_OK) - return rv; - - if (!quota_file_io_.get()) - return PP_OK; - - if (!quota_file_io_->WillSetLength( - length, - base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback, - weak_factory_.GetWeakPtr()))) - return PP_ERROR_FAILED; - - RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL); - return PP_OK_COMPLETIONPENDING; -} - -PluginDelegate* PPB_FileIO_Impl::GetPluginDelegate() { - return ResourceHelper::GetPluginDelegate(this); -} - -void PPB_FileIO_Impl::ExecutePlatformGeneralCallback( - base::PlatformFileError error_code) { - ExecuteGeneralCallback(::ppapi::PlatformFileErrorToPepperError(error_code)); -} - -void PPB_FileIO_Impl::ExecutePlatformOpenFileCallback( - base::PlatformFileError error_code, - base::PassPlatformFile file) { - DCHECK(file_ == base::kInvalidPlatformFileValue); - file_ = file.ReleaseValue(); - - DCHECK(!quota_file_io_.get()); - if (file_ != base::kInvalidPlatformFileValue && - (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY || - file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT)) { - quota_file_io_.reset(new QuotaFileIO( - pp_instance(), file_, file_system_url_, file_system_type_)); - } - - ExecuteOpenFileCallback(::ppapi::PlatformFileErrorToPepperError(error_code)); -} - -void PPB_FileIO_Impl::ExecutePlatformOpenFileSystemURLCallback( - base::PlatformFileError error_code, - base::PassPlatformFile file, - const PluginDelegate::NotifyCloseFileCallback& callback) { - if (error_code == base::PLATFORM_FILE_OK) - notify_close_file_callback_ = callback; - ExecutePlatformOpenFileCallback(error_code, file); -} - -void PPB_FileIO_Impl::ExecutePlatformQueryCallback( - base::PlatformFileError error_code, - const base::PlatformFileInfo& file_info) { - PP_FileInfo pp_info; - pp_info.size = file_info.size; - pp_info.creation_time = TimeToPPTime(file_info.creation_time); - pp_info.last_access_time = TimeToPPTime(file_info.last_accessed); - pp_info.last_modified_time = TimeToPPTime(file_info.last_modified); - pp_info.system_type = file_system_type_; - if (file_info.is_directory) - pp_info.type = PP_FILETYPE_DIRECTORY; - else - pp_info.type = PP_FILETYPE_REGULAR; - - ExecuteQueryCallback(::ppapi::PlatformFileErrorToPepperError(error_code), - pp_info); -} - -void PPB_FileIO_Impl::ExecutePlatformReadCallback( - base::PlatformFileError error_code, - const char* data, int bytes_read) { - // Map the error code, OK getting mapped to the # of bytes read. - int32_t pp_result = ::ppapi::PlatformFileErrorToPepperError(error_code); - pp_result = pp_result == PP_OK ? bytes_read : pp_result; - ExecuteReadCallback(pp_result, data); -} - -void PPB_FileIO_Impl::ExecutePlatformWriteCallback( - base::PlatformFileError error_code, - int bytes_written) { - int32_t pp_result = ::ppapi::PlatformFileErrorToPepperError(error_code); - ExecuteGeneralCallback(pp_result == PP_OK ? bytes_written : pp_result); -} - -void PPB_FileIO_Impl::ExecutePlatformWillWriteCallback( - base::PlatformFileError error_code, - int bytes_written) { - if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) { - NOTREACHED(); - return; - } - - if (error_code != base::PLATFORM_FILE_OK) { - RunAndRemoveFirstPendingCallback( - ::ppapi::PlatformFileErrorToPepperError(error_code)); - } else { - RunAndRemoveFirstPendingCallback(bytes_written); - } -} - -} // namespace ppapi -} // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.h b/webkit/plugins/ppapi/ppb_file_io_impl.h deleted file mode 100644 index a6f9e89..0000000 --- a/webkit/plugins/ppapi/ppb_file_io_impl.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_PLUGINS_PPAPI_PPB_FILE_IO_IMPL_H_ -#define WEBKIT_PLUGINS_PPAPI_PPB_FILE_IO_IMPL_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "ppapi/shared_impl/ppb_file_io_shared.h" -#include "webkit/plugins/ppapi/plugin_delegate.h" - -namespace webkit { -namespace ppapi { - -class QuotaFileIO; - -class PPB_FileIO_Impl : public ::ppapi::PPB_FileIO_Shared { - public: - explicit PPB_FileIO_Impl(PP_Instance instance); - virtual ~PPB_FileIO_Impl(); - - // PPB_FileIO_API implementation (most of the operations are implemented - // as the "Validated" versions below). - virtual void Close() OVERRIDE; - virtual int32_t GetOSFileDescriptor() OVERRIDE; - virtual int32_t WillWrite( - int64_t offset, - int32_t bytes_to_write, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t WillSetLength( - int64_t length, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - - private: - // FileIOImpl overrides. - virtual int32_t OpenValidated( - PP_Resource file_ref_resource, - ::ppapi::thunk::PPB_FileRef_API* file_ref_api, - int32_t open_flags, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t QueryValidated( - PP_FileInfo* info, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t TouchValidated( - PP_Time last_access_time, - PP_Time last_modified_time, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t ReadValidated( - int64_t offset, - const PP_ArrayOutput& output_array_buffer, - int32_t max_read_length, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t WriteValidated( - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t SetLengthValidated( - int64_t length, - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t FlushValidated( - scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE; - - // Returns the plugin delegate for this resource if it exists, or NULL if it - // doesn't. Calling code should always check for NULL. - PluginDelegate* GetPluginDelegate(); - - // Callback handlers. These mostly convert the PlatformFileError to the - // PP_Error code and call the shared (non-"Platform") version. - void ExecutePlatformGeneralCallback(base::PlatformFileError error_code); - void ExecutePlatformOpenFileCallback(base::PlatformFileError error_code, - base::PassPlatformFile file); - void ExecutePlatformOpenFileSystemURLCallback( - base::PlatformFileError error_code, - base::PassPlatformFile file, - const PluginDelegate::NotifyCloseFileCallback& callback); - void ExecutePlatformQueryCallback(base::PlatformFileError error_code, - const base::PlatformFileInfo& file_info); - void ExecutePlatformReadCallback(base::PlatformFileError error_code, - const char* data, int bytes_read); - void ExecutePlatformWriteCallback(base::PlatformFileError error_code, - int bytes_written); - void ExecutePlatformWillWriteCallback(base::PlatformFileError error_code, - int bytes_written); - - base::PlatformFile file_; - - // Valid only for PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}. - GURL file_system_url_; - - // Callback function for notifying when the file handle is closed. - PluginDelegate::NotifyCloseFileCallback notify_close_file_callback_; - - // Pointer to a QuotaFileIO instance, which is valid only while a file - // of type PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY} is opened. - scoped_ptr<QuotaFileIO> quota_file_io_; - - base::WeakPtrFactory<PPB_FileIO_Impl> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Impl); -}; - -} // namespace ppapi -} // namespace webkit - -#endif // WEBKIT_PLUGINS_PPAPI_PPB_FILE_IO_IMPL_H_ diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc index 1ef878f..44f535c 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.cc +++ b/webkit/plugins/ppapi/resource_creation_impl.cc @@ -14,7 +14,6 @@ #include "webkit/plugins/ppapi/ppb_broker_impl.h" #include "webkit/plugins/ppapi/ppb_buffer_impl.h" #include "webkit/plugins/ppapi/ppb_directory_reader_impl.h" -#include "webkit/plugins/ppapi/ppb_file_io_impl.h" #include "webkit/plugins/ppapi/ppb_file_ref_impl.h" #include "webkit/plugins/ppapi/ppb_file_system_impl.h" #include "webkit/plugins/ppapi/ppb_flash_message_loop_impl.h" @@ -85,10 +84,6 @@ PP_Resource ResourceCreationImpl::CreateDirectoryReader( return PPB_DirectoryReader_Impl::Create(directory_ref); } -PP_Resource ResourceCreationImpl::CreateFileIO(PP_Instance instance) { - return (new PPB_FileIO_Impl(instance))->GetReference(); -} - PP_Resource ResourceCreationImpl::CreateFileRef(PP_Resource file_system, const char* path) { PPB_FileRef_Impl* res = PPB_FileRef_Impl::CreateInternal(file_system, path); diff --git a/webkit/plugins/ppapi/resource_creation_impl.h b/webkit/plugins/ppapi/resource_creation_impl.h index 7216b46..9549354 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.h +++ b/webkit/plugins/ppapi/resource_creation_impl.h @@ -35,7 +35,6 @@ class WEBKIT_PLUGINS_EXPORT ResourceCreationImpl virtual PP_Resource CreateBuffer(PP_Instance instance, uint32_t size) OVERRIDE; virtual PP_Resource CreateDirectoryReader(PP_Resource directory_ref) OVERRIDE; - virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateFileRef(PP_Resource file_system, const char* path) OVERRIDE; virtual PP_Resource CreateFileSystem(PP_Instance instance, |