diff options
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, |