summaryrefslogtreecommitdiffstats
path: root/webkit/plugins
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-09 18:09:59 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-09 18:09:59 +0000
commitf2a211d23fc4d94ae21bb2efb7a72eff5a9a2457 (patch)
tree3a74a4bd800ee012a0e851c86f6e1f267673c299 /webkit/plugins
parent46fb94424addb322c7dfad1e8eba462baf0cdcb7 (diff)
downloadchromium_src-f2a211d23fc4d94ae21bb2efb7a72eff5a9a2457.zip
chromium_src-f2a211d23fc4d94ae21bb2efb7a72eff5a9a2457.tar.gz
chromium_src-f2a211d23fc4d94ae21bb2efb7a72eff5a9a2457.tar.bz2
Revert 113817 - Implement a proxy for Pepper FileIO.
[ Reland of 113565 http://codereview.chromium.org/8764003 ] This splits apart the old in-process implementation into a new object in shared_impl that does most of the general tracking. This alllows that code to be shared by the proxy. BUG=http://crbug.com/101154 TBR=brettw@chromium.org Review URL: http://codereview.chromium.org/8898005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/plugins')
-rw-r--r--webkit/plugins/ppapi/file_callbacks.cc4
-rw-r--r--webkit/plugins/ppapi/file_type_conversions.cc76
-rw-r--r--webkit/plugins/ppapi/file_type_conversions.h25
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc2
-rw-r--r--webkit/plugins/ppapi/ppb_file_io_impl.cc331
-rw-r--r--webkit/plugins/ppapi/ppb_file_io_impl.h140
-rw-r--r--webkit/plugins/ppapi/ppb_flash_file_impl.cc24
7 files changed, 452 insertions, 150 deletions
diff --git a/webkit/plugins/ppapi/file_callbacks.cc b/webkit/plugins/ppapi/file_callbacks.cc
index ce84c41..3cb1c08 100644
--- a/webkit/plugins/ppapi/file_callbacks.cc
+++ b/webkit/plugins/ppapi/file_callbacks.cc
@@ -8,10 +8,10 @@
#include "ppapi/c/pp_file_info.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_system.h"
-#include "ppapi/shared_impl/file_type_conversion.h"
#include "ppapi/shared_impl/time_conversion.h"
#include "webkit/fileapi/file_system_types.h"
#include "webkit/plugins/ppapi/callbacks.h"
+#include "webkit/plugins/ppapi/file_type_conversions.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppb_directory_reader_impl.h"
#include "webkit/plugins/ppapi/ppb_file_system_impl.h"
@@ -101,7 +101,7 @@ void FileCallbacks::RunCallback(base::PlatformFileError error_code) {
if (callback_->completed())
return;
- callback_->Run(::ppapi::PlatformFileErrorToPepperError(error_code));
+ callback_->Run(PlatformFileErrorToPepperError(error_code));
}
} // namespace ppapi
diff --git a/webkit/plugins/ppapi/file_type_conversions.cc b/webkit/plugins/ppapi/file_type_conversions.cc
new file mode 100644
index 0000000..42f1aa1
--- /dev/null
+++ b/webkit/plugins/ppapi/file_type_conversions.cc
@@ -0,0 +1,76 @@
+// 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.
+
+#include "webkit/plugins/ppapi/file_type_conversions.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_file_io.h"
+
+namespace webkit {
+namespace ppapi {
+
+int PlatformFileErrorToPepperError(base::PlatformFileError error_code) {
+ switch (error_code) {
+ case base::PLATFORM_FILE_OK:
+ return PP_OK;
+ case base::PLATFORM_FILE_ERROR_EXISTS:
+ return PP_ERROR_FILEEXISTS;
+ case base::PLATFORM_FILE_ERROR_NOT_FOUND:
+ return PP_ERROR_FILENOTFOUND;
+ case base::PLATFORM_FILE_ERROR_ACCESS_DENIED:
+ case base::PLATFORM_FILE_ERROR_SECURITY:
+ return PP_ERROR_NOACCESS;
+ case base::PLATFORM_FILE_ERROR_NO_MEMORY:
+ return PP_ERROR_NOMEMORY;
+ case base::PLATFORM_FILE_ERROR_NO_SPACE:
+ return PP_ERROR_NOSPACE;
+ case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
+ return PP_ERROR_FAILED;
+ default:
+ return PP_ERROR_FAILED;
+ }
+}
+
+bool PepperFileOpenFlagsToPlatformFileFlags(int32_t pp_open_flags,
+ int* flags_out) {
+ if (!flags_out)
+ return false;
+
+ bool pp_read = !!(pp_open_flags & PP_FILEOPENFLAG_READ);
+ bool pp_write = !!(pp_open_flags & PP_FILEOPENFLAG_WRITE);
+ bool pp_create = !!(pp_open_flags & PP_FILEOPENFLAG_CREATE);
+ bool pp_truncate = !!(pp_open_flags & PP_FILEOPENFLAG_TRUNCATE);
+ bool pp_exclusive = !!(pp_open_flags & PP_FILEOPENFLAG_EXCLUSIVE);
+
+ int flags = 0;
+ if (pp_read)
+ flags |= base::PLATFORM_FILE_READ;
+ if (pp_write) {
+ flags |= base::PLATFORM_FILE_WRITE;
+ flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES;
+ }
+
+ if (pp_truncate && !pp_write)
+ return false;
+
+ if (pp_create) {
+ if (pp_exclusive) {
+ flags |= base::PLATFORM_FILE_CREATE;
+ } else if (pp_truncate) {
+ flags |= base::PLATFORM_FILE_CREATE_ALWAYS;
+ } else {
+ flags |= base::PLATFORM_FILE_OPEN_ALWAYS;
+ }
+ } else if (pp_truncate) {
+ flags |= base::PLATFORM_FILE_OPEN_TRUNCATED;
+ } else {
+ flags |= base::PLATFORM_FILE_OPEN;
+ }
+
+ *flags_out = flags;
+ return true;
+}
+
+} // namespace ppapi
+} // namespace webkit
diff --git a/webkit/plugins/ppapi/file_type_conversions.h b/webkit/plugins/ppapi/file_type_conversions.h
new file mode 100644
index 0000000..708a94b
--- /dev/null
+++ b/webkit/plugins/ppapi/file_type_conversions.h
@@ -0,0 +1,25 @@
+// 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 WEBKIT_PLUGINS_PPAPI_FILE_TYPE_CONVERSIONS_H_
+#define WEBKIT_PLUGINS_PPAPI_FILE_TYPE_CONVERSIONS_H_
+
+#include "base/platform_file.h"
+#include "ppapi/c/pp_stdint.h"
+
+namespace webkit {
+namespace ppapi {
+
+int PlatformFileErrorToPepperError(base::PlatformFileError error_code);
+
+// Converts a PP_FileOpenFlags_Dev flag combination into a corresponding
+// PlatformFileFlags flag combination.
+// Returns |true| if okay.
+bool PepperFileOpenFlagsToPlatformFileFlags(int32_t pp_open_flags,
+ int* flags_out);
+
+} // namespace ppapi
+} // namespace webkit
+
+#endif // WEBKIT_PLUGINS_PPAPI_FILE_TYPE_CONVERSIONS_H_
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 1b723a6..aaee85f 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -284,6 +284,8 @@ const void* GetInterface(const char* name) {
return ::ppapi::thunk::GetPPB_BufferTrusted_Thunk();
if (strcmp(name, PPB_CORE_INTERFACE) == 0)
return &core_interface;
+ if (strcmp(name, PPB_FILEIOTRUSTED_INTERFACE) == 0)
+ return ::ppapi::thunk::GetPPB_FileIOTrusted_Thunk();
if (strcmp(name, PPB_FILECHOOSER_TRUSTED_INTERFACE) == 0)
return ::ppapi::thunk::GetPPB_FileChooser_Trusted_Thunk();
if (strcmp(name, PPB_FLASH_INTERFACE) == 0)
diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.cc b/webkit/plugins/ppapi/ppb_file_io_impl.cc
index 7fa69bc..351d232 100644
--- a/webkit/plugins/ppapi/ppb_file_io_impl.cc
+++ b/webkit/plugins/ppapi/ppb_file_io_impl.cc
@@ -16,11 +16,11 @@
#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_type_conversions.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
@@ -29,14 +29,31 @@
using ppapi::PPTimeToTime;
using ppapi::TimeToPPTime;
+using ppapi::thunk::EnterResourceNoLock;
+using ppapi::thunk::PPB_FileIO_API;
using ppapi::thunk::PPB_FileRef_API;
namespace webkit {
namespace ppapi {
+PPB_FileIO_Impl::CallbackEntry::CallbackEntry()
+ : read_buffer(NULL) {
+}
+
+PPB_FileIO_Impl::CallbackEntry::CallbackEntry(const CallbackEntry& entry)
+ : callback(entry.callback),
+ read_buffer(entry.read_buffer) {
+}
+
+PPB_FileIO_Impl::CallbackEntry::~CallbackEntry() {
+}
+
PPB_FileIO_Impl::PPB_FileIO_Impl(PP_Instance instance)
- : ::ppapi::PPB_FileIO_Shared(instance),
+ : Resource(instance),
file_(base::kInvalidPlatformFileValue),
+ file_system_type_(PP_FILESYSTEMTYPE_INVALID),
+ pending_op_(OPERATION_NONE),
+ info_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
}
@@ -44,25 +61,41 @@ 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,
- PP_CompletionCallback callback) {
- PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api);
+PPB_FileIO_API* PPB_FileIO_Impl::AsPPB_FileIO_API() {
+ return this;
+}
+
+int32_t PPB_FileIO_Impl::Open(PP_Resource pp_file_ref,
+ int32_t open_flags,
+ PP_CompletionCallback callback) {
+ EnterResourceNoLock<PPB_FileRef_API> enter(pp_file_ref, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+ PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(enter.object());
+
+ int32_t rv = CommonCallValidation(false, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
int flags = 0;
- if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, &flags))
+ if (!PepperFileOpenFlagsToPlatformFileFlags(open_flags, &flags))
return PP_ERROR_BADARGUMENT;
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
- return PP_ERROR_BADARGUMENT;
+ return false;
+
+ file_system_type_ = file_ref->GetFileSystemType();
+ if (file_system_type_ != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
+ file_system_type_ != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
+ file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL)
+ return PP_ERROR_FAILED;
if (file_ref->HasValidFileSystem()) {
file_system_url_ = file_ref->GetFileSystemURL();
if (!plugin_delegate->AsyncOpenFileSystemURL(
file_system_url_, flags,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformOpenFileCallback,
+ base::Bind(&PPB_FileIO_Impl::AsyncOpenFileCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
} else {
@@ -70,35 +103,49 @@ int32_t PPB_FileIO_Impl::OpenValidated(PP_Resource file_ref_resource,
return PP_ERROR_FAILED;
if (!plugin_delegate->AsyncOpenFile(
file_ref->GetSystemPath(), flags,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformOpenFileCallback,
+ base::Bind(&PPB_FileIO_Impl::AsyncOpenFileCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
}
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
-int32_t PPB_FileIO_Impl::QueryValidated(PP_FileInfo* info,
- PP_CompletionCallback callback) {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+int32_t PPB_FileIO_Impl::Query(PP_FileInfo* info,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ if (!info)
+ return PP_ERROR_BADARGUMENT;
+
+ DCHECK(!info_); // If |info_|, a callback should be pending (caught above).
+ info_ = info;
+
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
return PP_ERROR_FAILED;
if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
plugin_delegate->GetFileThreadMessageLoopProxy(), file_,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformQueryCallback,
+ base::Bind(&PPB_FileIO_Impl::QueryInfoCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, info);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
-int32_t PPB_FileIO_Impl::TouchValidated(PP_Time last_access_time,
- PP_Time last_modified_time,
- PP_CompletionCallback callback) {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+int32_t PPB_FileIO_Impl::Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
return PP_ERROR_FAILED;
@@ -106,101 +153,117 @@ int32_t PPB_FileIO_Impl::TouchValidated(PP_Time last_access_time,
plugin_delegate->GetFileThreadMessageLoopProxy(),
file_, PPTimeToTime(last_access_time),
PPTimeToTime(last_modified_time),
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
+ base::Bind(&PPB_FileIO_Impl::StatusCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
-int32_t PPB_FileIO_Impl::ReadValidated(int64_t offset,
- char* buffer,
- int32_t bytes_to_read,
- PP_CompletionCallback callback) {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+int32_t PPB_FileIO_Impl::Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_READ, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
return PP_ERROR_FAILED;
if (!base::FileUtilProxy::Read(
plugin_delegate->GetFileThreadMessageLoopProxy(), file_, offset,
bytes_to_read,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformReadCallback,
+ base::Bind(&PPB_FileIO_Impl::ReadCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
- RegisterCallback(OPERATION_READ, callback, buffer, NULL);
+ RegisterCallback(OPERATION_READ, callback, buffer);
return PP_OK_COMPLETIONPENDING;
}
-int32_t PPB_FileIO_Impl::WriteValidated(int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- PP_CompletionCallback callback) {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+int32_t PPB_FileIO_Impl::Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_WRITE, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
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,
+ base::Bind(&PPB_FileIO_Impl::WriteCallback,
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,
+ base::Bind(&PPB_FileIO_Impl::WriteCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
}
- RegisterCallback(OPERATION_WRITE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_WRITE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
-int32_t PPB_FileIO_Impl::SetLengthValidated(int64_t length,
- PP_CompletionCallback callback) {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+int32_t PPB_FileIO_Impl::SetLength(int64_t length,
+ PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
return PP_ERROR_FAILED;
if (quota_file_io_.get()) {
if (!quota_file_io_->SetLength(
length,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
+ base::Bind(&PPB_FileIO_Impl::StatusCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
} else {
if (!base::FileUtilProxy::Truncate(
plugin_delegate->GetFileThreadMessageLoopProxy(), file_, length,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
+ base::Bind(&PPB_FileIO_Impl::StatusCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
}
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
-int32_t PPB_FileIO_Impl::FlushValidated(PP_CompletionCallback callback) {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+int32_t PPB_FileIO_Impl::Flush(PP_CompletionCallback callback) {
+ int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE, callback);
+ if (rv != PP_OK)
+ return rv;
+
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
return PP_ERROR_FAILED;
if (!base::FileUtilProxy::Flush(
plugin_delegate->GetFileThreadMessageLoopProxy(), file_,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
+ base::Bind(&PPB_FileIO_Impl::StatusCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
void PPB_FileIO_Impl::Close() {
- PluginDelegate* plugin_delegate = GetPluginDelegate();
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (file_ != base::kInvalidPlatformFileValue && plugin_delegate) {
base::FileUtilProxy::Close(
plugin_delegate->GetFileThreadMessageLoopProxy(), file_,
@@ -232,11 +295,11 @@ int32_t PPB_FileIO_Impl::WillWrite(int64_t offset,
if (!quota_file_io_->WillWrite(
offset, bytes_to_write,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformWillWriteCallback,
+ base::Bind(&PPB_FileIO_Impl::WillWriteCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
@@ -251,26 +314,85 @@ int32_t PPB_FileIO_Impl::WillSetLength(int64_t length,
if (!quota_file_io_->WillSetLength(
length,
- base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
+ base::Bind(&PPB_FileIO_Impl::StatusCallback,
weak_factory_.GetWeakPtr())))
return PP_ERROR_FAILED;
- RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
+ RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL);
return PP_OK_COMPLETIONPENDING;
}
-PluginDelegate* PPB_FileIO_Impl::GetPluginDelegate() {
- return ResourceHelper::GetPluginDelegate(this);
+int32_t PPB_FileIO_Impl::CommonCallValidation(bool should_be_open,
+ OperationType new_op,
+ PP_CompletionCallback callback) {
+ // Only asynchronous operation is supported.
+ if (!callback.func)
+ return PP_ERROR_BLOCKS_MAIN_THREAD;
+
+ if (should_be_open) {
+ if (file_ == base::kInvalidPlatformFileValue)
+ return PP_ERROR_FAILED;
+ } else {
+ if (file_ != base::kInvalidPlatformFileValue)
+ 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_Impl::RegisterCallback(OperationType op,
+ PP_CompletionCallback callback,
+ char* read_buffer) {
+ DCHECK(callback.func);
+ DCHECK(pending_op_ == OPERATION_NONE ||
+ (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == op));
+
+ PluginModule* plugin_module = ResourceHelper::GetPluginModule(this);
+ if (!plugin_module)
+ return;
+
+ CallbackEntry entry;
+ entry.callback = new TrackedCompletionCallback(
+ plugin_module->GetCallbackTracker(), pp_resource(), callback);
+ entry.read_buffer = read_buffer;
+
+ callbacks_.push(entry);
+ pending_op_ = op;
+}
+
+void PPB_FileIO_Impl::RunAndRemoveFirstPendingCallback(int32_t result) {
+ DCHECK(!callbacks_.empty());
+
+ CallbackEntry front = callbacks_.front();
+ callbacks_.pop();
+ if (callbacks_.empty())
+ pending_op_ = OPERATION_NONE;
+
+ front.callback->Run(result); // Will complete abortively if necessary.
}
-void PPB_FileIO_Impl::ExecutePlatformGeneralCallback(
- base::PlatformFileError error_code) {
- ExecuteGeneralCallback(::ppapi::PlatformFileErrorToPepperError(error_code));
+void PPB_FileIO_Impl::StatusCallback(base::PlatformFileError error_code) {
+ if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) {
+ NOTREACHED();
+ return;
+ }
+
+ RunAndRemoveFirstPendingCallback(PlatformFileErrorToPepperError(error_code));
}
-void PPB_FileIO_Impl::ExecutePlatformOpenFileCallback(
+void PPB_FileIO_Impl::AsyncOpenFileCallback(
base::PlatformFileError error_code,
base::PassPlatformFile file) {
+ if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) {
+ NOTREACHED();
+ return;
+ }
+
DCHECK(file_ == base::kInvalidPlatformFileValue);
file_ = file.ReleaseValue();
@@ -282,46 +404,73 @@ void PPB_FileIO_Impl::ExecutePlatformOpenFileCallback(
pp_instance(), file_, file_system_url_, file_system_type_));
}
- ExecuteOpenFileCallback(::ppapi::PlatformFileErrorToPepperError(error_code));
+ RunAndRemoveFirstPendingCallback(PlatformFileErrorToPepperError(error_code));
}
-void PPB_FileIO_Impl::ExecutePlatformQueryCallback(
+void PPB_FileIO_Impl::QueryInfoCallback(
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);
+ if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) {
+ NOTREACHED();
+ return;
+ }
+
+ DCHECK(info_);
+ if (error_code == base::PLATFORM_FILE_OK) {
+ info_->size = file_info.size;
+ info_->creation_time = TimeToPPTime(file_info.creation_time);
+ info_->last_access_time = TimeToPPTime(file_info.last_accessed);
+ info_->last_modified_time = TimeToPPTime(file_info.last_modified);
+ info_->system_type = file_system_type_;
+ if (file_info.is_directory)
+ info_->type = PP_FILETYPE_DIRECTORY;
+ else
+ info_->type = PP_FILETYPE_REGULAR;
+ }
+ info_ = NULL;
+ RunAndRemoveFirstPendingCallback(PlatformFileErrorToPepperError(error_code));
}
-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::ReadCallback(base::PlatformFileError error_code,
+ const char* data, int bytes_read) {
+ if (pending_op_ != OPERATION_READ || callbacks_.empty()) {
+ NOTREACHED();
+ return;
+ }
+
+ char* read_buffer = callbacks_.front().read_buffer;
+ DCHECK(data);
+ DCHECK(read_buffer);
+
+ int rv;
+ if (error_code == base::PLATFORM_FILE_OK) {
+ rv = bytes_read;
+ if (file_ != base::kInvalidPlatformFileValue)
+ memcpy(read_buffer, data, bytes_read);
+ } else {
+ rv = PlatformFileErrorToPepperError(error_code);
+ }
+
+ RunAndRemoveFirstPendingCallback(rv);
}
-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::WriteCallback(base::PlatformFileError error_code,
+ int bytes_written) {
+ if (pending_op_ != OPERATION_WRITE || callbacks_.empty()) {
+ NOTREACHED();
+ return;
+ }
+
+ if (error_code != base::PLATFORM_FILE_OK) {
+ RunAndRemoveFirstPendingCallback(
+ PlatformFileErrorToPepperError(error_code));
+ } else {
+ RunAndRemoveFirstPendingCallback(bytes_written);
+ }
}
-void PPB_FileIO_Impl::ExecutePlatformWillWriteCallback(
- base::PlatformFileError error_code,
- int bytes_written) {
+void PPB_FileIO_Impl::WillWriteCallback(base::PlatformFileError error_code,
+ int bytes_written) {
if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) {
NOTREACHED();
return;
@@ -329,7 +478,7 @@ void PPB_FileIO_Impl::ExecutePlatformWillWriteCallback(
if (error_code != base::PLATFORM_FILE_OK) {
RunAndRemoveFirstPendingCallback(
- ::ppapi::PlatformFileErrorToPepperError(error_code));
+ PlatformFileErrorToPepperError(error_code));
} else {
RunAndRemoveFirstPendingCallback(bytes_written);
}
diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.h b/webkit/plugins/ppapi/ppb_file_io_impl.h
index c57430b..c4a0b3a9 100644
--- a/webkit/plugins/ppapi/ppb_file_io_impl.h
+++ b/webkit/plugins/ppapi/ppb_file_io_impl.h
@@ -5,12 +5,19 @@
#ifndef WEBKIT_PLUGINS_PPAPI_PPB_FILE_IO_IMPL_H_
#define WEBKIT_PLUGINS_PPAPI_PPB_FILE_IO_IMPL_H_
+#include <queue>
+
#include "base/basictypes.h"
-#include "base/compiler_specific.h"
+#include "base/file_path.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 "base/platform_file.h"
+#include "ppapi/c/pp_file_info.h"
+#include "ppapi/c/pp_time.h"
+#include "ppapi/shared_impl/resource.h"
+#include "ppapi/thunk/ppb_file_io_api.h"
+#include "webkit/plugins/ppapi/callbacks.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
struct PP_CompletionCallback;
@@ -21,13 +28,35 @@ namespace ppapi {
class QuotaFileIO;
-class PPB_FileIO_Impl : public ::ppapi::PPB_FileIO_Shared {
+class PPB_FileIO_Impl : public ::ppapi::Resource,
+ public ::ppapi::thunk::PPB_FileIO_API {
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).
+ // Resource overrides.
+ virtual ::ppapi::thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE;
+
+ // PPB_FileIO_API implementation.
+ virtual int32_t Open(PP_Resource file_ref,
+ int32_t open_flags,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t Query(PP_FileInfo* info,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t SetLength(int64_t length,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t Flush(PP_CompletionCallback callback) OVERRIDE;
virtual void Close() OVERRIDE;
virtual int32_t GetOSFileDescriptor() OVERRIDE;
virtual int32_t WillWrite(int64_t offset,
@@ -37,51 +66,74 @@ class PPB_FileIO_Impl : public ::ppapi::PPB_FileIO_Shared {
PP_CompletionCallback 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,
- PP_CompletionCallback callback) OVERRIDE;
- virtual int32_t QueryValidated(PP_FileInfo* info,
- PP_CompletionCallback callback) OVERRIDE;
- virtual int32_t TouchValidated(PP_Time last_access_time,
- PP_Time last_modified_time,
- PP_CompletionCallback callback) OVERRIDE;
- virtual int32_t ReadValidated(int64_t offset,
- char* buffer,
- int32_t bytes_to_read,
- PP_CompletionCallback callback) OVERRIDE;
- virtual int32_t WriteValidated(int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- PP_CompletionCallback callback) OVERRIDE;
- virtual int32_t SetLengthValidated(int64_t length,
- PP_CompletionCallback callback) OVERRIDE;
- virtual int32_t FlushValidated(PP_CompletionCallback 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 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);
+ struct CallbackEntry {
+ CallbackEntry();
+ CallbackEntry(const CallbackEntry& entry);
+ ~CallbackEntry();
+
+ scoped_refptr<TrackedCompletionCallback> callback;
+
+ // Pointer back to the caller's read buffer; only used by |Read()|.
+ // Not owned.
+ char* read_buffer;
+ };
+
+ enum OperationType {
+ // 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,
+ // There is no pending operation right now.
+ OPERATION_NONE,
+ };
+
+ // Verifies:
+ // - that |callback| is valid (only nonblocking operation supported);
+ // - that the file is already open or not, depending on |should_be_open|; 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,
+ PP_CompletionCallback callback);
+
+ // 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.
+ void RegisterCallback(OperationType op,
+ PP_CompletionCallback callback,
+ char* read_buffer);
+ void RunAndRemoveFirstPendingCallback(int32_t result);
+
+ void StatusCallback(base::PlatformFileError error_code);
+ void AsyncOpenFileCallback(base::PlatformFileError error_code,
+ base::PassPlatformFile file);
+ void QueryInfoCallback(base::PlatformFileError error_code,
+ const base::PlatformFileInfo& file_info);
+ void ReadCallback(base::PlatformFileError error_code,
+ const char* data, int bytes_read);
+ void WriteCallback(base::PlatformFileError error_code, int bytes_written);
+ void WillWriteCallback(base::PlatformFileError error_code, int bytes_written);
base::PlatformFile file_;
+ PP_FileSystemType file_system_type_;
// Valid only for PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}.
GURL file_system_url_;
+ std::queue<CallbackEntry> callbacks_;
+ OperationType pending_op_;
+
+ // Output buffer pointer for |Query()|; only non-null when a callback is
+ // pending for it.
+ PP_FileInfo* info_;
+
// 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_;
diff --git a/webkit/plugins/ppapi/ppb_flash_file_impl.cc b/webkit/plugins/ppapi/ppb_flash_file_impl.cc
index 46d9786..97eb649 100644
--- a/webkit/plugins/ppapi/ppb_flash_file_impl.cc
+++ b/webkit/plugins/ppapi/ppb_flash_file_impl.cc
@@ -11,11 +11,11 @@
#include "ppapi/c/pp_file_info.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/c/private/ppb_flash_file.h"
-#include "ppapi/shared_impl/file_type_conversion.h"
#include "ppapi/shared_impl/time_conversion.h"
#include "ppapi/thunk/enter.h"
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/file_path.h"
+#include "webkit/plugins/ppapi/file_type_conversions.h"
#include "webkit/plugins/ppapi/host_globals.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/plugin_module.h"
@@ -63,9 +63,7 @@ int32_t OpenModuleLocalFile(PP_Instance pp_instance,
int32_t mode,
PP_FileHandle* file) {
int flags = 0;
- if (!path ||
- !::ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) ||
- !file)
+ if (!path || !PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || !file)
return PP_ERROR_BADARGUMENT;
PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance);
@@ -78,7 +76,7 @@ int32_t OpenModuleLocalFile(PP_Instance pp_instance,
flags,
&base_file);
*file = base_file;
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
int32_t RenameModuleLocalFile(PP_Instance pp_instance,
@@ -94,7 +92,7 @@ int32_t RenameModuleLocalFile(PP_Instance pp_instance,
base::PlatformFileError result = instance->delegate()->RenameFile(
PepperFilePath::MakeModuleLocal(instance->module(), from_path),
PepperFilePath::MakeModuleLocal(instance->module(), to_path));
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
int32_t DeleteModuleLocalFileOrDir(PP_Instance pp_instance,
@@ -110,7 +108,7 @@ int32_t DeleteModuleLocalFileOrDir(PP_Instance pp_instance,
base::PlatformFileError result = instance->delegate()->DeleteFileOrDir(
PepperFilePath::MakeModuleLocal(instance->module(), path),
PPBoolToBool(recursive));
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
int32_t CreateModuleLocalDir(PP_Instance pp_instance, const char* path) {
@@ -123,7 +121,7 @@ int32_t CreateModuleLocalDir(PP_Instance pp_instance, const char* path) {
base::PlatformFileError result = instance->delegate()->CreateDir(
PepperFilePath::MakeModuleLocal(instance->module(), path));
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
int32_t QueryModuleLocalFile(PP_Instance pp_instance,
@@ -151,7 +149,7 @@ int32_t QueryModuleLocalFile(PP_Instance pp_instance,
else
info->type = PP_FILETYPE_REGULAR;
}
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
int32_t GetModuleLocalDirContents(PP_Instance pp_instance,
@@ -170,7 +168,7 @@ int32_t GetModuleLocalDirContents(PP_Instance pp_instance,
&pepper_contents);
if (result != base::PLATFORM_FILE_OK)
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
*contents = new PP_DirContents_Dev;
size_t count = pepper_contents.size();
@@ -220,7 +218,7 @@ int32_t OpenFileRefFile(PP_Resource file_ref_id,
int32_t mode,
PP_FileHandle* file) {
int flags = 0;
- if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || !file)
+ if (!PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || !file)
return PP_ERROR_BADARGUMENT;
EnterResource<PPB_FileRef_API> enter(file_ref_id, true);
@@ -238,7 +236,7 @@ int32_t OpenFileRefFile(PP_Resource file_ref_id,
flags,
&base_file);
*file = base_file;
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
int32_t QueryFileRefFile(PP_Resource file_ref_id,
@@ -267,7 +265,7 @@ int32_t QueryFileRefFile(PP_Resource file_ref_id,
else
info->type = PP_FILETYPE_REGULAR;
}
- return ::ppapi::PlatformFileErrorToPepperError(result);
+ return PlatformFileErrorToPepperError(result);
}
const PPB_Flash_File_FileRef ppb_flash_file_fileref = {