summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-15 22:56:53 +0000
committeryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-15 22:56:53 +0000
commit481a4b7f34565ef087c8aa44c8e04f9f0e466b2d (patch)
tree58a27508ef38cecf35d478710ee9039aa9a2cea0
parente5d5b0e8f45962bbb5cba1a6dd9a3b31eadb9429 (diff)
downloadchromium_src-481a4b7f34565ef087c8aa44c8e04f9f0e466b2d.zip
chromium_src-481a4b7f34565ef087c8aa44c8e04f9f0e466b2d.tar.gz
chromium_src-481a4b7f34565ef087c8aa44c8e04f9f0e466b2d.tar.bz2
Add CreateTemporaryFile to PPB_Flash_File_ModuleLocal.
BUG=129807 TEST=None Review URL: https://chromiumcodereview.appspot.com/10534045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142512 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/ui/ppapi_uitest.cc3
-rw-r--r--content/browser/renderer_host/pepper_file_message_filter.cc78
-rw-r--r--content/browser/renderer_host/pepper_file_message_filter.h2
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.cc14
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.h2
-rw-r--r--ppapi/c/private/ppb_flash_file.h45
-rw-r--r--ppapi/ppapi_sources.gypi2
-rw-r--r--ppapi/proxy/pepper_file_messages.h4
-rw-r--r--ppapi/proxy/ppb_flash_proxy.cc19
-rw-r--r--ppapi/proxy/ppb_flash_proxy.h2
-rw-r--r--ppapi/tests/test_flash_file.cc133
-rw-r--r--ppapi/tests/test_flash_file.h34
-rw-r--r--ppapi/thunk/interfaces_ppb_private_flash.h7
-rw-r--r--ppapi/thunk/ppb_flash_api.h2
-rw-r--r--ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc40
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.cc5
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.h2
-rw-r--r--webkit/plugins/ppapi/plugin_delegate.h2
-rw-r--r--webkit/plugins/ppapi/ppb_flash_impl.cc16
-rw-r--r--webkit/plugins/ppapi/ppb_flash_impl.h2
20 files changed, 389 insertions, 25 deletions
diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc
index 3f0f5d5..dba0015 100644
--- a/chrome/test/ui/ppapi_uitest.cc
+++ b/chrome/test/ui/ppapi_uitest.cc
@@ -1116,4 +1116,7 @@ TEST_PPAPI_IN_PROCESS(MouseCursor)
TEST_PPAPI_OUT_OF_PROCESS(MouseCursor)
TEST_PPAPI_NACL_VIA_HTTP(MouseCursor)
+// Only enabled in out-of-process mode.
+TEST_PPAPI_OUT_OF_PROCESS(FlashFile_CreateTemporaryFile)
+
#endif // ADDRESS_SANITIZER
diff --git a/content/browser/renderer_host/pepper_file_message_filter.cc b/content/browser/renderer_host/pepper_file_message_filter.cc
index d508341..12caa7a 100644
--- a/content/browser/renderer_host/pepper_file_message_filter.cc
+++ b/content/browser/renderer_host/pepper_file_message_filter.cc
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/logging.h"
#include "base/platform_file.h"
#include "base/process_util.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -23,6 +24,8 @@
using content::BrowserThread;
+namespace {
+
// Used to check if the renderer has permission for the requested operation.
// TODO(viettrungluu): Verify these. They don't necessarily quite make sense,
// but it seems to be approximately what the file system code does.
@@ -37,6 +40,28 @@ const int kWritePermissions = base::PLATFORM_FILE_OPEN |
base::PLATFORM_FILE_EXCLUSIVE_WRITE |
base::PLATFORM_FILE_WRITE_ATTRIBUTES;
+IPC::PlatformFileForTransit PlatformFileToPlatformFileForTransit(
+ base::ProcessHandle peer_handle,
+ base::PlatformFile file_handle,
+ base::PlatformFileError* error) {
+ IPC::PlatformFileForTransit file;
+#if defined(OS_WIN)
+ // Duplicate the file handle so that the renderer process can access the file.
+ if (!DuplicateHandle(GetCurrentProcess(), file_handle,
+ peer_handle, &file, 0, false,
+ DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
+ // file_handle is closed whether or not DuplicateHandle succeeds.
+ *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
+ file = INVALID_HANDLE_VALUE;
+ }
+#else
+ file = base::FileDescriptor(file_handle, true);
+#endif
+ return file;
+}
+
+} // namespace
+
PepperFileMessageFilter::PepperFileMessageFilter(int child_id)
: child_id_(child_id),
channel_(NULL) {
@@ -59,6 +84,8 @@ bool PepperFileMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER(PepperFileMsg_CreateDir, OnCreateDir)
IPC_MESSAGE_HANDLER(PepperFileMsg_QueryFile, OnQueryFile)
IPC_MESSAGE_HANDLER(PepperFileMsg_GetDirContents, OnGetDirContents)
+ IPC_MESSAGE_HANDLER(PepperFileMsg_CreateTemporaryFile,
+ OnCreateTemporaryFile)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
return handled;
@@ -110,18 +137,8 @@ void PepperFileMessageFilter::OnOpenFile(
return;
}
-#if defined(OS_WIN)
- // Duplicate the file handle so that the renderer process can access the file.
- if (!DuplicateHandle(GetCurrentProcess(), file_handle,
- peer_handle(), file, 0, false,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- // file_handle is closed whether or not DuplicateHandle succeeds.
- *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
- *file = INVALID_HANDLE_VALUE;
- }
-#else
- *file = base::FileDescriptor(file_handle, true);
-#endif
+ *file = PlatformFileToPlatformFileForTransit(peer_handle(), file_handle,
+ error);
}
void PepperFileMessageFilter::OnRenameFile(
@@ -220,6 +237,43 @@ void PepperFileMessageFilter::OnGetDirContents(
*error = base::PLATFORM_FILE_OK;
}
+void PepperFileMessageFilter::OnCreateTemporaryFile(
+ base::PlatformFileError* error,
+ IPC::PlatformFileForTransit* file) {
+ *error = base::PLATFORM_FILE_ERROR_FAILED;
+ *file = IPC::InvalidPlatformFileForTransit();
+
+ ppapi::PepperFilePath dir_path(
+ ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, FilePath());
+ FilePath validated_dir_path = ValidateAndConvertPepperFilePath(
+ dir_path, kReadPermissions | kWritePermissions);
+ if (validated_dir_path.empty() ||
+ (!file_util::DirectoryExists(validated_dir_path) &&
+ !file_util::CreateDirectory(validated_dir_path))) {
+ *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
+ return;
+ }
+
+ FilePath file_path;
+ if (!file_util::CreateTemporaryFileInDir(validated_dir_path, &file_path))
+ return;
+
+ base::PlatformFile file_handle = base::CreatePlatformFile(
+ file_path,
+ base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_READ |
+ base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_TEMPORARY |
+ base::PLATFORM_FILE_DELETE_ON_CLOSE,
+ NULL, error);
+
+ if (*error != base::PLATFORM_FILE_OK) {
+ DCHECK_EQ(file_handle, base::kInvalidPlatformFileValue);
+ return;
+ }
+
+ *file = PlatformFileToPlatformFileForTransit(peer_handle(), file_handle,
+ error);
+}
+
FilePath PepperFileMessageFilter::ValidateAndConvertPepperFilePath(
const ppapi::PepperFilePath& pepper_path, int flags) {
FilePath file_path; // Empty path returned on error.
diff --git a/content/browser/renderer_host/pepper_file_message_filter.h b/content/browser/renderer_host/pepper_file_message_filter.h
index 4ec0686..fa7bc60 100644
--- a/content/browser/renderer_host/pepper_file_message_filter.h
+++ b/content/browser/renderer_host/pepper_file_message_filter.h
@@ -74,6 +74,8 @@ class PepperFileMessageFilter : public content::BrowserMessageFilter {
void OnGetDirContents(const ppapi::PepperFilePath& path,
ppapi::DirContents* contents,
base::PlatformFileError* error);
+ void OnCreateTemporaryFile(base::PlatformFileError* error,
+ IPC::PlatformFileForTransit* file);
// Validate and convert the Pepper file path to a "real" |FilePath|. Returns
// an empty |FilePath| on error.
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
index 0a30831..18c40a9 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
@@ -978,6 +978,20 @@ base::PlatformFileError PepperPluginDelegateImpl::GetDirContents(
return error;
}
+base::PlatformFileError PepperPluginDelegateImpl::CreateTemporaryFile(
+ base::PlatformFile* file) {
+ IPC::PlatformFileForTransit transit_file;
+ base::PlatformFileError error;
+ IPC::Message* msg = new PepperFileMsg_CreateTemporaryFile(&error,
+ &transit_file);
+ if (!render_view_->Send(msg)) {
+ *file = base::kInvalidPlatformFileValue;
+ return base::PLATFORM_FILE_ERROR_FAILED;
+ }
+ *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
+ return error;
+}
+
void PepperPluginDelegateImpl::SyncGetFileSystemPlatformPath(
const GURL& url, FilePath* platform_path) {
RenderThreadImpl::current()->Send(new FileSystemHostMsg_SyncGetPlatformPath(
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h
index c013402..9cae5fa 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h
@@ -268,6 +268,8 @@ class PepperPluginDelegateImpl
virtual base::PlatformFileError GetDirContents(
const ppapi::PepperFilePath& path,
ppapi::DirContents* contents) OVERRIDE;
+ virtual base::PlatformFileError CreateTemporaryFile(
+ base::PlatformFile* file) OVERRIDE;
virtual void SyncGetFileSystemPlatformPath(
const GURL& url,
FilePath* platform_path) OVERRIDE;
diff --git a/ppapi/c/private/ppb_flash_file.h b/ppapi/c/private/ppb_flash_file.h
index ac8c0fb..521ab39 100644
--- a/ppapi/c/private/ppb_flash_file.h
+++ b/ppapi/c/private/ppb_flash_file.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -34,13 +34,15 @@ struct PP_DirContents_Dev {
};
// PPB_Flash_File_ModuleLocal --------------------------------------------------
-
-#define PPB_FLASH_FILE_MODULELOCAL_INTERFACE "PPB_Flash_File_ModuleLocal;2"
+#define PPB_FLASH_FILE_MODULELOCAL_INTERFACE_2_0 "PPB_Flash_File_ModuleLocal;2"
+#define PPB_FLASH_FILE_MODULELOCAL_INTERFACE_3_0 "PPB_Flash_File_ModuleLocal;3"
+#define PPB_FLASH_FILE_MODULELOCAL_INTERFACE \
+ PPB_FLASH_FILE_MODULELOCAL_INTERFACE_3_0
// This interface provides (for Flash) synchronous access to module-local files.
// Module-local file paths are '/'-separated UTF-8 strings, relative to a
// module-specific root.
-struct PPB_Flash_File_ModuleLocal {
+struct PPB_Flash_File_ModuleLocal_3_0 {
// Does initialization necessary for proxying this interface on background
// threads. You must always call this function before using any other
// function in this interface for a given instance ID.
@@ -97,8 +99,43 @@ struct PPB_Flash_File_ModuleLocal {
// Frees the data allocated by GetDirContents.
void (*FreeDirContents)(PP_Instance instance,
struct PP_DirContents_Dev* contents);
+
+ // Creates a temporary file. The file will be automatically deleted when all
+ // handles to it are closed.
+ // Returns PP_OK if successful, one of the PP_ERROR_* values in case of
+ // failure.
+ //
+ // If successful, |file| is set to a file descriptor (posix) or a HANDLE
+ // (win32) to the file. If failed, |file| is not touched.
+ int32_t (*CreateTemporaryFile)(PP_Instance instance, PP_FileHandle* file);
+};
+
+struct PPB_Flash_File_ModuleLocal_2_0 {
+ bool (*CreateThreadAdapterForInstance)(PP_Instance instance);
+ void (*ClearThreadAdapterForInstance)(PP_Instance instance);
+ int32_t (*OpenFile)(PP_Instance instance,
+ const char* path,
+ int32_t mode,
+ PP_FileHandle* file);
+ int32_t (*RenameFile)(PP_Instance instance,
+ const char* path_from,
+ const char* path_to);
+ int32_t (*DeleteFileOrDir)(PP_Instance instance,
+ const char* path,
+ PP_Bool recursive);
+ int32_t (*CreateDir)(PP_Instance instance, const char* path);
+ int32_t (*QueryFile)(PP_Instance instance,
+ const char* path,
+ struct PP_FileInfo* info);
+ int32_t (*GetDirContents)(PP_Instance instance,
+ const char* path,
+ struct PP_DirContents_Dev** contents);
+ void (*FreeDirContents)(PP_Instance instance,
+ struct PP_DirContents_Dev* contents);
};
+typedef struct PPB_Flash_File_ModuleLocal_3_0 PPB_Flash_File_ModuleLocal;
+
// PPB_Flash_File_FileRef ------------------------------------------------------
#define PPB_FLASH_FILE_FILEREF_INTERFACE "PPB_Flash_File_FileRef;2"
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 9e494a9..155da5a 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -414,6 +414,8 @@
'tests/test_flash.h',
'tests/test_flash_clipboard.cc',
'tests/test_flash_clipboard.h',
+ 'tests/test_flash_file.cc',
+ 'tests/test_flash_file.h',
'tests/test_flash_fullscreen.cc',
'tests/test_flash_fullscreen.h',
'tests/test_flash_message_loop.cc',
diff --git a/ppapi/proxy/pepper_file_messages.h b/ppapi/proxy/pepper_file_messages.h
index c36e7b6..3edd490 100644
--- a/ppapi/proxy/pepper_file_messages.h
+++ b/ppapi/proxy/pepper_file_messages.h
@@ -76,3 +76,7 @@ IPC_SYNC_MESSAGE_CONTROL1_2(PepperFileMsg_GetDirContents,
ppapi::DirContents, /* contents */
base::PlatformFileError /* error_code */)
+// Create a temporary file.
+IPC_SYNC_MESSAGE_CONTROL0_2(PepperFileMsg_CreateTemporaryFile,
+ base::PlatformFileError /* error_code */,
+ IPC::PlatformFileForTransit /* file */)
diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc
index a6b7e62..28444e9 100644
--- a/ppapi/proxy/ppb_flash_proxy.cc
+++ b/ppapi/proxy/ppb_flash_proxy.cc
@@ -498,6 +498,25 @@ int32_t PPB_Flash_Proxy::GetDirContents(PP_Instance,
return ppapi::PlatformFileErrorToPepperError(error);
}
+int32_t PPB_Flash_Proxy::CreateTemporaryFile(PP_Instance instance,
+ PP_FileHandle* file) {
+ if (!file)
+ return PP_ERROR_BADARGUMENT;
+
+ base::PlatformFileError error;
+ IPC::PlatformFileForTransit transit_file;
+
+ if (PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser(
+ new PepperFileMsg_CreateTemporaryFile(&error, &transit_file))) {
+ *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
+ } else {
+ error = base::PLATFORM_FILE_ERROR_FAILED;
+ *file = base::kInvalidPlatformFileValue;
+ }
+
+ return ppapi::PlatformFileErrorToPepperError(error);
+}
+
int32_t PPB_Flash_Proxy::OpenFileRef(PP_Instance instance,
PP_Resource file_ref_id,
int32_t mode,
diff --git a/ppapi/proxy/ppb_flash_proxy.h b/ppapi/proxy/ppb_flash_proxy.h
index be48c14..c441455 100644
--- a/ppapi/proxy/ppb_flash_proxy.h
+++ b/ppapi/proxy/ppb_flash_proxy.h
@@ -107,6 +107,8 @@ class PPB_Flash_Proxy : public InterfaceProxy, public PPB_Flash_Shared {
virtual int32_t GetDirContents(PP_Instance instance,
const char* path,
PP_DirContents_Dev** contents) OVERRIDE;
+ virtual int32_t CreateTemporaryFile(PP_Instance instance,
+ PP_FileHandle* file) OVERRIDE;
virtual int32_t OpenFileRef(PP_Instance instance,
PP_Resource file_ref,
int32_t mode,
diff --git a/ppapi/tests/test_flash_file.cc b/ppapi/tests/test_flash_file.cc
new file mode 100644
index 0000000..b7baeae
--- /dev/null
+++ b/ppapi/tests/test_flash_file.cc
@@ -0,0 +1,133 @@
+// 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/tests/test_flash_file.h"
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/tests/testing_instance.h"
+#include "ppapi/tests/test_utils.h"
+
+#if defined(PPAPI_OS_WIN)
+#include <windows.h>
+#else
+#include <errno.h>
+#include <unistd.h>
+#endif
+
+namespace {
+
+void CloseFileHandle(PP_FileHandle file_handle) {
+#if defined(PPAPI_OS_WIN)
+ CloseHandle(file_handle);
+#else
+ close(file_handle);
+#endif
+}
+
+bool WriteFile(PP_FileHandle file_handle, const std::string& contents) {
+#if defined(PPAPI_OS_WIN)
+ DWORD bytes_written = 0;
+ BOOL result = ::WriteFile(file_handle, contents.c_str(), contents.size(),
+ &bytes_written, NULL);
+ return result && bytes_written == static_cast<DWORD>(contents.size());
+#else
+ ssize_t bytes_written = 0;
+ do {
+ bytes_written = write(file_handle, contents.c_str(), contents.size());
+ } while (bytes_written == -1 && errno == EINTR);
+ return bytes_written == static_cast<ssize_t>(contents.size());
+#endif
+}
+
+bool ReadFile(PP_FileHandle file_handle, std::string* contents) {
+ static const size_t kBufferSize = 1024;
+ char* buffer = new char[kBufferSize];
+ bool result = false;
+ contents->clear();
+
+#if defined(PPAPI_OS_WIN)
+ SetFilePointer(file_handle, 0, NULL, FILE_BEGIN);
+ DWORD bytes_read = 0;
+ do {
+ result = !!::ReadFile(file_handle, buffer, kBufferSize, &bytes_read, NULL);
+ if (result && bytes_read > 0)
+ contents->append(buffer, bytes_read);
+ } while (result && bytes_read > 0);
+#else
+ lseek(file_handle, 0, SEEK_SET);
+ ssize_t bytes_read = 0;
+ do {
+ do {
+ bytes_read = read(file_handle, buffer, kBufferSize);
+ } while (bytes_read == -1 && errno == EINTR);
+ result = bytes_read != -1;
+ if (bytes_read > 0)
+ contents->append(buffer, bytes_read);
+ } while (bytes_read > 0);
+#endif
+
+ delete[] buffer;
+ return result;
+}
+
+} // namespace
+
+REGISTER_TEST_CASE(FlashFile);
+
+TestFlashFile::TestFlashFile(TestingInstance* instance)
+ : TestCase(instance), module_local_interface_(NULL) {
+}
+
+TestFlashFile::~TestFlashFile() {
+}
+
+bool TestFlashFile::Init() {
+ module_local_interface_ = static_cast<const PPB_Flash_File_ModuleLocal*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_FLASH_FILE_MODULELOCAL_INTERFACE));
+ return !!module_local_interface_;
+}
+
+void TestFlashFile::RunTests(const std::string& filter) {
+ RUN_TEST(CreateTemporaryFile, filter);
+}
+
+std::string TestFlashFile::TestCreateTemporaryFile() {
+ // Make sure that the root directory exists.
+ module_local_interface_->CreateDir(instance_->pp_instance(), "");
+
+ int32_t before_create = 0;
+ ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&before_create));
+
+ PP_FileHandle file_handle = PP_kInvalidFileHandle;
+ int32_t result = module_local_interface_->CreateTemporaryFile(
+ instance_->pp_instance(), &file_handle);
+ ASSERT_EQ(result, PP_OK);
+
+ std::string contents = "This is a temp file.";
+ ASSERT_TRUE(WriteFile(file_handle, contents));
+ std::string read_contents;
+ ASSERT_TRUE(ReadFile(file_handle, &read_contents));
+ ASSERT_EQ(contents, read_contents);
+
+ CloseFileHandle(file_handle);
+
+ int32_t after_close = 0;
+ ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&after_close));
+ ASSERT_EQ(before_create, after_close);
+
+ PASS();
+}
+
+std::string TestFlashFile::GetItemCountUnderModuleLocalRoot(
+ int32_t* item_count) {
+ PP_DirContents_Dev* contents = NULL;
+ int32_t result = module_local_interface_->GetDirContents(
+ instance_->pp_instance(), "", &contents);
+ ASSERT_EQ(result, PP_OK);
+
+ *item_count = contents->count;
+ module_local_interface_->FreeDirContents(instance_->pp_instance(), contents);
+ PASS();
+}
diff --git a/ppapi/tests/test_flash_file.h b/ppapi/tests/test_flash_file.h
new file mode 100644
index 0000000..36adfae
--- /dev/null
+++ b/ppapi/tests/test_flash_file.h
@@ -0,0 +1,34 @@
+// 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 PAPPI_TESTS_TEST_FLASH_FILE_H_
+#define PPAPI_TESTS_TEST_FLASH_FILE_H_
+
+#include <string>
+
+#include "ppapi/c/private/ppb_flash_file.h"
+#include "ppapi/tests/test_case.h"
+
+class TestFlashFile: public TestCase {
+ public:
+ explicit TestFlashFile(TestingInstance* instance);
+ virtual ~TestFlashFile();
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTests(const std::string& filter);
+
+ private:
+ // TODO(yzshen): Add more test cases for PPB_Flash_File_ModuleLocal and
+ // PPB_Flash_File_FileRef.
+ std::string TestCreateTemporaryFile();
+
+ // Gets the number of files and directories under the module-local root
+ // directory.
+ std::string GetItemCountUnderModuleLocalRoot(int32_t* item_count);
+
+ const PPB_Flash_File_ModuleLocal* module_local_interface_;
+};
+
+#endif // PPAPI_TESTS_TEST_FLASH_FILE_H_
diff --git a/ppapi/thunk/interfaces_ppb_private_flash.h b/ppapi/thunk/interfaces_ppb_private_flash.h
index c0bd0df..fb5817b 100644
--- a/ppapi/thunk/interfaces_ppb_private_flash.h
+++ b/ppapi/thunk/interfaces_ppb_private_flash.h
@@ -34,8 +34,11 @@ PROXIED_IFACE(PPB_Flash,
PPB_FLASH_CLIPBOARD_INTERFACE_4_0,
PPB_Flash_Clipboard_4_0)
PROXIED_IFACE(PPB_Flash,
- PPB_FLASH_FILE_MODULELOCAL_INTERFACE,
- PPB_Flash_File_ModuleLocal)
+ PPB_FLASH_FILE_MODULELOCAL_INTERFACE_2_0,
+ PPB_Flash_File_ModuleLocal_2_0)
+PROXIED_IFACE(PPB_Flash,
+ PPB_FLASH_FILE_MODULELOCAL_INTERFACE_3_0,
+ PPB_Flash_File_ModuleLocal_3_0)
PROXIED_IFACE(PPB_Flash,
PPB_FLASH_FILE_FILEREF_INTERFACE,
PPB_Flash_File_FileRef)
diff --git a/ppapi/thunk/ppb_flash_api.h b/ppapi/thunk/ppb_flash_api.h
index 0fdcc68..823740e 100644
--- a/ppapi/thunk/ppb_flash_api.h
+++ b/ppapi/thunk/ppb_flash_api.h
@@ -82,6 +82,8 @@ class PPAPI_THUNK_EXPORT PPB_Flash_API {
PP_DirContents_Dev** contents) = 0;
virtual void FreeDirContents(PP_Instance instance,
PP_DirContents_Dev* contents) = 0;
+ virtual int32_t CreateTemporaryFile(PP_Instance instance,
+ PP_FileHandle* file) = 0;
// FlashFile_FileRef.
virtual int32_t OpenFileRef(PP_Instance instance,
diff --git a/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc b/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc
index 6338779..7e9678a 100644
--- a/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc
+++ b/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc
@@ -87,13 +87,20 @@ int32_t GetDirContents(PP_Instance instance,
void FreeDirContents(PP_Instance instance,
PP_DirContents_Dev* contents) {
EnterInstance enter(instance);
- if (enter.succeeded()) {
- return enter.functions()->GetFlashAPI()->FreeDirContents(instance,
- contents);
- }
+ if (enter.succeeded())
+ enter.functions()->GetFlashAPI()->FreeDirContents(instance, contents);
+}
+
+int32_t CreateTemporaryFile(PP_Instance instance, PP_FileHandle* file) {
+ EnterInstance enter(instance);
+ if (enter.failed())
+ return PP_ERROR_BADARGUMENT;
+
+ *file = PP_kInvalidFileHandle;
+ return enter.functions()->GetFlashAPI()->CreateTemporaryFile(instance, file);
}
-const PPB_Flash_File_ModuleLocal g_ppb_flash_file_modulelocal_thunk = {
+const PPB_Flash_File_ModuleLocal_2_0 g_ppb_flash_file_modulelocal_thunk_2_0 = {
&CreateThreadAdapterForInstance,
&ClearThreadAdapterForInstance,
&OpenFile,
@@ -105,10 +112,29 @@ const PPB_Flash_File_ModuleLocal g_ppb_flash_file_modulelocal_thunk = {
&FreeDirContents
};
+const PPB_Flash_File_ModuleLocal_3_0 g_ppb_flash_file_modulelocal_thunk_3_0 = {
+ &CreateThreadAdapterForInstance,
+ &ClearThreadAdapterForInstance,
+ &OpenFile,
+ &RenameFile,
+ &DeleteFileOrDir,
+ &CreateDir,
+ &QueryFile,
+ &GetDirContents,
+ &FreeDirContents,
+ &CreateTemporaryFile
+};
+
} // namespace
-const PPB_Flash_File_ModuleLocal* GetPPB_Flash_File_ModuleLocal_Thunk() {
- return &g_ppb_flash_file_modulelocal_thunk;
+const PPB_Flash_File_ModuleLocal_2_0*
+ GetPPB_Flash_File_ModuleLocal_2_0_Thunk() {
+ return &g_ppb_flash_file_modulelocal_thunk_2_0;
+}
+
+const PPB_Flash_File_ModuleLocal_3_0*
+ GetPPB_Flash_File_ModuleLocal_3_0_Thunk() {
+ return &g_ppb_flash_file_modulelocal_thunk_3_0;
}
} // namespace thunk
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc
index f82fe93..b648e68 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.cc
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc
@@ -237,6 +237,11 @@ base::PlatformFileError MockPluginDelegate::GetDirContents(
return base::PLATFORM_FILE_ERROR_FAILED;
}
+base::PlatformFileError MockPluginDelegate::CreateTemporaryFile(
+ base::PlatformFile* file) {
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
void MockPluginDelegate::SyncGetFileSystemPlatformPath(
const GURL& url,
FilePath* platform_path) {
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h
index 276342f..023c437 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.h
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.h
@@ -114,6 +114,8 @@ class MockPluginDelegate : public PluginDelegate {
virtual base::PlatformFileError GetDirContents(
const ::ppapi::PepperFilePath& path,
::ppapi::DirContents* contents);
+ virtual base::PlatformFileError CreateTemporaryFile(
+ base::PlatformFile* file);
virtual void SyncGetFileSystemPlatformPath(const GURL& url,
FilePath* platform_path);
virtual scoped_refptr<base::MessageLoopProxy>
diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h
index 8bbd125..6f85190 100644
--- a/webkit/plugins/ppapi/plugin_delegate.h
+++ b/webkit/plugins/ppapi/plugin_delegate.h
@@ -474,6 +474,8 @@ class PluginDelegate {
virtual base::PlatformFileError GetDirContents(
const ::ppapi::PepperFilePath& path,
::ppapi::DirContents* contents) = 0;
+ virtual base::PlatformFileError CreateTemporaryFile(
+ base::PlatformFile* file) = 0;
// Synchronously returns the platform file path for a filesystem URL.
virtual void SyncGetFileSystemPlatformPath(const GURL& url,
diff --git a/webkit/plugins/ppapi/ppb_flash_impl.cc b/webkit/plugins/ppapi/ppb_flash_impl.cc
index cfcca21..aa911d7 100644
--- a/webkit/plugins/ppapi/ppb_flash_impl.cc
+++ b/webkit/plugins/ppapi/ppb_flash_impl.cc
@@ -529,6 +529,22 @@ int32_t PPB_Flash_Impl::GetDirContents(PP_Instance pp_instance,
return PP_OK;
}
+int32_t PPB_Flash_Impl::CreateTemporaryFile(PP_Instance instance,
+ PP_FileHandle* file) {
+ if (!file)
+ return PP_ERROR_BADARGUMENT;
+
+ PluginInstance* plugin_instance = HostGlobals::Get()->GetInstance(instance);
+ if (!plugin_instance) {
+ *file = PP_kInvalidFileHandle;
+ return PP_ERROR_FAILED;
+ }
+
+ base::PlatformFileError result =
+ plugin_instance->delegate()->CreateTemporaryFile(file);
+ return ::ppapi::PlatformFileErrorToPepperError(result);
+}
+
int32_t PPB_Flash_Impl::OpenFileRef(PP_Instance pp_instance,
PP_Resource file_ref_id,
int32_t mode,
diff --git a/webkit/plugins/ppapi/ppb_flash_impl.h b/webkit/plugins/ppapi/ppb_flash_impl.h
index c9d4d65..65d8f52 100644
--- a/webkit/plugins/ppapi/ppb_flash_impl.h
+++ b/webkit/plugins/ppapi/ppb_flash_impl.h
@@ -89,6 +89,8 @@ class PPB_Flash_Impl : public ::ppapi::PPB_Flash_Shared {
virtual int32_t GetDirContents(PP_Instance instance,
const char* path,
PP_DirContents_Dev** contents) OVERRIDE;
+ virtual int32_t CreateTemporaryFile(PP_Instance instance,
+ PP_FileHandle* file) OVERRIDE;
virtual int32_t OpenFileRef(PP_Instance instance,
PP_Resource file_ref,
int32_t mode,