diff options
author | raymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-08 00:46:23 +0000 |
---|---|---|
committer | raymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-08 00:46:23 +0000 |
commit | 0c92b0d1079123c39f6e8fbd7eb3ff6503e9bccd (patch) | |
tree | b6defa7168b626436612114c0176b91c84284beb | |
parent | e61449d257bd231d718afe97a19a686feac2219d (diff) | |
download | chromium_src-0c92b0d1079123c39f6e8fbd7eb3ff6503e9bccd.zip chromium_src-0c92b0d1079123c39f6e8fbd7eb3ff6503e9bccd.tar.gz chromium_src-0c92b0d1079123c39f6e8fbd7eb3ff6503e9bccd.tar.bz2 |
Refactored the PPB_Flash_File_ModuleLocal/FileRef to the new ppapi resource model
The refactors PPB_Flash_File_ModuleLocal/FileRef to the new resource model. Calls for both these interfaces are now made directly to the browser. This removes the in-process implementation for these interfaces also (as they are flash-only). Tests are added for PPB_Flash_File_ModuleLocal.
Review URL: https://codereview.chromium.org/11359097
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171902 0039d316-1c4b-4281-b951-d872f2087c98
65 files changed, 1256 insertions, 1637 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 8a2daec..a188c1c 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -1826,11 +1826,6 @@ bool ChromeContentBrowserClient::AllowPepperSocketAPI( return false; } -bool ChromeContentBrowserClient::AllowPepperPrivateFileAPI() { - return CommandLine::ForCurrentProcess()->HasSwitch( - switches::kPpapiFlashInProcess); -} - FilePath ChromeContentBrowserClient::GetHyphenDictionaryDirectory() { FilePath directory; PathService::Get(chrome::DIR_APP_DICTIONARIES, &directory); diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 75ce0ae..53a89f3 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -213,7 +213,6 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { content::BrowserContext* browser_context, const GURL& url, const content::SocketPermissionRequest& params) OVERRIDE; - virtual bool AllowPepperPrivateFileAPI() OVERRIDE; virtual FilePath GetHyphenDictionaryDirectory() OVERRIDE; #if defined(OS_POSIX) && !defined(OS_MACOSX) diff --git a/chrome/nacl/nacl_ipc_adapter.cc b/chrome/nacl/nacl_ipc_adapter.cc index 2bbaa1f..d7e7786 100644 --- a/chrome/nacl/nacl_ipc_adapter.cc +++ b/chrome/nacl/nacl_ipc_adapter.cc @@ -546,6 +546,10 @@ bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { base::Passed(&response))); break; } + case ppapi::proxy::SerializedHandle::FILE: + // TODO(raymes): Handle file handles for NaCl. + NOTIMPLEMENTED(); + break; case ppapi::proxy::SerializedHandle::INVALID: { // Nothing to do. TODO(dmichael): Should we log this? Or is it // sometimes okay to pass an INVALID handle? diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 293bd32..964d0e7 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -659,8 +659,6 @@ TEST_PPAPI_OUT_OF_PROCESS(Flash_SetInstanceAlwaysOnTop) TEST_PPAPI_OUT_OF_PROCESS(Flash_GetLocalTimeZoneOffset) TEST_PPAPI_OUT_OF_PROCESS(Flash_GetCommandLineArgs) TEST_PPAPI_OUT_OF_PROCESS(Flash_GetSetting) -// No in-process test for SetCrashData. -TEST_PPAPI_OUT_OF_PROCESS(Flash_SetCrashData) // NaCl based PPAPI tests with WebSocket server TEST_PPAPI_IN_PROCESS(WebSocket_IsWebSocket) @@ -886,8 +884,9 @@ TEST_PPAPI_OUT_OF_PROCESS(MessageLoop_Post) // Going forward, Flash APIs will only work out-of-process. TEST_PPAPI_OUT_OF_PROCESS(Flash_GetProxyForURL) +TEST_PPAPI_OUT_OF_PROCESS(Flash_SetCrashData) TEST_PPAPI_OUT_OF_PROCESS(FlashClipboard) -TEST_PPAPI_OUT_OF_PROCESS(FlashFile_CreateTemporaryFile) +TEST_PPAPI_OUT_OF_PROCESS(FlashFile) // Mac/Aura reach NOTIMPLEMENTED/time out. // mac: http://crbug.com/96767 // aura: http://crbug.com/104384 diff --git a/content/browser/plugin_data_remover_impl.cc b/content/browser/plugin_data_remover_impl.cc index 76043db..731f1e6 100644 --- a/content/browser/plugin_data_remover_impl.cc +++ b/content/browser/plugin_data_remover_impl.cc @@ -14,7 +14,7 @@ #include "base/version.h" #include "content/browser/plugin_process_host.h" #include "content/browser/plugin_service_impl.h" -#include "content/browser/renderer_host/pepper/pepper_file_message_filter.h" +#include "content/browser/renderer_host/pepper/pepper_flash_file_host.h" #include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_context.h" @@ -202,7 +202,7 @@ class PluginDataRemoverImpl::Context IPC::Message* CreatePpapiClearSiteDataMsg(uint64 max_age) { FilePath profile_path = - PepperFileMessageFilter::GetDataDirName(browser_context_path_); + PepperFlashFileHost::GetDataDirName(browser_context_path_); // TODO(vtl): This "duplicates" logic in webkit/plugins/ppapi/file_path.cc // (which prepends the plugin name to the relative part of the path // instead, with the absolute, profile-dependent part being enforced by diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index 655c513..db9f23d 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc @@ -172,13 +172,10 @@ PpapiPluginProcessHost::PpapiPluginProcessHost( permissions_, host_resolver); - host_impl_.reset(new BrowserPpapiHostImpl(this, permissions_)); - - file_filter_ = new PepperTrustedFileMessageFilter( - process_->GetData().id, info.name, profile_data_directory); + host_impl_.reset(new BrowserPpapiHostImpl(this, permissions_, info.name, + profile_data_directory)); process_->GetHost()->AddFilter(filter_.get()); - process_->GetHost()->AddFilter(file_filter_.get()); process_->GetHost()->AddFilter(host_impl_->message_filter()); GetContentClient()->browser()->DidCreatePpapiPlugin(host_impl_.get()); @@ -190,7 +187,12 @@ PpapiPluginProcessHost::PpapiPluginProcessHost() PROCESS_TYPE_PPAPI_BROKER, this)); ppapi::PpapiPermissions permissions; // No permissions. - host_impl_.reset(new BrowserPpapiHostImpl(this, permissions)); + // The plugin name and profile data directory shouldn't be needed for the + // broker. + std::string plugin_name; + FilePath profile_data_directory; + host_impl_.reset(new BrowserPpapiHostImpl(this, permissions, plugin_name, + profile_data_directory)); } bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) { diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h index cbab68c..9dc3481 100644 --- a/content/browser/ppapi_plugin_process_host.h +++ b/content/browser/ppapi_plugin_process_host.h @@ -13,7 +13,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" -#include "content/browser/renderer_host/pepper/pepper_file_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/browser/browser_child_process_host_iterator.h" @@ -140,9 +139,6 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate, ppapi::PpapiPermissions permissions_; scoped_ptr<BrowserPpapiHostImpl> host_impl_; - // Handles filesystem requests from flash plugins. May be NULL. - scoped_refptr<PepperFileMessageFilter> file_filter_; - // Observes network changes. May be NULL. scoped_ptr<PluginNetworkObserver> network_observer_; diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc index 3e074c4..4dcb18d 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc @@ -3,8 +3,8 @@ // found in the LICENSE file. #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" -#include "content/browser/renderer_host/pepper/pepper_message_filter.h" +#include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_view_host.h" #include "ipc/ipc_message_macros.h" @@ -20,8 +20,14 @@ BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess( net::HostResolver* host_resolver, int render_process_id, int render_view_id) { + // TODO(raymes): Figure out how to plumb plugin_name and + // profile_data_directory through for NaCl. They are currently only needed for + // PPB_Flash_File interfaces so it doesn't matter. + std::string plugin_name; + FilePath profile_data_directory; BrowserPpapiHostImpl* browser_ppapi_host = - new BrowserPpapiHostImpl(sender, permissions); + new BrowserPpapiHostImpl(sender, permissions, plugin_name, + profile_data_directory); browser_ppapi_host->set_plugin_process_handle(plugin_child_process); channel->AddFilter( @@ -37,9 +43,13 @@ BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess( BrowserPpapiHostImpl::BrowserPpapiHostImpl( IPC::Sender* sender, - const ppapi::PpapiPermissions& permissions) + const ppapi::PpapiPermissions& permissions, + const std::string& plugin_name, + const FilePath& profile_data_directory) : ppapi_host_(sender, permissions), - plugin_process_handle_(base::kNullProcessHandle) { + plugin_process_handle_(base::kNullProcessHandle), + plugin_name_(plugin_name), + profile_data_directory_(profile_data_directory) { message_filter_ = new HostMessageFilter(&ppapi_host_); ppapi_host_.AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>( new ContentBrowserPepperHostFactory(this))); @@ -80,6 +90,14 @@ bool BrowserPpapiHostImpl::GetRenderViewIDsForInstance( return true; } +const std::string& BrowserPpapiHostImpl::GetPluginName() { + return plugin_name_; +} + +const FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() { + return profile_data_directory_; +} + void BrowserPpapiHostImpl::AddInstanceForView(PP_Instance instance, int render_process_id, int render_view_id) { diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h index bee35a6..888bb7c 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h @@ -6,9 +6,11 @@ #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_BROWSER_PPAPI_HOST_IMPL_H_ #include <map> +#include <string> #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/file_path.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/common/content_export.h" #include "content/public/browser/browser_ppapi_host.h" @@ -23,7 +25,9 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { // as it is known (we start the process asynchronously so it won't be known // when this object is created). BrowserPpapiHostImpl(IPC::Sender* sender, - const ppapi::PpapiPermissions& permissions); + const ppapi::PpapiPermissions& permissions, + const std::string& plugin_name, + const FilePath& profile_data_directory); virtual ~BrowserPpapiHostImpl(); // BrowserPpapiHost. @@ -33,6 +37,8 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { virtual bool GetRenderViewIDsForInstance(PP_Instance instance, int* render_process_id, int* render_view_id) const OVERRIDE; + virtual const std::string& GetPluginName() OVERRIDE; + virtual const FilePath& GetProfileDataDirectory() OVERRIDE; void set_plugin_process_handle(base::ProcessHandle handle) { plugin_process_handle_ = handle; @@ -79,6 +85,8 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { ppapi::host::PpapiHost ppapi_host_; base::ProcessHandle plugin_process_handle_; + std::string plugin_name_; + FilePath profile_data_directory_; // Tracks all PP_Instances in this plugin and maps them to // RenderProcess/RenderView IDs. diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc index 941782c..ea81b7b 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc @@ -13,7 +13,9 @@ BrowserPpapiHostTest::BrowserPpapiHostTest() : sink_() { ppapi_host_.reset(new BrowserPpapiHostImpl( &sink_, - ppapi::PpapiPermissions::AllPermissions())); + ppapi::PpapiPermissions::AllPermissions(), + std::string(), + FilePath())); ppapi_host_->set_plugin_process_handle(base::GetCurrentProcessHandle()); } diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc index 3033adb..fd9a13a 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc @@ -6,6 +6,7 @@ #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_flash_browser_host.h" +#include "content/browser/renderer_host/pepper/pepper_flash_file_host.h" #include "content/browser/renderer_host/pepper/pepper_gamepad_host.h" #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h" #include "content/browser/renderer_host/pepper/pepper_printing_host.h" @@ -62,6 +63,9 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( case PpapiHostMsg_Flash_Create::ID: return scoped_ptr<ResourceHost>(new PepperFlashBrowserHost( host_, instance, params.pp_resource())); + case PpapiHostMsg_FlashFile_Create::ID: + return scoped_ptr<ResourceHost>(new PepperFlashFileHost( + host_, instance, params.pp_resource())); } } diff --git a/content/browser/renderer_host/pepper/pepper_file_message_filter.cc b/content/browser/renderer_host/pepper/pepper_file_message_filter.cc deleted file mode 100644 index 428c6ed..0000000 --- a/content/browser/renderer_host/pepper/pepper_file_message_filter.cc +++ /dev/null @@ -1,367 +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 "content/browser/renderer_host/pepper/pepper_file_message_filter.h" - -#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 "base/threading/sequenced_worker_pool.h" -#include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/renderer_host/render_process_host_impl.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/common/content_constants.h" -#include "ipc/ipc_platform_file.h" -#include "ppapi/proxy/pepper_file_messages.h" -#include "ppapi/shared_impl/file_path.h" - -#if defined(OS_POSIX) -#include "base/file_descriptor_posix.h" -#endif - -namespace content { -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. -const int kReadPermissions = base::PLATFORM_FILE_OPEN | - base::PLATFORM_FILE_READ | - base::PLATFORM_FILE_EXCLUSIVE_READ; -const int kWritePermissions = base::PLATFORM_FILE_OPEN | - base::PLATFORM_FILE_CREATE | - base::PLATFORM_FILE_CREATE_ALWAYS | - base::PLATFORM_FILE_OPEN_TRUNCATED | - base::PLATFORM_FILE_WRITE | - 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) { -} - -base::TaskRunner* PepperFileMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& message) { - // The blocking pool provides a pool of threads to run file - // operations, instead of a single thread which might require - // queuing time. Since these messages are synchronous as sent from - // the plugin, the sending thread cannot send a new message until - // this one returns, so there is no need to sequence tasks here. If - // the plugin has multiple threads, it cannot make assumptions about - // ordering of IPC message sends, so it cannot make assumptions - // about ordering of operations caused by those IPC messages. - if (IPC_MESSAGE_CLASS(message) == PepperFileMsgStart) - return BrowserThread::GetBlockingPool(); - return NULL; -} - -bool PepperFileMessageFilter::OnMessageReceived(const IPC::Message& message, - bool* message_was_ok) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_EX(PepperFileMessageFilter, message, *message_was_ok) - IPC_MESSAGE_HANDLER(PepperFileMsg_OpenFile, OnOpenFile) - IPC_MESSAGE_HANDLER(PepperFileMsg_RenameFile, OnRenameFile) - IPC_MESSAGE_HANDLER(PepperFileMsg_DeleteFileOrDir, OnDeleteFileOrDir) - 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; -} - -void PepperFileMessageFilter::OnDestruct() const { - BrowserThread::DeleteOnIOThread::Destruct(this); -} - -// static -FilePath PepperFileMessageFilter::GetDataDirName(const FilePath& profile_path) { - return profile_path.Append(kPepperDataDirname); -} - -PepperFileMessageFilter::~PepperFileMessageFilter() { - // This function should be called on the IO thread. - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); -} - -// Called on the FILE thread: -void PepperFileMessageFilter::OnOpenFile( - const ppapi::PepperFilePath& path, - int flags, - base::PlatformFileError* error, - IPC::PlatformFileForTransit* file) { - FilePath full_path = ValidateAndConvertPepperFilePath(path, flags); - if (full_path.empty()) { - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - *file = IPC::InvalidPlatformFileForTransit(); - return; - } - - base::PlatformFile file_handle = base::CreatePlatformFile( - full_path, flags, NULL, error); - - if (*error != base::PLATFORM_FILE_OK || - file_handle == base::kInvalidPlatformFileValue) { - *file = IPC::InvalidPlatformFileForTransit(); - return; - } - - // Make sure we didn't try to open a directory: directory fd shouldn't pass - // to untrusted processes because they open security holes. - base::PlatformFileInfo info; - if (!base::GetPlatformFileInfo(file_handle, &info) || info.is_directory) { - // When in doubt, throw it out. - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - *file = IPC::InvalidPlatformFileForTransit(); - return; - } - - *file = PlatformFileToPlatformFileForTransit(peer_handle(), file_handle, - error); -} - -void PepperFileMessageFilter::OnRenameFile( - const ppapi::PepperFilePath& from_path, - const ppapi::PepperFilePath& to_path, - base::PlatformFileError* error) { - FilePath from_full_path = ValidateAndConvertPepperFilePath(from_path, - kWritePermissions); - FilePath to_full_path = ValidateAndConvertPepperFilePath(to_path, - kWritePermissions); - if (from_full_path.empty() || to_full_path.empty()) { - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - return; - } - - bool result = file_util::Move(from_full_path, to_full_path); - *error = result ? base::PLATFORM_FILE_OK - : base::PLATFORM_FILE_ERROR_ACCESS_DENIED; -} - -void PepperFileMessageFilter::OnDeleteFileOrDir( - const ppapi::PepperFilePath& path, - bool recursive, - base::PlatformFileError* error) { - FilePath full_path = ValidateAndConvertPepperFilePath(path, - kWritePermissions); - if (full_path.empty()) { - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - return; - } - - bool result = file_util::Delete(full_path, recursive); - *error = result ? base::PLATFORM_FILE_OK - : base::PLATFORM_FILE_ERROR_ACCESS_DENIED; -} - -void PepperFileMessageFilter::OnCreateDir( - const ppapi::PepperFilePath& path, - base::PlatformFileError* error) { - FilePath full_path = ValidateAndConvertPepperFilePath(path, - kWritePermissions); - if (full_path.empty()) { - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - return; - } - - bool result = file_util::CreateDirectory(full_path); - *error = result ? base::PLATFORM_FILE_OK - : base::PLATFORM_FILE_ERROR_ACCESS_DENIED; -} - -void PepperFileMessageFilter::OnQueryFile( - const ppapi::PepperFilePath& path, - base::PlatformFileInfo* info, - base::PlatformFileError* error) { - FilePath full_path = ValidateAndConvertPepperFilePath(path, kReadPermissions); - if (full_path.empty()) { - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - return; - } - - bool result = file_util::GetFileInfo(full_path, info); - *error = result ? base::PLATFORM_FILE_OK - : base::PLATFORM_FILE_ERROR_ACCESS_DENIED; -} - -void PepperFileMessageFilter::OnGetDirContents( - const ppapi::PepperFilePath& path, - ppapi::DirContents* contents, - base::PlatformFileError* error) { - FilePath full_path = ValidateAndConvertPepperFilePath(path, kReadPermissions); - if (full_path.empty()) { - *error = base::PLATFORM_FILE_ERROR_ACCESS_DENIED; - return; - } - - contents->clear(); - - file_util::FileEnumerator enumerator(full_path, false, - file_util::FileEnumerator::FILES | - file_util::FileEnumerator::DIRECTORIES | - file_util::FileEnumerator::INCLUDE_DOT_DOT); - - while (!enumerator.Next().empty()) { - file_util::FileEnumerator::FindInfo info; - enumerator.GetFindInfo(&info); - ppapi::DirEntry entry = { - file_util::FileEnumerator::GetFilename(info), - file_util::FileEnumerator::IsDirectory(info) - }; - contents->push_back(entry); - } - - *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. - if (pepper_path.domain() == ppapi::PepperFilePath::DOMAIN_ABSOLUTE) { - if (pepper_path.path().IsAbsolute() && - ChildProcessSecurityPolicyImpl::GetInstance()->HasPermissionsForFile( - child_id(), pepper_path.path(), flags)) - file_path = pepper_path.path(); - } - return file_path; -} - -PepperTrustedFileMessageFilter::PepperTrustedFileMessageFilter( - int child_id, - const std::string& plugin_name, - const FilePath& profile_data_directory) - : PepperFileMessageFilter(child_id) { - plugin_data_directory_ = GetDataDirName(profile_data_directory).Append( - FilePath::FromUTF8Unsafe(plugin_name)); -} - -PepperTrustedFileMessageFilter::~PepperTrustedFileMessageFilter() { -} - -FilePath PepperTrustedFileMessageFilter::ValidateAndConvertPepperFilePath( - const ppapi::PepperFilePath& pepper_path, - int flags) { - FilePath file_path; // Empty path returned on error. - switch (pepper_path.domain()) { - case ppapi::PepperFilePath::DOMAIN_ABSOLUTE: - if (pepper_path.path().IsAbsolute() && - ChildProcessSecurityPolicyImpl::GetInstance()->HasPermissionsForFile( - child_id(), pepper_path.path(), flags)) - file_path = pepper_path.path(); - break; - case ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL: - // This filter provides the module name portion of the path to prevent - // plugins from accessing each other's data. - if (!pepper_path.path().IsAbsolute() && - !pepper_path.path().ReferencesParent()) - file_path = plugin_data_directory_.Append(pepper_path.path()); - break; - default: - NOTREACHED(); - break; - } - return file_path; -} - -PepperUnsafeFileMessageFilter::PepperUnsafeFileMessageFilter( - int child_id, - const FilePath& profile_data_directory) - : PepperFileMessageFilter(child_id) { - profile_data_directory_ = GetDataDirName(profile_data_directory); -} - -PepperUnsafeFileMessageFilter::~PepperUnsafeFileMessageFilter() { -} - -FilePath PepperUnsafeFileMessageFilter::ValidateAndConvertPepperFilePath( - const ppapi::PepperFilePath& pepper_path, - int flags) { - FilePath file_path; // Empty path returned on error. - switch (pepper_path.domain()) { - case ppapi::PepperFilePath::DOMAIN_ABSOLUTE: - if (pepper_path.path().IsAbsolute() && - ChildProcessSecurityPolicyImpl::GetInstance()->HasPermissionsForFile( - child_id(), pepper_path.path(), flags)) - file_path = pepper_path.path(); - break; - case ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL: - // The message supplies the module portion of the path (so it can't - // really be trusted). - if (!pepper_path.path().IsAbsolute() && - !pepper_path.path().ReferencesParent()) - file_path = profile_data_directory_.Append(pepper_path.path()); - break; - default: - NOTREACHED(); - break; - } - return file_path; -} - -} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_file_message_filter.h b/content/browser/renderer_host/pepper/pepper_file_message_filter.h deleted file mode 100644 index 7efca84..0000000 --- a/content/browser/renderer_host/pepper/pepper_file_message_filter.h +++ /dev/null @@ -1,138 +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 CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_MESSAGE_FILTER_H_ -#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_MESSAGE_FILTER_H_ - -#include <string> -#include <vector> - -#include "base/file_path.h" -#include "base/memory/ref_counted.h" -#include "base/process.h" -#include "base/sequenced_task_runner_helpers.h" -#include "build/build_config.h" -#include "content/public/browser/browser_message_filter.h" -#include "ipc/ipc_platform_file.h" -#include "ppapi/shared_impl/dir_contents.h" - -namespace ppapi { -class PepperFilePath; -} - -namespace content { -class BrowserContext; - -// A message filter for Pepper-specific File I/O messages. Used on -// renderer channels, this denys the renderer the trusted operations -// permitted only by plugin processes. -class PepperFileMessageFilter : public BrowserMessageFilter { - public: - explicit PepperFileMessageFilter(int child_id); - - // BrowserMessageFilter methods: - virtual base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& message) OVERRIDE; - virtual bool OnMessageReceived(const IPC::Message& message, - bool* message_was_ok) OVERRIDE; - virtual void OnDestruct() const OVERRIDE; - - int child_id() const { return child_id_; } - - // Returns the name of the pepper data directory that we'll use for local - // storage. The argument is the profile path so that this can be used on any - // thread independent of the profile context. - static FilePath GetDataDirName(const FilePath& profile_path); - - protected: - virtual ~PepperFileMessageFilter(); - - private: - friend class BrowserThread; - friend class base::DeleteHelper<PepperFileMessageFilter>; - - // Called on the FILE thread: - void OnOpenFile(const ppapi::PepperFilePath& path, - int flags, - base::PlatformFileError* error, - IPC::PlatformFileForTransit* file); - void OnRenameFile(const ppapi::PepperFilePath& from_path, - const ppapi::PepperFilePath& to_path, - base::PlatformFileError* error); - void OnDeleteFileOrDir(const ppapi::PepperFilePath& path, - bool recursive, - base::PlatformFileError* error); - void OnCreateDir(const ppapi::PepperFilePath& path, - base::PlatformFileError* error); - void OnQueryFile(const ppapi::PepperFilePath& path, - base::PlatformFileInfo* info, - base::PlatformFileError* error); - 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. - virtual FilePath ValidateAndConvertPepperFilePath( - const ppapi::PepperFilePath& pepper_path, int flags); - - // The ID of the child process. - const int child_id_; - - // The channel associated with the renderer connection. This pointer is not - // owned by this class. - IPC::Channel* channel_; - - DISALLOW_COPY_AND_ASSIGN(PepperFileMessageFilter); -}; - -// Message filter used with out-of-process pepper flash plugin channels that -// provides the trusted operations permitted only by plugin processes. -class PepperTrustedFileMessageFilter : public PepperFileMessageFilter { - public: - PepperTrustedFileMessageFilter(int child_id, - const std::string& plugin_name, - const FilePath& profile_data_directory); - - protected: - virtual ~PepperTrustedFileMessageFilter(); - - private: - virtual FilePath ValidateAndConvertPepperFilePath( - const ppapi::PepperFilePath& pepper_path, int flags) OVERRIDE; - - // The path to the per-plugin directory under the per-profile data directory - // (includes module name). - FilePath plugin_data_directory_; - - DISALLOW_COPY_AND_ASSIGN(PepperTrustedFileMessageFilter); -}; - -// Message filter used with in-process pepper flash plugins that provides the -// renderer channels with the trusted operations permitted only by plugin -// process. This should not be used as part of normal operations, and may -// only be applied under the control of a command-line flag. -class PepperUnsafeFileMessageFilter : public PepperFileMessageFilter { - public: - PepperUnsafeFileMessageFilter(int child_id, - const FilePath& profile_data_directory); - - protected: - virtual ~PepperUnsafeFileMessageFilter(); - - private: - virtual FilePath ValidateAndConvertPepperFilePath( - const ppapi::PepperFilePath& pepper_path, int flags) OVERRIDE; - - // The per-profile data directory (not including module name). - FilePath profile_data_directory_; - - DISALLOW_COPY_AND_ASSIGN(PepperUnsafeFileMessageFilter); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_MESSAGE_FILTER_H_ diff --git a/content/browser/renderer_host/pepper/pepper_flash_file_host.cc b/content/browser/renderer_host/pepper/pepper_flash_file_host.cc new file mode 100644 index 0000000..f4dc898 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_flash_file_host.cc @@ -0,0 +1,367 @@ +// 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/browser/renderer_host/pepper/pepper_flash_file_host.h" + +#include "base/bind.h" +#include "base/file_util.h" +#include "base/task_runner.h" +#include "base/threading/sequenced_worker_pool.h" +#include "content/browser/child_process_security_policy_impl.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/content_constants.h" +#include "ipc/ipc_platform_file.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_path.h" +#include "ppapi/shared_impl/file_type_conversion.h" + +namespace content { + +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. +const int kReadPermissions = base::PLATFORM_FILE_OPEN | + base::PLATFORM_FILE_READ | + base::PLATFORM_FILE_EXCLUSIVE_READ; +const int kWritePermissions = base::PLATFORM_FILE_OPEN | + base::PLATFORM_FILE_CREATE | + base::PLATFORM_FILE_CREATE_ALWAYS | + base::PLATFORM_FILE_OPEN_TRUNCATED | + base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_EXCLUSIVE_WRITE | + base::PLATFORM_FILE_WRITE_ATTRIBUTES; + +// All file messages are handled by BrowserThread's blocking pool. +class FileMessageFilter : public ppapi::host::ResourceMessageFilter { + public: + FileMessageFilter(const std::string& plugin_name, + const FilePath& profile_data_directory, + int render_process_id, + base::ProcessHandle plugin_process_handle); + protected: + // ppapi::host::ResourceMessageFilter implementation. + virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( + const IPC::Message& msg) OVERRIDE; + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + private: + virtual ~FileMessageFilter(); + + int32_t OnOpenFile(ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path, + int flags); + int32_t OnRenameFile(ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& from_path, + const ppapi::PepperFilePath& to_path); + int32_t OnDeleteFileOrDir(ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path, + bool recursive); + int32_t OnCreateDir(ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path); + int32_t OnQueryFile(ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path); + int32_t OnGetDirContents(ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path); + int32_t OnCreateTemporaryFile(ppapi::host::HostMessageContext* context); + + FilePath ValidateAndConvertPepperFilePath( + const ppapi::PepperFilePath& pepper_path, + int flags); + + FilePath plugin_data_directory_; + int render_process_id_; + base::ProcessHandle plugin_process_handle_; +}; + +FileMessageFilter::FileMessageFilter( + const std::string& plugin_name, + const FilePath& profile_data_directory, + int render_process_id, + base::ProcessHandle plugin_process_handle) + : render_process_id_(render_process_id), + plugin_process_handle_(plugin_process_handle) { + if (profile_data_directory.empty() || plugin_name.empty()) { + // These are used to construct the path. If they are not set it means we + // will construct a bad path and could provide access to the wrong files. + // In this case, |plugin_data_directory_| will remain unset and + // |ValidateAndConvertPepperFilePath| will fail. + NOTREACHED(); + } else { + plugin_data_directory_ = PepperFlashFileHost::GetDataDirName( + profile_data_directory).Append(FilePath::FromUTF8Unsafe(plugin_name)); + } +} + +FileMessageFilter::~FileMessageFilter() { +} + +scoped_refptr<base::TaskRunner> +FileMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) { + // The blocking pool provides a pool of threads to run file + // operations, instead of a single thread which might require + // queuing time. Since these messages are synchronous as sent from + // the plugin, the sending thread cannot send a new message until + // this one returns, so there is no need to sequence tasks here. If + // the plugin has multiple threads, it cannot make assumptions about + // ordering of IPC message sends, so it cannot make assumptions + // about ordering of operations caused by those IPC messages. + return scoped_refptr<base::TaskRunner>(BrowserThread::GetBlockingPool()); +} + +int32_t FileMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + IPC_BEGIN_MESSAGE_MAP(FileMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_OpenFile, + OnOpenFile) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_RenameFile, + OnRenameFile) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_DeleteFileOrDir, + OnDeleteFileOrDir) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_CreateDir, + OnCreateDir) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_QueryFile, + OnQueryFile) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_GetDirContents, + OnGetDirContents) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( + PpapiHostMsg_FlashFile_CreateTemporaryFile, + OnCreateTemporaryFile) + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t FileMessageFilter::OnOpenFile( + ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path, + int flags) { + FilePath full_path = ValidateAndConvertPepperFilePath(path, flags); + if (full_path.empty()) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; + base::PlatformFile file_handle = base::CreatePlatformFile( + full_path, flags, NULL, &error); + if (error != base::PLATFORM_FILE_OK) { + DCHECK_EQ(file_handle, base::kInvalidPlatformFileValue); + return ppapi::PlatformFileErrorToPepperError(error); + } + + // Make sure we didn't try to open a directory: directory fd shouldn't be + // passed to untrusted processes because they open security holes. + base::PlatformFileInfo info; + if (!base::GetPlatformFileInfo(file_handle, &info) || info.is_directory) { + // When in doubt, throw it out. + base::ClosePlatformFile(file_handle); + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + IPC::PlatformFileForTransit file = IPC::GetFileHandleForProcess(file_handle, + plugin_process_handle_, true); + ppapi::host::ReplyMessageContext reply_context = + context->MakeReplyMessageContext(); + reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle( + ppapi::proxy::SerializedHandle::FILE, file)); + SendReply(reply_context, IPC::Message()); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileMessageFilter::OnRenameFile( + ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& from_path, + const ppapi::PepperFilePath& to_path) { + FilePath from_full_path = ValidateAndConvertPepperFilePath(from_path, + kWritePermissions); + FilePath to_full_path = ValidateAndConvertPepperFilePath(to_path, + kWritePermissions); + if (from_full_path.empty() || to_full_path.empty()) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + bool result = file_util::Move(from_full_path, to_full_path); + return ppapi::PlatformFileErrorToPepperError(result ? + base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_ACCESS_DENIED); +} + +int32_t FileMessageFilter::OnDeleteFileOrDir( + ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path, + bool recursive) { + FilePath full_path = ValidateAndConvertPepperFilePath(path, + kWritePermissions); + if (full_path.empty()) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + bool result = file_util::Delete(full_path, recursive); + return ppapi::PlatformFileErrorToPepperError(result ? + base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_ACCESS_DENIED); +} +int32_t FileMessageFilter::OnCreateDir( + ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path) { + FilePath full_path = ValidateAndConvertPepperFilePath(path, + kWritePermissions); + if (full_path.empty()) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + bool result = file_util::CreateDirectory(full_path); + return ppapi::PlatformFileErrorToPepperError(result ? + base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_ACCESS_DENIED); +} + +int32_t FileMessageFilter::OnQueryFile( + ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path) { + FilePath full_path = ValidateAndConvertPepperFilePath(path, + kReadPermissions); + if (full_path.empty()) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + base::PlatformFileInfo info; + bool result = file_util::GetFileInfo(full_path, &info); + context->reply_msg = PpapiPluginMsg_FlashFile_QueryFileReply(info); + return ppapi::PlatformFileErrorToPepperError(result ? + base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_ACCESS_DENIED); +} + +int32_t FileMessageFilter::OnGetDirContents( + ppapi::host::HostMessageContext* context, + const ppapi::PepperFilePath& path) { + FilePath full_path = ValidateAndConvertPepperFilePath(path, kReadPermissions); + if (full_path.empty()) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + ppapi::DirContents contents; + file_util::FileEnumerator enumerator(full_path, false, + file_util::FileEnumerator::FILES | + file_util::FileEnumerator::DIRECTORIES | + file_util::FileEnumerator::INCLUDE_DOT_DOT); + + while (!enumerator.Next().empty()) { + file_util::FileEnumerator::FindInfo info; + enumerator.GetFindInfo(&info); + ppapi::DirEntry entry = { + file_util::FileEnumerator::GetFilename(info), + file_util::FileEnumerator::IsDirectory(info) + }; + contents.push_back(entry); + } + + context->reply_msg = PpapiPluginMsg_FlashFile_GetDirContentsReply(contents); + return PP_OK; +} + +int32_t FileMessageFilter::OnCreateTemporaryFile( + ppapi::host::HostMessageContext* context) { + 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))) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_ACCESS_DENIED); + } + + FilePath file_path; + if (!file_util::CreateTemporaryFileInDir(validated_dir_path, &file_path)) { + return ppapi::PlatformFileErrorToPepperError( + base::PLATFORM_FILE_ERROR_FAILED); + } + + base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; + 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 ppapi::PlatformFileErrorToPepperError(error); + } + + IPC::PlatformFileForTransit file = IPC::GetFileHandleForProcess(file_handle, + plugin_process_handle_, true); + ppapi::host::ReplyMessageContext reply_context = + context->MakeReplyMessageContext(); + reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle( + ppapi::proxy::SerializedHandle::FILE, file)); + SendReply(reply_context, IPC::Message()); + return PP_OK_COMPLETIONPENDING; +} + +FilePath FileMessageFilter::ValidateAndConvertPepperFilePath( + const ppapi::PepperFilePath& pepper_path, + int flags) { + FilePath file_path; // Empty path returned on error. + switch (pepper_path.domain()) { + case ppapi::PepperFilePath::DOMAIN_ABSOLUTE: + if (pepper_path.path().IsAbsolute() && + ChildProcessSecurityPolicyImpl::GetInstance()->HasPermissionsForFile( + render_process_id_, pepper_path.path(), flags)) + file_path = pepper_path.path(); + break; + case ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL: + // This filter provides the module name portion of the path to prevent + // plugins from accessing each other's data. + if (!plugin_data_directory_.empty() && + !pepper_path.path().IsAbsolute() && + !pepper_path.path().ReferencesParent()) + file_path = plugin_data_directory_.Append(pepper_path.path()); + break; + default: + NOTREACHED(); + break; + } + return file_path; +} + +} // namespace + +PepperFlashFileHost::PepperFlashFileHost( + BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource) { + int render_process_id, unused; + host->GetRenderViewIDsForInstance(instance, &render_process_id, &unused); + AddFilter(scoped_refptr<ppapi::host::ResourceMessageFilter>( + new FileMessageFilter(host->GetPluginName(), + host->GetProfileDataDirectory(), + render_process_id, + host->GetPluginProcessHandle()))); +} + +PepperFlashFileHost::~PepperFlashFileHost() { +} + +// static +FilePath PepperFlashFileHost::GetDataDirName(const FilePath& profile_path) { + return profile_path.Append(kPepperDataDirname); +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_flash_file_host.h b/content/browser/renderer_host/pepper/pepper_flash_file_host.h new file mode 100644 index 0000000..6b45d98 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_flash_file_host.h @@ -0,0 +1,44 @@ +// 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_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_HOST_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_HOST_H_ + +#include "base/compiler_specific.h" +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/process.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/host/resource_message_filter.h" + +namespace ppapi { +class PepperFilePath; +} + +namespace ppapi { +namespace host { +struct ReplyMessageContext; +} +} + +namespace content { + +class BrowserPpapiHost; + +class PepperFlashFileHost : public ppapi::host::ResourceHost { + public: + PepperFlashFileHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + virtual ~PepperFlashFileHost(); + + static FilePath GetDataDirName(const FilePath& profile_path); + + private: + DISALLOW_COPY_AND_ASSIGN(PepperFlashFileHost); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_FILE_HOST_H_ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index bed26aa..77aec55 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -70,7 +70,6 @@ #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #include "content/browser/renderer_host/media/video_capture_host.h" #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h" -#include "content/browser/renderer_host/pepper/pepper_file_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/browser/renderer_host/quota_dispatcher_host.h" #include "content/browser/renderer_host/render_message_filter.h" @@ -539,12 +538,6 @@ void RenderProcessHostImpl::CreateMessageFilters() { channel_->AddFilter(new MediaStreamDispatcherHost(GetID())); #endif #if defined(ENABLE_PLUGINS) - channel_->AddFilter( - GetContentClient()->browser()->AllowPepperPrivateFileAPI() ? - new PepperUnsafeFileMessageFilter( - GetID(), - storage_partition_impl_->GetPath()) : - new PepperFileMessageFilter(GetID())); channel_->AddFilter(new PepperMessageFilter(PepperMessageFilter::RENDERER, GetID(), browser_context)); #endif diff --git a/content/common/all_messages.h b/content/common/all_messages.h index b102ec9..106af5a 100644 --- a/content/common/all_messages.h +++ b/content/common/all_messages.h @@ -9,6 +9,5 @@ // included here. #include "content/common/content_message_generator.h" #if defined(ENABLE_PLUGINS) -#include "ppapi/proxy/pepper_file_messages.h" #include "ppapi/proxy/ppapi_messages.h" #endif diff --git a/content/common/pepper_plugin_registry.cc b/content/common/pepper_plugin_registry.cc index 6db31e7..457ee8f 100644 --- a/content/common/pepper_plugin_registry.cc +++ b/content/common/pepper_plugin_registry.cc @@ -70,6 +70,10 @@ void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) { plugin.mime_types.push_back(mime_type); } + // If the plugin name is empty, use the filename. + if (plugin.name.empty()) + plugin.name = UTF16ToUTF8(plugin.path.BaseName().LossyDisplayName()); + // Command-line plugins get full permissions. plugin.permissions = ppapi::PERMISSION_ALL_BITS; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 4bb7050..344fe37 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -677,10 +677,10 @@ 'browser/renderer_host/pepper/browser_ppapi_host_impl.h', 'browser/renderer_host/pepper/content_browser_pepper_host_factory.cc', 'browser/renderer_host/pepper/content_browser_pepper_host_factory.h', - 'browser/renderer_host/pepper/pepper_file_message_filter.cc', - 'browser/renderer_host/pepper/pepper_file_message_filter.h', 'browser/renderer_host/pepper/pepper_flash_browser_host.cc', 'browser/renderer_host/pepper/pepper_flash_browser_host.h', + 'browser/renderer_host/pepper/pepper_flash_file_host.cc', + 'browser/renderer_host/pepper/pepper_flash_file_host.h', 'browser/renderer_host/pepper/pepper_gamepad_host.cc', 'browser/renderer_host/pepper/pepper_gamepad_host.h', 'browser/renderer_host/pepper/pepper_lookup_request.h', diff --git a/content/public/browser/browser_ppapi_host.h b/content/public/browser/browser_ppapi_host.h index febd0ea..f5aa11c 100644 --- a/content/public/browser/browser_ppapi_host.h +++ b/content/public/browser/browser_ppapi_host.h @@ -72,6 +72,11 @@ class CONTENT_EXPORT BrowserPpapiHost { virtual bool GetRenderViewIDsForInstance(PP_Instance instance, int* render_process_id, int* render_view_id) const = 0; + // Returns the name of the plugin. + virtual const std::string& GetPluginName() = 0; + + // Returns the user's profile data directory. + virtual const FilePath& GetProfileDataDirectory() = 0; }; } // namespace content diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 05ddc93..c01dc06 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc @@ -250,10 +250,6 @@ bool ContentBrowserClient::AllowPepperSocketAPI( return false; } -bool ContentBrowserClient::AllowPepperPrivateFileAPI() { - return false; -} - FilePath ContentBrowserClient::GetHyphenDictionaryDirectory() { return FilePath(); } diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 7368ebb..373ec58 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -459,9 +459,6 @@ class CONTENT_EXPORT ContentBrowserClient { const GURL& url, const SocketPermissionRequest& params); - // Returns true if renderer processes can use private Pepper File APIs. - virtual bool AllowPepperPrivateFileAPI(); - // Returns the directory containing hyphenation dictionaries. virtual FilePath GetHyphenDictionaryDirectory(); diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index b890100..eba8ee3 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -63,7 +63,6 @@ #include "ppapi/c/private/ppb_flash.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/host_dispatcher.h" -#include "ppapi/proxy/pepper_file_messages.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/file_path.h" #include "ppapi/shared_impl/platform_file.h" @@ -1090,86 +1089,6 @@ bool PepperPluginDelegateImpl::AsyncOpenFileSystemURL( base::Bind(&DoNotifyCloseFile, path))); } -base::PlatformFileError PepperPluginDelegateImpl::OpenFile( - const ppapi::PepperFilePath& path, - int flags, - base::PlatformFile* file) { - IPC::PlatformFileForTransit transit_file; - base::PlatformFileError error; - IPC::Message* msg = new PepperFileMsg_OpenFile( - path, flags, &error, &transit_file); - if (!render_view_->Send(msg)) { - *file = base::kInvalidPlatformFileValue; - return base::PLATFORM_FILE_ERROR_FAILED; - } - *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); - return error; -} - -base::PlatformFileError PepperPluginDelegateImpl::RenameFile( - const ppapi::PepperFilePath& from_path, - const ppapi::PepperFilePath& to_path) { - base::PlatformFileError error; - IPC::Message* msg = new PepperFileMsg_RenameFile(from_path, to_path, &error); - if (!render_view_->Send(msg)) - return base::PLATFORM_FILE_ERROR_FAILED; - return error; -} - -base::PlatformFileError PepperPluginDelegateImpl::DeleteFileOrDir( - const ppapi::PepperFilePath& path, - bool recursive) { - base::PlatformFileError error; - IPC::Message* msg = new PepperFileMsg_DeleteFileOrDir( - path, recursive, &error); - if (!render_view_->Send(msg)) - return base::PLATFORM_FILE_ERROR_FAILED; - return error; -} - -base::PlatformFileError PepperPluginDelegateImpl::CreateDir( - const ppapi::PepperFilePath& path) { - base::PlatformFileError error; - IPC::Message* msg = new PepperFileMsg_CreateDir(path, &error); - if (!render_view_->Send(msg)) - return base::PLATFORM_FILE_ERROR_FAILED; - return error; -} - -base::PlatformFileError PepperPluginDelegateImpl::QueryFile( - const ppapi::PepperFilePath& path, - base::PlatformFileInfo* info) { - base::PlatformFileError error; - IPC::Message* msg = new PepperFileMsg_QueryFile(path, info, &error); - if (!render_view_->Send(msg)) - return base::PLATFORM_FILE_ERROR_FAILED; - return error; -} - -base::PlatformFileError PepperPluginDelegateImpl::GetDirContents( - const ppapi::PepperFilePath& path, - ppapi::DirContents* contents) { - base::PlatformFileError error; - IPC::Message* msg = new PepperFileMsg_GetDirContents(path, contents, &error); - if (!render_view_->Send(msg)) - return base::PLATFORM_FILE_ERROR_FAILED; - 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 d88a672..700bbef 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h @@ -240,26 +240,6 @@ class PepperPluginDelegateImpl const AvailableSpaceCallback& callback) OVERRIDE; virtual void WillUpdateFile(const GURL& file_path) OVERRIDE; virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE; - virtual base::PlatformFileError OpenFile( - const ppapi::PepperFilePath& path, - int flags, - base::PlatformFile* file) OVERRIDE; - virtual base::PlatformFileError RenameFile( - const ppapi::PepperFilePath& from_path, - const ppapi::PepperFilePath& to_path) OVERRIDE; - virtual base::PlatformFileError DeleteFileOrDir( - const ppapi::PepperFilePath& path, - bool recursive) OVERRIDE; - virtual base::PlatformFileError CreateDir( - const ppapi::PepperFilePath& path) OVERRIDE; - virtual base::PlatformFileError QueryFile( - const ppapi::PepperFilePath& path, - base::PlatformFileInfo* info) OVERRIDE; - 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 c5aeeaf..1473d45 100644 --- a/ppapi/c/private/ppb_flash_file.h +++ b/ppapi/c/private/ppb_flash_file.h @@ -31,18 +31,9 @@ struct PP_DirContents_Dev { // Module-local file paths are '/'-separated UTF-8 strings, relative to a // module-specific root. 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. - // - // Returns true if multithreaded access is supported. In this case you can - // use the rest of the functions from background threads. You may not call - // GetInterface or do any other PPAPI operations on background threads at - // this time. + // Deprecated. Returns true. bool (*CreateThreadAdapterForInstance)(PP_Instance instance); - - // Call when an instance is destroyed when you've previously called - // CreateThreadAdapterForInstance. + // Deprecated. Does nothing. void (*ClearThreadAdapterForInstance)(PP_Instance instance); // Opens a file, returning a file descriptor (posix) or a HANDLE (win32) into diff --git a/ppapi/ppapi_ipc.gypi b/ppapi/ppapi_ipc.gypi index 8c23bf2..8e374b2 100644 --- a/ppapi/ppapi_ipc.gypi +++ b/ppapi/ppapi_ipc.gypi @@ -12,8 +12,6 @@ # This part is shared between the targets defined below. ['ppapi_ipc_target==1', { 'sources': [ - 'proxy/pepper_file_messages.cc', - 'proxy/pepper_file_messages.h', 'proxy/ppapi_messages.cc', 'proxy/ppapi_messages.h', 'proxy/ppapi_param_traits.cc', diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index f835ff2..81ec94f 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -39,6 +39,8 @@ 'proxy/flash_clipboard_resource.h', 'proxy/flash_device_id_resource.cc', 'proxy/flash_device_id_resource.h', + 'proxy/flash_file_resource.cc', + 'proxy/flash_file_resource.h', 'proxy/flash_font_file_resource.cc', 'proxy/flash_font_file_resource.h', 'proxy/flash_fullscreen_resource.cc', @@ -187,6 +189,7 @@ 'proxy/device_enumeration_resource_helper.cc', 'proxy/flash_clipboard_resource.cc', 'proxy/flash_device_id_resource.cc', + 'proxy/flash_file_resource.cc', 'proxy/flash_font_file_resource.cc', 'proxy/flash_fullscreen_resource.cc', 'proxy/flash_menu_resource.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index da446ef..9033612 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -55,8 +55,6 @@ 'shared_impl/ppb_file_io_shared.h', 'shared_impl/ppb_file_ref_shared.cc', 'shared_impl/ppb_file_ref_shared.h', - 'shared_impl/ppb_flash_shared.cc', - 'shared_impl/ppb_flash_shared.h', 'shared_impl/ppb_gamepad_shared.cc', 'shared_impl/ppb_gamepad_shared.h', 'shared_impl/ppb_graphics_3d_shared.cc', diff --git a/ppapi/proxy/flash_file_resource.cc b/ppapi/proxy/flash_file_resource.cc new file mode 100644 index 0000000..ac9e555 --- /dev/null +++ b/ppapi/proxy/flash_file_resource.cc @@ -0,0 +1,231 @@ +// 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/flash_file_resource.h" + +#include "base/file_path.h" +#include "ipc/ipc_message.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_type_conversion.h" +#include "ppapi/shared_impl/scoped_pp_var.h" +#include "ppapi/shared_impl/time_conversion.h" +#include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/enter.h" + +namespace ppapi { +namespace proxy { + +namespace { + +// Returns the path that a PPB_FileRef resource references as long as it is an +// PP_FILESYSTEMTYPE_EXTERNAL path. Returns an empty string on error. +std::string GetPathFromFileRef(PP_Resource file_ref) { + thunk::EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref, true); + if (enter.failed()) + return std::string(); + if (enter.object()->GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL) + return std::string(); + ScopedPPVar var(ScopedPPVar::PassRef(), enter.object()->GetAbsolutePath()); + StringVar* string_var = StringVar::FromPPVar(var.get()); + if (!string_var) + return std::string(); + return string_var->value(); +} + +} // namespace + +FlashFileResource::FlashFileResource(Connection connection, + PP_Instance instance) + : PluginResource(connection, instance) { + SendCreate(BROWSER, PpapiHostMsg_FlashFile_Create()); +} + +FlashFileResource::~FlashFileResource() { +} + +thunk::PPB_Flash_File_API* FlashFileResource::AsPPB_Flash_File_API() { + return this; +} + +int32_t FlashFileResource::OpenFile(PP_Instance /*instance*/, + const char* path, + int32_t mode, + PP_FileHandle* file) { + return OpenFileHelper(path, PepperFilePath::DOMAIN_MODULE_LOCAL, mode, file); +} + +int32_t FlashFileResource::RenameFile(PP_Instance /*instance*/, + const char* path_from, + const char* path_to) { + PepperFilePath pepper_from(PepperFilePath::DOMAIN_MODULE_LOCAL, + FilePath::FromUTF8Unsafe(path_from)); + PepperFilePath pepper_to(PepperFilePath::DOMAIN_MODULE_LOCAL, + FilePath::FromUTF8Unsafe(path_to)); + + int32_t error = SyncCall<IPC::Message>( + BROWSER, PpapiHostMsg_FlashFile_RenameFile(pepper_from, pepper_to)); + + return error; +} + +int32_t FlashFileResource::DeleteFileOrDir(PP_Instance /*instance*/, + const char* path, + PP_Bool recursive) { + PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL, + FilePath::FromUTF8Unsafe(path)); + + int32_t error = SyncCall<IPC::Message>( + BROWSER, PpapiHostMsg_FlashFile_DeleteFileOrDir(pepper_path, + PP_ToBool(recursive))); + + return error; +} + +int32_t FlashFileResource::CreateDir(PP_Instance /*instance*/, + const char* path) { + PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL, + FilePath::FromUTF8Unsafe(path)); + + int32_t error = SyncCall<IPC::Message>(BROWSER, + PpapiHostMsg_FlashFile_CreateDir(pepper_path)); + + return error; +} + +int32_t FlashFileResource::QueryFile(PP_Instance /*instance*/, + const char* path, + PP_FileInfo* info) { + return QueryFileHelper(path, PepperFilePath::DOMAIN_MODULE_LOCAL, info); +} + +int32_t FlashFileResource::GetDirContents(PP_Instance /*instance*/, + const char* path, + PP_DirContents_Dev** contents) { + ppapi::DirContents entries; + PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL, + FilePath::FromUTF8Unsafe(path)); + + int32_t error = SyncCall<PpapiPluginMsg_FlashFile_GetDirContentsReply>( + BROWSER, PpapiHostMsg_FlashFile_GetDirContents(pepper_path), &entries); + + if (error == PP_OK) { + // Copy the serialized dir entries to the output struct. + *contents = new PP_DirContents_Dev; + (*contents)->count = static_cast<int32_t>(entries.size()); + (*contents)->entries = new PP_DirEntry_Dev[entries.size()]; + for (size_t i = 0; i < entries.size(); i++) { + const ppapi::DirEntry& source = entries[i]; + PP_DirEntry_Dev* dest = &(*contents)->entries[i]; + std::string name = source.name.AsUTF8Unsafe(); + char* name_copy = new char[name.size() + 1]; + memcpy(name_copy, name.c_str(), name.size() + 1); + dest->name = name_copy; + dest->is_dir = PP_FromBool(source.is_dir); + } + } + + return error; +} + +void FlashFileResource::FreeDirContents(PP_Instance /*instance*/, + PP_DirContents_Dev* contents) { + for (int32_t i = 0; i < contents->count; ++i) + delete[] contents->entries[i].name; + delete[] contents->entries; + delete contents; +} + +int32_t FlashFileResource::CreateTemporaryFile(PP_Instance /*instance*/, + PP_FileHandle* file) { + if (!file) + return PP_ERROR_BADARGUMENT; + + IPC::Message unused; + ResourceMessageReplyParams reply_params; + int32_t error = GenericSyncCall(BROWSER, + PpapiHostMsg_FlashFile_CreateTemporaryFile(), &unused, &reply_params); + if (error != PP_OK) + return error; + + IPC::PlatformFileForTransit transit_file; + if (!reply_params.TakeFileHandleAtIndex(0, &transit_file)) + return PP_ERROR_FAILED; + + *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); + return PP_OK; +} + +int32_t FlashFileResource::OpenFileRef(PP_Instance /*instance*/, + PP_Resource file_ref, + int32_t mode, + PP_FileHandle* file) { + return OpenFileHelper(GetPathFromFileRef(file_ref), + PepperFilePath::DOMAIN_ABSOLUTE, mode, file); +} + +int32_t FlashFileResource::QueryFileRef(PP_Instance /*instance*/, + PP_Resource file_ref, + PP_FileInfo* info) { + return QueryFileHelper(GetPathFromFileRef(file_ref), + PepperFilePath::DOMAIN_ABSOLUTE, info); +} + +int32_t FlashFileResource::OpenFileHelper(const std::string& path, + PepperFilePath::Domain domain_type, + int32_t mode, + PP_FileHandle* file) { + int flags = 0; + if (path.empty() || + !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || + !file) + return PP_ERROR_BADARGUMENT; + + PepperFilePath pepper_path(domain_type, FilePath::FromUTF8Unsafe(path)); + + IPC::Message unused; + ResourceMessageReplyParams reply_params; + int32_t error = GenericSyncCall(BROWSER, + PpapiHostMsg_FlashFile_OpenFile(pepper_path, flags), &unused, + &reply_params); + if (error != PP_OK) + return error; + + IPC::PlatformFileForTransit transit_file; + if (!reply_params.TakeFileHandleAtIndex(0, &transit_file)) + return PP_ERROR_FAILED; + + *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); + return PP_OK; +} + +int32_t FlashFileResource::QueryFileHelper(const std::string& path, + PepperFilePath::Domain domain_type, + PP_FileInfo* info) { + if (path.empty() || !info) + return PP_ERROR_BADARGUMENT; + + base::PlatformFileInfo file_info; + PepperFilePath pepper_path(domain_type, FilePath::FromUTF8Unsafe(path)); + + int32_t error = SyncCall<PpapiPluginMsg_FlashFile_QueryFileReply>(BROWSER, + PpapiHostMsg_FlashFile_QueryFile(pepper_path), &file_info); + + if (error == PP_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 = PP_FILESYSTEMTYPE_EXTERNAL; + if (file_info.is_directory) + info->type = PP_FILETYPE_DIRECTORY; + else + info->type = PP_FILETYPE_REGULAR; + } + + return error; +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/flash_file_resource.h b/ppapi/proxy/flash_file_resource.h new file mode 100644 index 0000000..f8c4b18 --- /dev/null +++ b/ppapi/proxy/flash_file_resource.h @@ -0,0 +1,73 @@ +// 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_FLASH_FILE_RESOURCE_H_ +#define PPAPI_PROXY_FLASH_FILE_RESOURCE_H_ + +#include <string> + +#include "ppapi/proxy/connection.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/shared_impl/file_path.h" +#include "ppapi/thunk/ppb_flash_file_api.h" + +namespace ppapi { +namespace proxy { + +class FlashFileResource + : public PluginResource, + public thunk::PPB_Flash_File_API { + public: + FlashFileResource(Connection connection, PP_Instance instance); + virtual ~FlashFileResource(); + + // Resource overrides. + virtual thunk::PPB_Flash_File_API* AsPPB_Flash_File_API() OVERRIDE; + + // PPB_Flash_Functions_API. + virtual int32_t OpenFile(PP_Instance instance, + const char* path, + int32_t mode, + PP_FileHandle* file) OVERRIDE; + virtual int32_t RenameFile(PP_Instance instance, + const char* path_from, + const char* path_to) OVERRIDE; + virtual int32_t DeleteFileOrDir(PP_Instance instance, + const char* path, + PP_Bool recursive) OVERRIDE; + virtual int32_t CreateDir(PP_Instance instance, const char* path) OVERRIDE; + virtual int32_t QueryFile(PP_Instance instance, + const char* path, + PP_FileInfo* info) OVERRIDE; + virtual int32_t GetDirContents(PP_Instance instance, + const char* path, + PP_DirContents_Dev** contents) OVERRIDE; + virtual void FreeDirContents(PP_Instance instance, + 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, + PP_FileHandle* file) OVERRIDE; + virtual int32_t QueryFileRef(PP_Instance instance, + PP_Resource file_ref, + PP_FileInfo* info) OVERRIDE; + + private: + int32_t OpenFileHelper(const std::string& path, + PepperFilePath::Domain domain_type, + int32_t mode, + PP_FileHandle* file); + int32_t QueryFileHelper(const std::string& path, + PepperFilePath::Domain domain_type, + PP_FileInfo* info); + + DISALLOW_COPY_AND_ASSIGN(FlashFileResource); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_FLASH_FILE_RESOURCE_H_ diff --git a/ppapi/proxy/pepper_file_messages.cc b/ppapi/proxy/pepper_file_messages.cc deleted file mode 100644 index 53b4fcb..0000000 --- a/ppapi/proxy/pepper_file_messages.cc +++ /dev/null @@ -1,68 +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. - - -// Get basic type definitions. -#define IPC_MESSAGE_IMPL -#include "ppapi/proxy/pepper_file_messages.h" - -// Generate constructors. -#include "ipc/struct_constructor_macros.h" -#include "ppapi/proxy/pepper_file_messages.h" - -// Generate destructors. -#include "ipc/struct_destructor_macros.h" -#include "ppapi/proxy/pepper_file_messages.h" - -// Generate param traits write methods. -#include "ipc/param_traits_write_macros.h" -namespace IPC { -#include "ppapi/proxy/pepper_file_messages.h" -} // namespace IPC - -// Generate param traits read methods. -#include "ipc/param_traits_read_macros.h" -namespace IPC { -#include "ppapi/proxy/pepper_file_messages.h" -} // namespace IPC - -// Generate param traits log methods. -#include "ipc/param_traits_log_macros.h" -namespace IPC { -#include "ppapi/proxy/pepper_file_messages.h" -} // namespace IPC - -namespace IPC { - -void ParamTraits<ppapi::PepperFilePath>::Write(Message* m, - const param_type& p) { - WriteParam(m, static_cast<unsigned>(p.domain())); - WriteParam(m, p.path()); -} - -bool ParamTraits<ppapi::PepperFilePath>::Read(const Message* m, - PickleIterator* iter, - param_type* p) { - unsigned domain; - FilePath path; - if (!ReadParam(m, iter, &domain) || !ReadParam(m, iter, &path)) - return false; - if (domain > ppapi::PepperFilePath::DOMAIN_MAX_VALID) - return false; - - *p = ppapi::PepperFilePath( - static_cast<ppapi::PepperFilePath::Domain>(domain), path); - return true; -} - -void ParamTraits<ppapi::PepperFilePath>::Log(const param_type& p, - std::string* l) { - l->append("("); - LogParam(static_cast<unsigned>(p.domain()), l); - l->append(", "); - LogParam(p.path(), l); - l->append(")"); -} - -} // namespace IPC diff --git a/ppapi/proxy/pepper_file_messages.h b/ppapi/proxy/pepper_file_messages.h deleted file mode 100644 index 3edd490..0000000 --- a/ppapi/proxy/pepper_file_messages.h +++ /dev/null @@ -1,82 +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. - -// Multiply-included message file, no traditional include guard. -#include "ipc/ipc_message_macros.h" -#include "ipc/ipc_param_traits.h" -#include "ipc/ipc_platform_file.h" -#include "ppapi/proxy/ppapi_proxy_export.h" -#include "ppapi/shared_impl/dir_contents.h" -#include "ppapi/shared_impl/file_path.h" - -// Singly-included section since need custom serialization. -#ifndef PPAPI_SHARED_IMPL_PEPPER_FILE_MESSAGES_H_ -#define PPAPI_SHARED_IMPL_PEPPER_FILE_MESSAGES_H_ - -namespace IPC { - -template <> -struct ParamTraits<ppapi::PepperFilePath> { - typedef ppapi::PepperFilePath param_type; - static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* p); - static void Log(const param_type& p, std::string* l); -}; - -} // namespace IPC - -#endif // PPAPI_SHARED_IMPL_PEPPER_FILE_MESSAGES_H_ - -#undef IPC_MESSAGE_EXPORT -#define IPC_MESSAGE_EXPORT PPAPI_PROXY_EXPORT - -#define IPC_MESSAGE_START PepperFileMsgStart - -IPC_STRUCT_TRAITS_BEGIN(ppapi::DirEntry) - IPC_STRUCT_TRAITS_MEMBER(name) - IPC_STRUCT_TRAITS_MEMBER(is_dir) -IPC_STRUCT_TRAITS_END() - -// Trusted Pepper Filesystem messages from the renderer to the browser. - -// Open the file. -IPC_SYNC_MESSAGE_CONTROL2_2(PepperFileMsg_OpenFile, - ppapi::PepperFilePath /* path */, - int /* flags */, - base::PlatformFileError /* error_code */, - IPC::PlatformFileForTransit /* result */) - -// Rename the file. -IPC_SYNC_MESSAGE_CONTROL2_1(PepperFileMsg_RenameFile, - ppapi::PepperFilePath /* from_path */, - ppapi::PepperFilePath /* to_path */, - base::PlatformFileError /* error_code */) - -// Delete the file. -IPC_SYNC_MESSAGE_CONTROL2_1(PepperFileMsg_DeleteFileOrDir, - ppapi::PepperFilePath /* path */, - bool /* recursive */, - base::PlatformFileError /* error_code */) - -// Create the directory. -IPC_SYNC_MESSAGE_CONTROL1_1(PepperFileMsg_CreateDir, - ppapi::PepperFilePath /* path */, - base::PlatformFileError /* error_code */) - -// Query the file's info. -IPC_SYNC_MESSAGE_CONTROL1_2(PepperFileMsg_QueryFile, - ppapi::PepperFilePath /* path */, - base::PlatformFileInfo, /* info */ - base::PlatformFileError /* error_code */) - -// Get the directory's contents. -IPC_SYNC_MESSAGE_CONTROL1_2(PepperFileMsg_GetDirContents, - ppapi::PepperFilePath /* path */, - 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/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index 939327b..b864d99 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -16,6 +16,7 @@ #include "ppapi/c/ppp_instance.h" #include "ppapi/proxy/flash_resource.h" #include "ppapi/proxy/flash_clipboard_resource.h" +#include "ppapi/proxy/flash_file_resource.h" #include "ppapi/proxy/gamepad_resource.h" #include "ppapi/proxy/interface_list.h" #include "ppapi/proxy/interface_proxy.h" diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h index 98f43a6..8d12e39d 100644 --- a/ppapi/proxy/plugin_dispatcher.h +++ b/ppapi/proxy/plugin_dispatcher.h @@ -35,9 +35,6 @@ class ResourceCreationAPI; namespace proxy { -class FlashClipboardResource; -class FlashResource; -class GamepadResource; class ResourceMessageReplyParams; // Used to keep track of per-instance data. diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc index fca0630..3dd47ba 100644 --- a/ppapi/proxy/plugin_resource.cc +++ b/ppapi/proxy/plugin_resource.cc @@ -108,16 +108,17 @@ bool PluginResource::SendResourceCall( new PpapiHostMsg_ResourceCall(call_params, nested_msg)); } -int32_t PluginResource::GenericSyncCall(Destination dest, - const IPC::Message& msg, - IPC::Message* reply) { +int32_t PluginResource::GenericSyncCall( + Destination dest, + const IPC::Message& msg, + IPC::Message* reply, + ResourceMessageReplyParams* reply_params) { ResourceMessageCallParams params(pp_resource(), GetNextSequence()); params.set_has_callback(); - ResourceMessageReplyParams reply_params; bool success = GetSender(dest)->Send(new PpapiHostMsg_ResourceSyncCall( - params, msg, &reply_params, reply)); + params, msg, reply_params, reply)); if (success) - return reply_params.result(); + return reply_params->result(); return PP_ERROR_FAILED; } diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 2363c8c..2e2e10f 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -126,6 +126,11 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource { int32_t SyncCall( Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e); + int32_t GenericSyncCall(Destination dest, + const IPC::Message& msg, + IPC::Message* reply_msg, + ResourceMessageReplyParams* reply_params); + private: IPC::Sender* GetSender(Destination dest) { return dest == RENDERER ? connection_.renderer_sender : @@ -138,10 +143,6 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource { const ResourceMessageCallParams& call_params, const IPC::Message& nested_msg); - int32_t GenericSyncCall(Destination dest, - const IPC::Message& msg, - IPC::Message* reply_msg); - int32_t GetNextSequence(); Connection connection_; @@ -177,14 +178,16 @@ int32_t PluginResource::Call(Destination dest, template <class ReplyMsgClass> int32_t PluginResource::SyncCall(Destination dest, const IPC::Message& msg) { IPC::Message reply; - return GenericSyncCall(dest, msg, &reply); + ResourceMessageReplyParams reply_params; + return GenericSyncCall(dest, msg, &reply, &reply_params); } template <class ReplyMsgClass, class A> int32_t PluginResource::SyncCall( Destination dest, const IPC::Message& msg, A* a) { IPC::Message reply; - int32_t result = GenericSyncCall(dest, msg, &reply); + ResourceMessageReplyParams reply_params; + int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params); if (UnpackMessage<ReplyMsgClass>(reply, a)) return result; @@ -195,7 +198,8 @@ template <class ReplyMsgClass, class A, class B> int32_t PluginResource::SyncCall( Destination dest, const IPC::Message& msg, A* a, B* b) { IPC::Message reply; - int32_t result = GenericSyncCall(dest, msg, &reply); + ResourceMessageReplyParams reply_params; + int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params); if (UnpackMessage<ReplyMsgClass>(reply, a, b)) return result; @@ -206,7 +210,8 @@ template <class ReplyMsgClass, class A, class B, class C> int32_t PluginResource::SyncCall( Destination dest, const IPC::Message& msg, A* a, B* b, C* c) { IPC::Message reply; - int32_t result = GenericSyncCall(dest, msg, &reply); + ResourceMessageReplyParams reply_params; + int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params); if (UnpackMessage<ReplyMsgClass>(reply, a, b, c)) return result; @@ -217,7 +222,8 @@ template <class ReplyMsgClass, class A, class B, class C, class D> int32_t PluginResource::SyncCall( Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d) { IPC::Message reply; - int32_t result = GenericSyncCall(dest, msg, &reply); + ResourceMessageReplyParams reply_params; + int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params); if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d)) return result; @@ -228,7 +234,8 @@ template <class ReplyMsgClass, class A, class B, class C, class D, class E> int32_t PluginResource::SyncCall( Destination dest, const IPC::Message& msg, A* a, B* b, C* c, D* d, E* e) { IPC::Message reply; - int32_t result = GenericSyncCall(dest, msg, &reply); + ResourceMessageReplyParams reply_params; + int32_t result = GenericSyncCall(dest, msg, &reply, &reply_params); if (UnpackMessage<ReplyMsgClass>(reply, a, b, c, d, e)) return result; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 959b93c..b5e04de 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -47,6 +47,8 @@ #include "ppapi/proxy/serialized_flash_menu.h" #include "ppapi/proxy/serialized_structs.h" #include "ppapi/proxy/serialized_var.h" +#include "ppapi/shared_impl/dir_contents.h" +#include "ppapi/shared_impl/file_path.h" #include "ppapi/shared_impl/ppapi_preferences.h" #include "ppapi/shared_impl/ppb_device_ref_shared.h" #include "ppapi/shared_impl/ppb_input_event_shared.h" @@ -162,6 +164,11 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::DeviceRefData) IPC_STRUCT_TRAITS_MEMBER(id) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ppapi::DirEntry) + IPC_STRUCT_TRAITS_MEMBER(name) + IPC_STRUCT_TRAITS_MEMBER(is_dir) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(ppapi::FlashSiteSetting) IPC_STRUCT_TRAITS_MEMBER(site) IPC_STRUCT_TRAITS_MEMBER(permission) @@ -1274,17 +1281,6 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFlash_IsRectTopmost, PP_Instance /* instance */, PP_Rect /* rect */, PP_Bool /* result */) -IPC_SYNC_MESSAGE_ROUTED3_2(PpapiHostMsg_PPBFlash_OpenFileRef, - PP_Instance /* instance */, - ppapi::HostResource /* file_ref */, - int32_t /* mode */, - IPC::PlatformFileForTransit /* file_handle */, - int32_t /* result */) -IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBFlash_QueryFileRef, - PP_Instance /* instance */, - ppapi::HostResource /* file_ref */, - PP_FileInfo /* info */, - int32_t /* result */) IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFlash_GetSetting, PP_Instance /* instance */, PP_FlashSetting /* setting */, @@ -1639,6 +1635,29 @@ IPC_MESSAGE_CONTROL3(PpapiHostMsg_FlashClipboard_WriteData, std::vector<uint32_t> /* formats */, std::vector<std::string> /* data */) +// Flash file. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FlashFile_Create) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FlashFile_OpenFile, + ppapi::PepperFilePath /* path */, + int /* flags */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FlashFile_RenameFile, + ppapi::PepperFilePath /* from_path */, + ppapi::PepperFilePath /* to_path */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FlashFile_DeleteFileOrDir, + ppapi::PepperFilePath /* path */, + bool /* recursive */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FlashFile_CreateDir, + ppapi::PepperFilePath /* path */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FlashFile_QueryFile, + ppapi::PepperFilePath /* path */) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FlashFile_QueryFileReply, + base::PlatformFileInfo /* file_info */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FlashFile_GetDirContents, + ppapi::PepperFilePath /* path */) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FlashFile_GetDirContentsReply, + ppapi::DirContents /* entries */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FlashFile_CreateTemporaryFile) + // Flash font file. IPC_MESSAGE_CONTROL2(PpapiHostMsg_FlashFontFile_Create, ppapi::proxy::SerializedFontDescription /* description */, diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc index 763d05c..ea792e6 100644 --- a/ppapi/proxy/ppapi_param_traits.cc +++ b/ppapi/proxy/ppapi_param_traits.cc @@ -346,6 +346,7 @@ void ParamTraits<ppapi::proxy::SerializedHandle>::Write(Message* m, break; case ppapi::proxy::SerializedHandle::SOCKET: case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: + case ppapi::proxy::SerializedHandle::FILE: ParamTraits<IPC::PlatformFileForTransit>::Write(m, p.descriptor()); break; case ppapi::proxy::SerializedHandle::INVALID: @@ -386,6 +387,14 @@ bool ParamTraits<ppapi::proxy::SerializedHandle>::Read(const Message* m, } break; } + case ppapi::proxy::SerializedHandle::FILE: { + IPC::PlatformFileForTransit desc; + if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) { + r->set_file_handle(desc); + return true; + } + break; + } case ppapi::proxy::SerializedHandle::INVALID: return true; // No default so the compiler will warn us if a new type is added. @@ -552,6 +561,41 @@ void ParamTraits<ppapi::proxy::SerializedFontDescription>::Log( std::string* l) { } +// ppapi::PepperFilePath ------------------------------------------------------- + +// static +void ParamTraits<ppapi::PepperFilePath>::Write(Message* m, + const param_type& p) { + WriteParam(m, static_cast<unsigned>(p.domain())); + WriteParam(m, p.path()); +} + +// static +bool ParamTraits<ppapi::PepperFilePath>::Read(const Message* m, + PickleIterator* iter, + param_type* p) { + unsigned domain; + FilePath path; + if (!ReadParam(m, iter, &domain) || !ReadParam(m, iter, &path)) + return false; + if (domain > ppapi::PepperFilePath::DOMAIN_MAX_VALID) + return false; + + *p = ppapi::PepperFilePath( + static_cast<ppapi::PepperFilePath::Domain>(domain), path); + return true; +} + +// static +void ParamTraits<ppapi::PepperFilePath>::Log(const param_type& p, + std::string* l) { + l->append("("); + LogParam(static_cast<unsigned>(p.domain()), l); + l->append(", "); + LogParam(p.path(), l); + l->append(")"); +} + // SerializedFlashMenu --------------------------------------------------------- // static diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h index 13f7351..7556e35 100644 --- a/ppapi/proxy/ppapi_param_traits.h +++ b/ppapi/proxy/ppapi_param_traits.h @@ -14,6 +14,7 @@ #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_var.h" #include "ppapi/proxy/ppapi_proxy_export.h" +#include "ppapi/shared_impl/file_path.h" #include "ppapi/shared_impl/ppapi_permissions.h" #include "ppapi/shared_impl/ppb_file_ref_shared.h" @@ -166,6 +167,14 @@ struct PPAPI_PROXY_EXPORT ParamTraits<ppapi::PpapiPermissions> { }; #if !defined(OS_NACL) && !defined(NACL_WIN64) +template <> +struct ParamTraits<ppapi::PepperFilePath> { + typedef ppapi::PepperFilePath param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, PickleIterator* iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; + template<> struct PPAPI_PROXY_EXPORT ParamTraits<ppapi::proxy::SerializedFlashMenu> { typedef ppapi::proxy::SerializedFlashMenu param_type; diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc index 0507910..9e06ede 100644 --- a/ppapi/proxy/ppb_flash_proxy.cc +++ b/ppapi/proxy/ppb_flash_proxy.cc @@ -21,14 +21,11 @@ #include "ppapi/c/private/ppb_flash_print.h" #include "ppapi/c/trusted/ppb_browser_font_trusted.h" #include "ppapi/proxy/host_dispatcher.h" -#include "ppapi/proxy/pepper_file_messages.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_globals.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/proxy_module.h" #include "ppapi/proxy/serialized_var.h" -#include "ppapi/shared_impl/dir_contents.h" -#include "ppapi/shared_impl/file_type_conversion.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/resource.h" @@ -67,19 +64,6 @@ class LocalTimeZoneOffsetCache base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER; -IPC::PlatformFileForTransit PlatformFileToPlatformFileForTransit( - Dispatcher* dispatcher, - int32_t* error, - base::PlatformFile file) { - if (*error != PP_OK) - return IPC::InvalidPlatformFileForTransit(); - IPC::PlatformFileForTransit out_handle = - dispatcher->ShareHandleWithRemote(file, true); - if (out_handle == IPC::InvalidPlatformFileForTransit()) - *error = PP_ERROR_NOACCESS; - return out_handle; -} - void InvokePrinting(PP_Instance instance) { ProxyAutoLock lock; @@ -125,10 +109,6 @@ bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) { OnHostMsgGetLocalTimeZoneOffset) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_IsRectTopmost, OnHostMsgIsRectTopmost) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_OpenFileRef, - OnHostMsgOpenFileRef) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_QueryFileRef, - OnHostMsgQueryFileRef) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_InvokePrinting, OnHostMsgInvokePrinting) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetSetting, @@ -300,187 +280,6 @@ PP_Var PPB_Flash_Proxy::GetSetting(PP_Instance instance, return PP_MakeUndefined(); } -bool PPB_Flash_Proxy::CreateThreadAdapterForInstance(PP_Instance instance) { - return true; -} - -void PPB_Flash_Proxy::ClearThreadAdapterForInstance(PP_Instance instance) { -} - -int32_t PPB_Flash_Proxy::OpenFile(PP_Instance, - const char* path, - int32_t mode, - PP_FileHandle* file) { - int flags = 0; - if (!path || - !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || - !file) - return PP_ERROR_BADARGUMENT; - - base::PlatformFileError error; - IPC::PlatformFileForTransit transit_file; - ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(path)); - - if (PluginGlobals::Get()->GetBrowserSender()->Send( - new PepperFileMsg_OpenFile(pepper_path, flags, - &error, &transit_file))) { - *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); - } else { - *file = base::kInvalidPlatformFileValue; - error = base::PLATFORM_FILE_ERROR_FAILED; - } - - return ppapi::PlatformFileErrorToPepperError(error); -} - -int32_t PPB_Flash_Proxy::RenameFile(PP_Instance, - const char* from_path, - const char* to_path) { - base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; - ppapi::PepperFilePath pepper_from(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(from_path)); - ppapi::PepperFilePath pepper_to(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(to_path)); - - PluginGlobals::Get()->GetBrowserSender()->Send( - new PepperFileMsg_RenameFile(pepper_from, pepper_to, &error)); - - return ppapi::PlatformFileErrorToPepperError(error); -} - -int32_t PPB_Flash_Proxy::DeleteFileOrDir(PP_Instance, - const char* path, - PP_Bool recursive) { - base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; - ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(path)); - - PluginGlobals::Get()->GetBrowserSender()->Send( - new PepperFileMsg_DeleteFileOrDir(pepper_path, - PP_ToBool(recursive), - &error)); - - return ppapi::PlatformFileErrorToPepperError(error); -} - -int32_t PPB_Flash_Proxy::CreateDir(PP_Instance, const char* path) { - base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; - ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(path)); - - PluginGlobals::Get()->GetBrowserSender()->Send( - new PepperFileMsg_CreateDir(pepper_path, &error)); - - return ppapi::PlatformFileErrorToPepperError(error); -} - -int32_t PPB_Flash_Proxy::QueryFile(PP_Instance, - const char* path, - PP_FileInfo* info) { - base::PlatformFileInfo file_info; - base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; - ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(path)); - - PluginGlobals::Get()->GetBrowserSender()->Send( - new PepperFileMsg_QueryFile(pepper_path, &file_info, &error)); - - if (error == 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 = PP_FILESYSTEMTYPE_EXTERNAL; - if (file_info.is_directory) - info->type = PP_FILETYPE_DIRECTORY; - else - info->type = PP_FILETYPE_REGULAR; - } - - return ppapi::PlatformFileErrorToPepperError(error); -} - -int32_t PPB_Flash_Proxy::GetDirContents(PP_Instance, - const char* path, - PP_DirContents_Dev** contents) { - ppapi::DirContents entries; - base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; - ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, - FilePath::FromUTF8Unsafe(path)); - - PluginGlobals::Get()->GetBrowserSender()->Send( - new PepperFileMsg_GetDirContents(pepper_path, &entries, &error)); - - if (error == base::PLATFORM_FILE_OK) { - // Copy the serialized dir entries to the output struct. - *contents = new PP_DirContents_Dev; - (*contents)->count = static_cast<int32_t>(entries.size()); - (*contents)->entries = new PP_DirEntry_Dev[entries.size()]; - for (size_t i = 0; i < entries.size(); i++) { - const ppapi::DirEntry& source = entries[i]; - PP_DirEntry_Dev* dest = &(*contents)->entries[i]; - std::string name = source.name.AsUTF8Unsafe(); - char* name_copy = new char[name.size() + 1]; - memcpy(name_copy, name.c_str(), name.size() + 1); - dest->name = name_copy; - dest->is_dir = PP_FromBool(source.is_dir); - } - } - - 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()->GetBrowserSender()->Send( - 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, - PP_FileHandle* file) { - EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref_id, true); - if (enter.failed()) - return PP_ERROR_BADRESOURCE; - - int32_t result = PP_ERROR_FAILED; - IPC::PlatformFileForTransit transit; - dispatcher()->Send(new PpapiHostMsg_PPBFlash_OpenFileRef( - API_ID_PPB_FLASH, instance, enter.resource()->host_resource(), mode, - &transit, &result)); - *file = IPC::PlatformFileForTransitToPlatformFile(transit); - return result; -} - -int32_t PPB_Flash_Proxy::QueryFileRef(PP_Instance instance, - PP_Resource file_ref_id, - PP_FileInfo* info) { - EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref_id, true); - if (enter.failed()) - return PP_ERROR_BADRESOURCE; - - int32_t result = PP_ERROR_FAILED; - dispatcher()->Send(new PpapiHostMsg_PPBFlash_QueryFileRef( - API_ID_PPB_FLASH, instance, enter.resource()->host_resource(), info, - &result)); - return result; -} - void PPB_Flash_Proxy::OnHostMsgSetInstanceAlwaysOnTop(PP_Instance instance, PP_Bool on_top) { EnterInstanceNoLock enter(instance); @@ -571,39 +370,6 @@ void PPB_Flash_Proxy::OnHostMsgIsRectTopmost(PP_Instance instance, *result = PP_FALSE; } -void PPB_Flash_Proxy::OnHostMsgOpenFileRef( - PP_Instance instance, - const HostResource& host_resource, - int32_t mode, - IPC::PlatformFileForTransit* file_handle, - int32_t* result) { - EnterInstanceNoLock enter(instance); - if (enter.failed()) { - *result = PP_ERROR_BADARGUMENT; - return; - } - - base::PlatformFile file; - *result = enter.functions()->GetFlashAPI()->OpenFileRef( - instance, host_resource.host_resource(), mode, &file); - *file_handle = PlatformFileToPlatformFileForTransit(dispatcher(), - result, file); -} - -void PPB_Flash_Proxy::OnHostMsgQueryFileRef( - PP_Instance instance, - const HostResource& host_resource, - PP_FileInfo* info, - int32_t* result) { - EnterInstanceNoLock enter(instance); - if (enter.failed()) { - *result = PP_ERROR_BADARGUMENT; - return; - } - *result = enter.functions()->GetFlashAPI()->QueryFileRef( - instance, host_resource.host_resource(), info); -} - void PPB_Flash_Proxy::OnHostMsgGetSetting(PP_Instance instance, PP_FlashSetting setting, SerializedVarReturnValue id) { diff --git a/ppapi/proxy/ppb_flash_proxy.h b/ppapi/proxy/ppb_flash_proxy.h index d9bea31..63cc506 100644 --- a/ppapi/proxy/ppb_flash_proxy.h +++ b/ppapi/proxy/ppb_flash_proxy.h @@ -6,10 +6,8 @@ #define PPAPI_PROXY_PPB_FLASH_PROXY_H_ #include <string> -#include <vector> #include "base/compiler_specific.h" -#include "ipc/ipc_platform_file.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_module.h" @@ -18,7 +16,7 @@ #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/shared_impl/host_resource.h" -#include "ppapi/shared_impl/ppb_flash_shared.h" +#include "ppapi/thunk/ppb_flash_api.h" struct PPB_Flash_Print_1_0; @@ -37,7 +35,7 @@ class SerializedVarReturnValue; // implemented in the new-style resource proxy (see flash_resource.h). // TODO(raymes): All of these functions should be moved to the new-style proxy. //////////////////////////////////////////////////////////////////////////////// -class PPB_Flash_Proxy : public InterfaceProxy, public PPB_Flash_Shared { +class PPB_Flash_Proxy : public InterfaceProxy, public thunk::PPB_Flash_API { public: explicit PPB_Flash_Proxy(Dispatcher* dispatcher); virtual ~PPB_Flash_Proxy(); @@ -79,34 +77,6 @@ class PPB_Flash_Proxy : public InterfaceProxy, public PPB_Flash_Shared { const PP_Rect* rect) OVERRIDE; virtual PP_Var GetSetting(PP_Instance instance, PP_FlashSetting setting) OVERRIDE; - virtual bool CreateThreadAdapterForInstance(PP_Instance instance) OVERRIDE; - virtual void ClearThreadAdapterForInstance(PP_Instance instance) OVERRIDE; - virtual int32_t OpenFile(PP_Instance instance, - const char* path, - int32_t mode, - PP_FileHandle* file) OVERRIDE; - virtual int32_t RenameFile(PP_Instance instance, - const char* path_from, - const char* path_to) OVERRIDE; - virtual int32_t DeleteFileOrDir(PP_Instance instance, - const char* path, - PP_Bool recursive) OVERRIDE; - virtual int32_t CreateDir(PP_Instance instance, const char* path) OVERRIDE; - virtual int32_t QueryFile(PP_Instance instance, - const char* path, - PP_FileInfo* info) OVERRIDE; - 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, - PP_FileHandle* file) OVERRIDE; - virtual int32_t QueryFileRef(PP_Instance instance, - PP_Resource file_ref, - PP_FileInfo* info) OVERRIDE; static const ApiID kApiID = API_ID_PPB_FLASH; @@ -127,15 +97,6 @@ class PPB_Flash_Proxy : public InterfaceProxy, public PPB_Flash_Shared { void OnHostMsgIsRectTopmost(PP_Instance instance, PP_Rect rect, PP_Bool* result); - void OnHostMsgOpenFileRef(PP_Instance instance, - const ppapi::HostResource& host_resource, - int32_t mode, - IPC::PlatformFileForTransit* file_handle, - int32_t* result); - void OnHostMsgQueryFileRef(PP_Instance instance, - const ppapi::HostResource& host_resource, - PP_FileInfo* info, - int32_t* result); void OnHostMsgGetSetting(PP_Instance instance, PP_FlashSetting setting, SerializedVarReturnValue result); diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 4e32822..d81fb8e 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -17,6 +17,7 @@ #include "ppapi/proxy/content_decryptor_private_serializer.h" #include "ppapi/proxy/enter_proxy.h" #include "ppapi/proxy/flash_clipboard_resource.h" +#include "ppapi/proxy/flash_file_resource.h" #include "ppapi/proxy/flash_fullscreen_resource.h" #include "ppapi/proxy/flash_resource.h" #include "ppapi/proxy/gamepad_resource.h" @@ -382,6 +383,9 @@ Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance, case FLASH_CLIPBOARD_SINGLETON_ID: new_singleton = new FlashClipboardResource(connection, instance); break; + case FLASH_FILE_SINGLETON_ID: + new_singleton = new FlashFileResource(connection, instance); + break; case FLASH_FULLSCREEN_SINGLETON_ID: new_singleton = new FlashFullscreenResource(connection, instance); break; @@ -390,6 +394,7 @@ Resource* PPB_Instance_Proxy::GetSingletonResource(PP_Instance instance, break; #else case FLASH_CLIPBOARD_SINGLETON_ID: + case FLASH_FILE_SINGLETON_ID: case FLASH_FULLSCREEN_SINGLETON_ID: case FLASH_SINGLETON_ID: NOTREACHED(); diff --git a/ppapi/proxy/resource_message_params.cc b/ppapi/proxy/resource_message_params.cc index aaca8c9..49b6328 100644 --- a/ppapi/proxy/resource_message_params.cc +++ b/ppapi/proxy/resource_message_params.cc @@ -91,6 +91,17 @@ bool ResourceMessageParams::TakeSocketHandleAtIndex( return true; } +bool ResourceMessageParams::TakeFileHandleAtIndex( + size_t index, + IPC::PlatformFileForTransit* handle) const { + SerializedHandle serialized = TakeHandleOfTypeAtIndex( + index, SerializedHandle::FILE); + if (!serialized.is_file()) + return false; + *handle = serialized.descriptor(); + return true; +} + void ResourceMessageParams::TakeAllSharedMemoryHandles( std::vector<base::SharedMemoryHandle>* handles) const { for (size_t i = 0; i < handles_->data().size(); ++i) { diff --git a/ppapi/proxy/resource_message_params.h b/ppapi/proxy/resource_message_params.h index a414b87..6d0abea 100644 --- a/ppapi/proxy/resource_message_params.h +++ b/ppapi/proxy/resource_message_params.h @@ -38,8 +38,8 @@ class PPAPI_PROXY_EXPORT ResourceMessageParams { SerializedHandle TakeHandleOfTypeAtIndex(size_t index, SerializedHandle::Type type) const; - // Helper functions to return shared memory or socket handles passed in the - // params struct. + // Helper functions to return shared memory, socket or file handles passed in + // the params struct. // If the index has a valid handle of the given type, it will be placed in the // output parameter, the corresponding slot in the list will be set to an // invalid handle, and the function will return true. If the handle doesn't @@ -54,6 +54,8 @@ class PPAPI_PROXY_EXPORT ResourceMessageParams { base::SharedMemoryHandle* handle) const; bool TakeSocketHandleAtIndex(size_t index, IPC::PlatformFileForTransit* handle) const; + bool TakeFileHandleAtIndex(size_t index, + IPC::PlatformFileForTransit* handle) const; void TakeAllSharedMemoryHandles( std::vector<base::SharedMemoryHandle>* handles) const; diff --git a/ppapi/proxy/serialized_structs.cc b/ppapi/proxy/serialized_structs.cc index 2904f9b..fcd41a7 100644 --- a/ppapi/proxy/serialized_structs.cc +++ b/ppapi/proxy/serialized_structs.cc @@ -134,10 +134,17 @@ SerializedHandle::SerializedHandle( } bool SerializedHandle::IsHandleValid() const { - if (type_ == SHARED_MEMORY) - return base::SharedMemory::IsHandleValid(shm_handle_); - else if (type_ == SOCKET || type_ == CHANNEL_HANDLE) - return !(IPC::InvalidPlatformFileForTransit() == descriptor_); + switch (type_) { + case SHARED_MEMORY: + return base::SharedMemory::IsHandleValid(shm_handle_); + case SOCKET: + case CHANNEL_HANDLE: + case FILE: + return !(IPC::InvalidPlatformFileForTransit() == descriptor_); + case INVALID: + return false; + // No default so the compiler will warn us if a new type is added. + } return false; } @@ -152,6 +159,7 @@ void SerializedHandle::Close() { break; case SOCKET: case CHANNEL_HANDLE: + case FILE: base::PlatformFile file = IPC::PlatformFileForTransitToPlatformFile(descriptor_); #if !defined(OS_NACL) @@ -195,6 +203,7 @@ bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) { } case SOCKET: case CHANNEL_HANDLE: + case FILE: case INVALID: valid_type = true; break; diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h index 04d7f5d..bdc1b678 100644 --- a/ppapi/proxy/serialized_structs.h +++ b/ppapi/proxy/serialized_structs.h @@ -91,7 +91,7 @@ struct PPBURLLoader_UpdateProgress_Params { // them in NaClIPCAdapter for use in NaCl. class PPAPI_PROXY_EXPORT SerializedHandle { public: - enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE }; + enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE }; struct Header { Header() : type(INVALID), size(0) {} Header(Type type_arg, uint32_t size_arg) @@ -108,7 +108,7 @@ class PPAPI_PROXY_EXPORT SerializedHandle { // Create a shared memory handle. SerializedHandle(const base::SharedMemoryHandle& handle, uint32_t size); - // Create a socket or channel handle. + // Create a socket, channel or file handle. SerializedHandle(const Type type, const IPC::PlatformFileForTransit& descriptor); @@ -116,6 +116,7 @@ class PPAPI_PROXY_EXPORT SerializedHandle { bool is_shmem() const { return type_ == SHARED_MEMORY; } bool is_socket() const { return type_ == SOCKET; } bool is_channel_handle() const { return type_ == CHANNEL_HANDLE; } + bool is_file() const { return type_ == FILE; } const base::SharedMemoryHandle& shmem() const { DCHECK(is_shmem()); return shm_handle_; @@ -125,7 +126,7 @@ class PPAPI_PROXY_EXPORT SerializedHandle { return size_; } const IPC::PlatformFileForTransit& descriptor() const { - DCHECK(is_socket() || is_channel_handle()); + DCHECK(is_socket() || is_channel_handle() || is_file()); return descriptor_; } void set_shmem(const base::SharedMemoryHandle& handle, uint32_t size) { @@ -149,6 +150,13 @@ class PPAPI_PROXY_EXPORT SerializedHandle { shm_handle_ = base::SharedMemory::NULLHandle(); size_ = 0; } + void set_file_handle(const IPC::PlatformFileForTransit& descriptor) { + type_ = FILE; + + descriptor_ = descriptor; + shm_handle_ = base::SharedMemory::NULLHandle(); + size_ = 0; + } void set_null_shmem() { set_shmem(base::SharedMemory::NULLHandle(), 0); } @@ -158,6 +166,9 @@ class PPAPI_PROXY_EXPORT SerializedHandle { void set_null_channel_handle() { set_channel_handle(IPC::InvalidPlatformFileForTransit()); } + void set_null_file_handle() { + set_file_handle(IPC::InvalidPlatformFileForTransit()); + } bool IsHandleValid() const; Header header() const { diff --git a/ppapi/shared_impl/file_path.cc b/ppapi/shared_impl/file_path.cc index 1208b08..1502d89 100644 --- a/ppapi/shared_impl/file_path.cc +++ b/ppapi/shared_impl/file_path.cc @@ -4,26 +4,8 @@ #include "ppapi/shared_impl/file_path.h" -#include <string> - -#if defined(OS_WIN) -#include "base/utf_string_conversions.h" -#endif - namespace ppapi { -namespace { - -FilePath GetFilePathFromUTF8(const std::string& utf8_path) { -#if defined(OS_WIN) - return FilePath(UTF8ToUTF16(utf8_path)); -#else - return FilePath(utf8_path); -#endif -} - -} // namespace - PepperFilePath::PepperFilePath() : domain_(DOMAIN_INVALID), path_() { @@ -35,17 +17,4 @@ PepperFilePath::PepperFilePath(Domain domain, const FilePath& path) // TODO(viettrungluu): Should we DCHECK() some things here? } -// static -PepperFilePath PepperFilePath::MakeAbsolute(const FilePath& path) { - return PepperFilePath(DOMAIN_ABSOLUTE, path); -} - -// static -PepperFilePath PepperFilePath::MakeModuleLocal(const std::string& name, - const char* utf8_path) { - FilePath full_path = GetFilePathFromUTF8(name).Append( - GetFilePathFromUTF8(utf8_path)); - return PepperFilePath(DOMAIN_MODULE_LOCAL, full_path); -} - } // namespace ppapi diff --git a/ppapi/shared_impl/file_path.h b/ppapi/shared_impl/file_path.h index bcec9f8..3d850f9 100644 --- a/ppapi/shared_impl/file_path.h +++ b/ppapi/shared_impl/file_path.h @@ -5,8 +5,6 @@ #ifndef PPAPI_SHARED_IMPL_FILE_PATH_H_ #define PPAPI_SHARED_IMPL_FILE_PATH_H_ -#include <string> - #include "base/file_path.h" #include "ppapi/shared_impl/ppapi_shared_export.h" @@ -30,10 +28,6 @@ class PPAPI_SHARED_EXPORT PepperFilePath { PepperFilePath(); PepperFilePath(Domain d, const FilePath& p); - static PepperFilePath MakeAbsolute(const FilePath& path); - static PepperFilePath MakeModuleLocal(const std::string& name, - const char* utf8_path); - Domain domain() const { return domain_; } const FilePath& path() const { return path_; } diff --git a/ppapi/shared_impl/ppb_flash_shared.cc b/ppapi/shared_impl/ppb_flash_shared.cc deleted file mode 100644 index c310e0e..0000000 --- a/ppapi/shared_impl/ppb_flash_shared.cc +++ /dev/null @@ -1,23 +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_flash_shared.h" - -namespace ppapi { - -PPB_Flash_Shared::PPB_Flash_Shared() { -} - -PPB_Flash_Shared::~PPB_Flash_Shared() { -} - -void PPB_Flash_Shared::FreeDirContents(PP_Instance instance, - PP_DirContents_Dev* contents) { - for (int32_t i = 0; i < contents->count; ++i) - delete[] contents->entries[i].name; - delete[] contents->entries; - delete contents; -} - -} // namespace ppapi diff --git a/ppapi/shared_impl/ppb_flash_shared.h b/ppapi/shared_impl/ppb_flash_shared.h deleted file mode 100644 index 29f8973..0000000 --- a/ppapi/shared_impl/ppb_flash_shared.h +++ /dev/null @@ -1,30 +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_FLASH_SHARED_H_ -#define PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ppapi/shared_impl/ppapi_shared_export.h" -#include "ppapi/thunk/ppb_flash_api.h" - -namespace ppapi { - -class PPAPI_SHARED_EXPORT PPB_Flash_Shared : public thunk::PPB_Flash_API { - public: - PPB_Flash_Shared(); - virtual ~PPB_Flash_Shared(); - - // Shared implementation of PPB_Flash_API. - virtual void FreeDirContents(PP_Instance instance, - PP_DirContents_Dev* contents) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(PPB_Flash_Shared); -}; - -} // namespace ppapi - -#endif // PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_ diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index dc1bf3f..6c86868 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -36,6 +36,7 @@ F(PPB_Find_API) \ F(PPB_Flash_Clipboard_API) \ F(PPB_Flash_DeviceID_API) \ + F(PPB_Flash_File_API) \ F(PPB_Flash_FontFile_API) \ F(PPB_Flash_Fullscreen_API) \ F(PPB_Flash_Functions_API) \ diff --git a/ppapi/shared_impl/singleton_resource_id.h b/ppapi/shared_impl/singleton_resource_id.h index 9558db6..442611a 100644 --- a/ppapi/shared_impl/singleton_resource_id.h +++ b/ppapi/shared_impl/singleton_resource_id.h @@ -11,6 +11,7 @@ namespace ppapi { // PPB_Instance_API.GetSingletonResource. enum SingletonResourceID { FLASH_CLIPBOARD_SINGLETON_ID, + FLASH_FILE_SINGLETON_ID, FLASH_FULLSCREEN_SINGLETON_ID, FLASH_SINGLETON_ID, GAMEPAD_SINGLETON_ID, diff --git a/ppapi/tests/test_flash_file.cc b/ppapi/tests/test_flash_file.cc index a4a1169..86100d9 100644 --- a/ppapi/tests/test_flash_file.cc +++ b/ppapi/tests/test_flash_file.cc @@ -4,6 +4,11 @@ #include "ppapi/tests/test_flash_file.h" +#include <algorithm> +#include <vector> + +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/ppb_file_io.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/private/flash_file.h" #include "ppapi/tests/testing_instance.h" @@ -74,6 +79,18 @@ bool ReadFile(PP_FileHandle file_handle, std::string* contents) { return result; } +bool DirEntryEqual(FileModuleLocal::DirEntry i, + FileModuleLocal::DirEntry j) { + return i.name == j.name && i.is_dir == j.is_dir; +} + +bool DirEntryLessThan(FileModuleLocal::DirEntry i, + FileModuleLocal::DirEntry j) { + if (i.name == j.name) + return i.is_dir < j.is_dir; + return i.name < j.name; +} + } // namespace REGISTER_TEST_CASE(FlashFile); @@ -90,13 +107,204 @@ bool TestFlashFile::Init() { } void TestFlashFile::RunTests(const std::string& filter) { + RUN_TEST(OpenFile, filter); + RUN_TEST(RenameFile, filter); + RUN_TEST(DeleteFileOrDir, filter); + RUN_TEST(CreateDir, filter); + RUN_TEST(QueryFile, filter); + RUN_TEST(GetDirContents, filter); RUN_TEST(CreateTemporaryFile, filter); } -std::string TestFlashFile::TestCreateTemporaryFile() { +void TestFlashFile::SetUp() { + // Clear out existing test data. + FileModuleLocal::DeleteFileOrDir(instance_, std::string(), true); // Make sure that the root directory exists. FileModuleLocal::CreateDir(instance_, std::string()); +} + +std::string TestFlashFile::TestOpenFile() { + SetUp(); + std::string filename = "abc.txt"; + PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_, + filename, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + + std::string contents = "This is file."; + std::string read_contents; + ASSERT_TRUE(WriteFile(file_handle, contents)); + ASSERT_FALSE(ReadFile(file_handle, &read_contents)); + CloseFileHandle(file_handle); + + file_handle = FileModuleLocal::OpenFile(instance_, + filename, + PP_FILEOPENFLAG_READ); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + + ASSERT_FALSE(WriteFile(file_handle, contents)); + ASSERT_TRUE(ReadFile(file_handle, &read_contents)); + ASSERT_EQ(contents, read_contents); + CloseFileHandle(file_handle); + + PASS(); +} + +std::string TestFlashFile::TestRenameFile() { + SetUp(); + std::string filename = "abc.txt"; + std::string new_filename = "abc_new.txt"; + std::string contents = "This is file."; + std::string read_contents; + + PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_, + filename, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + ASSERT_TRUE(WriteFile(file_handle, contents)); + CloseFileHandle(file_handle); + + ASSERT_TRUE(FileModuleLocal::RenameFile(instance_, filename, new_filename)); + + file_handle = FileModuleLocal::OpenFile(instance_, + new_filename, + PP_FILEOPENFLAG_READ); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + ASSERT_TRUE(ReadFile(file_handle, &read_contents)); + ASSERT_EQ(contents, read_contents); + CloseFileHandle(file_handle); + + // Check that the old file no longer exists. + PP_FileInfo unused; + ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused)); + + PASS(); +} + +std::string TestFlashFile::TestDeleteFileOrDir() { + SetUp(); + std::string filename = "abc.txt"; + std::string dirname = "def"; + std::string contents = "This is file."; + // Test file deletion. + PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_, + filename, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + ASSERT_TRUE(WriteFile(file_handle, contents)); + CloseFileHandle(file_handle); + ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, filename, false)); + PP_FileInfo unused; + ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused)); + + // Test directory deletion. + ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname)); + ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, false)); + ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, dirname, &unused)); + + // Test recursive directory deletion. + ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname)); + file_handle = FileModuleLocal::OpenFile( + instance_, dirname + "/" + filename, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + ASSERT_TRUE(WriteFile(file_handle, contents)); + CloseFileHandle(file_handle); + ASSERT_FALSE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, false)); + ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, true)); + ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused)); + + PASS(); +} + +std::string TestFlashFile::TestCreateDir() { + SetUp(); + std::string dirname = "abc"; + PP_FileInfo info; + ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, dirname, &info)); + ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname)); + ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, dirname, &info)); + ASSERT_EQ(info.type, PP_FILETYPE_DIRECTORY); + + PASS(); +} + +std::string TestFlashFile::TestQueryFile() { + std::string filename = "abc.txt"; + std::string dirname = "def"; + std::string contents = "This is file."; + PP_FileInfo info; + + // Test querying a file. + PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_, + filename, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + ASSERT_TRUE(WriteFile(file_handle, contents)); + CloseFileHandle(file_handle); + ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, filename, &info)); + ASSERT_EQ(static_cast<size_t>(info.size), contents.size()); + ASSERT_EQ(info.type, PP_FILETYPE_REGULAR); + // TODO(raymes): Test the other fields. + + // Test querying a directory. + ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname)); + ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, dirname, &info)); + ASSERT_EQ(info.type, PP_FILETYPE_DIRECTORY); + // TODO(raymes): Test the other fields. + + // Test querying a non-existent file. + ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, "xx", &info)); + + PASS(); +} + +std::string TestFlashFile::TestGetDirContents() { + SetUp(); + std::vector<FileModuleLocal::DirEntry> result; + ASSERT_TRUE(FileModuleLocal::GetDirContents(instance_, std::string(), + &result)); + ASSERT_EQ(result.size(), 1); + ASSERT_EQ(result[0].name, ".."); + ASSERT_EQ(result[0].is_dir, true); + + std::string filename = "abc.txt"; + std::string dirname = "def"; + std::string contents = "This is file."; + PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_, + filename, + PP_FILEOPENFLAG_WRITE | + PP_FILEOPENFLAG_CREATE); + ASSERT_NE(PP_kInvalidFileHandle, file_handle); + ASSERT_TRUE(WriteFile(file_handle, contents)); + CloseFileHandle(file_handle); + ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname)); + + ASSERT_TRUE(FileModuleLocal::GetDirContents(instance_, "", &result)); + FileModuleLocal::DirEntry expected[] = + { {"..", true}, + {filename, false}, + {dirname, true} + }; + size_t expected_size = sizeof(expected) / sizeof(expected[0]); + + std::sort(expected, expected + expected_size, DirEntryLessThan); + std::sort(result.begin(), result.end(), DirEntryLessThan); + + ASSERT_EQ(expected_size, result.size()); + ASSERT_TRUE(std::equal(expected, expected + expected_size, result.begin(), + DirEntryEqual)); + + PASS(); +} + +std::string TestFlashFile::TestCreateTemporaryFile() { + SetUp(); size_t before_create = 0; ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&before_create)); diff --git a/ppapi/tests/test_flash_file.h b/ppapi/tests/test_flash_file.h index b58890d..86055db 100644 --- a/ppapi/tests/test_flash_file.h +++ b/ppapi/tests/test_flash_file.h @@ -19,10 +19,21 @@ class TestFlashFile: public TestCase { virtual void RunTests(const std::string& filter); private: - // TODO(yzshen): Add more test cases for PPB_Flash_File_ModuleLocal and - // PPB_Flash_File_FileRef. + // TODO(raymes): We should have SetUp/TearDown methods for ppapi tests. + void SetUp(); + + std::string TestOpenFile(); + std::string TestRenameFile(); + std::string TestDeleteFileOrDir(); + std::string TestCreateDir(); + std::string TestQueryFile(); + std::string TestGetDirContents(); std::string TestCreateTemporaryFile(); + // TODO(raymes): Add these when we can test file chooser properly. + // std::string TestOpenFileRef(); + // std::string TestQueryFileRef(); + // Gets the number of files and directories under the module-local root // directory. std::string GetItemCountUnderModuleLocalRoot(size_t* item_count); diff --git a/ppapi/thunk/ppb_file_ref_api.h b/ppapi/thunk/ppb_file_ref_api.h index ed46098..0f9bbaa 100644 --- a/ppapi/thunk/ppb_file_ref_api.h +++ b/ppapi/thunk/ppb_file_ref_api.h @@ -33,7 +33,7 @@ class PPAPI_THUNK_EXPORT PPB_FileRef_API { virtual int32_t Rename(PP_Resource new_file_ref, scoped_refptr<TrackedCallback> callback) = 0; - // Intermal function for use in proxying. Returns the internal CreateInfo + // Internal function for use in proxying. Returns the internal CreateInfo // (the contained resource does not carry a ref on behalf of the caller). virtual const PPB_FileRef_CreateInfo& GetCreateInfo() const = 0; diff --git a/ppapi/thunk/ppb_flash_api.h b/ppapi/thunk/ppb_flash_api.h index 50a039d..d41acd9 100644 --- a/ppapi/thunk/ppb_flash_api.h +++ b/ppapi/thunk/ppb_flash_api.h @@ -57,40 +57,6 @@ class PPAPI_THUNK_EXPORT PPB_Flash_API { virtual double GetLocalTimeZoneOffset(PP_Instance instance, PP_Time t) = 0; virtual PP_Bool IsRectTopmost(PP_Instance instance, const PP_Rect* rect) = 0; virtual PP_Var GetSetting(PP_Instance instance, PP_FlashSetting setting) = 0; - - // FlashFile_ModuleLocal. - virtual bool CreateThreadAdapterForInstance(PP_Instance instance) = 0; - virtual void ClearThreadAdapterForInstance(PP_Instance instance) = 0; - virtual int32_t OpenFile(PP_Instance instance, - const char* path, - int32_t mode, - PP_FileHandle* file) = 0; - virtual int32_t RenameFile(PP_Instance instance, - const char* path_from, - const char* path_to) = 0; - virtual int32_t DeleteFileOrDir(PP_Instance instance, - const char* path, - PP_Bool recursive) = 0; - virtual int32_t CreateDir(PP_Instance instance, const char* path) = 0; - virtual int32_t QueryFile(PP_Instance instance, - const char* path, - PP_FileInfo* info) = 0; - virtual int32_t GetDirContents(PP_Instance instance, - const char* path, - 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, - PP_Resource file_ref, - int32_t mode, - PP_FileHandle* file) = 0; - virtual int32_t QueryFileRef(PP_Instance instance, - PP_Resource file_ref, - PP_FileInfo* info) = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_flash_file_api.h b/ppapi/thunk/ppb_flash_file_api.h new file mode 100644 index 0000000..d757253 --- /dev/null +++ b/ppapi/thunk/ppb_flash_file_api.h @@ -0,0 +1,63 @@ +// 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_THUNK_PPB_FLASH_FILE_API_H_ +#define PPAPI_THUNK_PPB_FLASH_FILE_API_H_ + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/private/pp_file_handle.h" +#include "ppapi/c/private/ppb_flash_file.h" +#include "ppapi/shared_impl/singleton_resource_id.h" +#include "ppapi/thunk/ppapi_thunk_export.h" + +struct PP_FileInfo; + +namespace ppapi { +namespace thunk { + +class PPAPI_THUNK_EXPORT PPB_Flash_File_API { + public: + virtual ~PPB_Flash_File_API() {} + + // FlashFile_ModuleLocal. + virtual int32_t OpenFile(PP_Instance instance, + const char* path, + int32_t mode, + PP_FileHandle* file) = 0; + virtual int32_t RenameFile(PP_Instance instance, + const char* path_from, + const char* path_to) = 0; + virtual int32_t DeleteFileOrDir(PP_Instance instance, + const char* path, + PP_Bool recursive) = 0; + virtual int32_t CreateDir(PP_Instance instance, const char* path) = 0; + virtual int32_t QueryFile(PP_Instance instance, + const char* path, + PP_FileInfo* info) = 0; + virtual int32_t GetDirContents(PP_Instance instance, + const char* path, + 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, + PP_Resource file_ref, + int32_t mode, + PP_FileHandle* file) = 0; + virtual int32_t QueryFileRef(PP_Instance instance, + PP_Resource file_ref, + PP_FileInfo* info) = 0; + + static const SingletonResourceID kSingletonResourceID = + FLASH_FILE_SINGLETON_ID; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_PPB_FLASH_FILE_API_H_ diff --git a/ppapi/thunk/ppb_flash_file_fileref_thunk.cc b/ppapi/thunk/ppb_flash_file_fileref_thunk.cc index 2b380c7..8ea0f24 100644 --- a/ppapi/thunk/ppb_flash_file_fileref_thunk.cc +++ b/ppapi/thunk/ppb_flash_file_fileref_thunk.cc @@ -6,8 +6,7 @@ #include "ppapi/c/private/ppb_flash_file.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_file_ref_api.h" -#include "ppapi/thunk/ppb_flash_api.h" -#include "ppapi/thunk/ppb_instance_api.h" +#include "ppapi/thunk/ppb_flash_file_api.h" #include "ppapi/thunk/thunk.h" namespace ppapi { @@ -27,22 +26,20 @@ int32_t OpenFile(PP_Resource file_ref_id, int32_t mode, PP_FileHandle* file) { // TODO(brettw): this function should take an instance. // To work around this, use the PP_Instance from the resource. PP_Instance instance = GetInstanceFromFileRef(file_ref_id); - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->OpenFileRef(instance, file_ref_id, - mode, file); + return enter.functions()->OpenFileRef(instance, file_ref_id, mode, file); } int32_t QueryFile(PP_Resource file_ref_id, struct PP_FileInfo* info) { // TODO(brettw): this function should take an instance. // To work around this, use the PP_Instance from the resource. PP_Instance instance = GetInstanceFromFileRef(file_ref_id); - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->QueryFileRef(instance, file_ref_id, - info); + return enter.functions()->QueryFileRef(instance, file_ref_id, info); } const PPB_Flash_File_FileRef g_ppb_flash_file_fileref_thunk = { diff --git a/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc b/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc index 70c45d4..11962e4 100644 --- a/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc +++ b/ppapi/thunk/ppb_flash_file_modulelocal_thunk.cc @@ -5,8 +5,7 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_flash_file.h" #include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_flash_api.h" -#include "ppapi/thunk/ppb_instance_api.h" +#include "ppapi/thunk/ppb_flash_file_api.h" #include "ppapi/thunk/thunk.h" namespace ppapi { @@ -15,89 +14,77 @@ namespace thunk { namespace { bool CreateThreadAdapterForInstance(PP_Instance instance) { - EnterInstance enter(instance); - if (enter.failed()) - return false; - return enter.functions()->GetFlashAPI()->CreateThreadAdapterForInstance( - instance); + return true; } void ClearThreadAdapterForInstance(PP_Instance instance) { - EnterInstance enter(instance); - if (enter.succeeded()) { - return enter.functions()->GetFlashAPI()->ClearThreadAdapterForInstance( - instance); - } } int32_t OpenFile(PP_Instance instance, const char* path, int32_t mode, PP_FileHandle* file) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->OpenFile(instance, path, mode, file); + return enter.functions()->OpenFile(instance, path, mode, file); } int32_t RenameFile(PP_Instance instance, const char* path_from, const char* path_to) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->RenameFile(instance, - path_from, path_to); + return enter.functions()->RenameFile(instance, path_from, path_to); } int32_t DeleteFileOrDir(PP_Instance instance, const char* path, PP_Bool recursive) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->DeleteFileOrDir(instance, path, - recursive); + return enter.functions()->DeleteFileOrDir(instance, path, recursive); } int32_t CreateDir(PP_Instance instance, const char* path) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->CreateDir(instance, path); + return enter.functions()->CreateDir(instance, path); } int32_t QueryFile(PP_Instance instance, const char* path, PP_FileInfo* info) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->QueryFile(instance, path, info); + return enter.functions()->QueryFile(instance, path, info); } int32_t GetDirContents(PP_Instance instance, const char* path, PP_DirContents_Dev** contents) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; - return enter.functions()->GetFlashAPI()->GetDirContents(instance, path, - contents); + return enter.functions()->GetDirContents(instance, path, contents); } void FreeDirContents(PP_Instance instance, PP_DirContents_Dev* contents) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.succeeded()) - enter.functions()->GetFlashAPI()->FreeDirContents(instance, contents); + enter.functions()->FreeDirContents(instance, contents); } int32_t CreateTemporaryFile(PP_Instance instance, PP_FileHandle* file) { - EnterInstance enter(instance); + EnterInstanceAPI<PPB_Flash_File_API> enter(instance); if (enter.failed()) return PP_ERROR_BADARGUMENT; *file = PP_kInvalidFileHandle; - return enter.functions()->GetFlashAPI()->CreateTemporaryFile(instance, file); + return enter.functions()->CreateTemporaryFile(instance, file); } const PPB_Flash_File_ModuleLocal_3_0 g_ppb_flash_file_modulelocal_thunk_3_0 = { diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc index 54947e7..eec48da 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.cc +++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc @@ -220,47 +220,6 @@ void MockPluginDelegate::WillUpdateFile(const GURL& file_path) { void MockPluginDelegate::DidUpdateFile(const GURL& file_path, int64_t delta) { } -base::PlatformFileError MockPluginDelegate::OpenFile( - const ::ppapi::PepperFilePath& path, - int flags, - base::PlatformFile* file) { - return base::PLATFORM_FILE_ERROR_FAILED; -} - -base::PlatformFileError MockPluginDelegate::RenameFile( - const ::ppapi::PepperFilePath& from_path, - const ::ppapi::PepperFilePath& to_path) { - return base::PLATFORM_FILE_ERROR_FAILED; -} - -base::PlatformFileError MockPluginDelegate::DeleteFileOrDir( - const ::ppapi::PepperFilePath& path, - bool recursive) { - return base::PLATFORM_FILE_ERROR_FAILED; -} - -base::PlatformFileError MockPluginDelegate::CreateDir( - const ::ppapi::PepperFilePath& path) { - return base::PLATFORM_FILE_ERROR_FAILED; -} - -base::PlatformFileError MockPluginDelegate::QueryFile( - const ::ppapi::PepperFilePath& path, - base::PlatformFileInfo* info) { - return base::PLATFORM_FILE_ERROR_FAILED; -} - -base::PlatformFileError MockPluginDelegate::GetDirContents( - const ::ppapi::PepperFilePath& path, - ::ppapi::DirContents* contents) { - 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 5ce5819..f2f3407 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.h +++ b/webkit/plugins/ppapi/mock_plugin_delegate.h @@ -101,26 +101,6 @@ class MockPluginDelegate : public PluginDelegate { const AvailableSpaceCallback& callback); virtual void WillUpdateFile(const GURL& file_path); virtual void DidUpdateFile(const GURL& file_path, int64_t delta); - virtual base::PlatformFileError OpenFile( - const ::ppapi::PepperFilePath& path, - int flags, - base::PlatformFile* file); - virtual base::PlatformFileError RenameFile( - const ::ppapi::PepperFilePath& from_path, - const ::ppapi::PepperFilePath& to_path); - virtual base::PlatformFileError DeleteFileOrDir( - const ::ppapi::PepperFilePath& path, - bool recursive); - virtual base::PlatformFileError CreateDir( - const ::ppapi::PepperFilePath& path); - virtual base::PlatformFileError QueryFile( - const ::ppapi::PepperFilePath& path, - base::PlatformFileInfo* info); - 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 a3cbd89..695b0f7 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -507,27 +507,6 @@ class PluginDelegate { virtual void WillUpdateFile(const GURL& file_path) = 0; virtual void DidUpdateFile(const GURL& file_path, int64_t delta) = 0; - virtual base::PlatformFileError OpenFile( - const ::ppapi::PepperFilePath& path, - int flags, - base::PlatformFile* file) = 0; - virtual base::PlatformFileError RenameFile( - const ::ppapi::PepperFilePath& from_path, - const ::ppapi::PepperFilePath& to_path) = 0; - virtual base::PlatformFileError DeleteFileOrDir( - const ::ppapi::PepperFilePath& path, - bool recursive) = 0; - virtual base::PlatformFileError CreateDir( - const ::ppapi::PepperFilePath& path) = 0; - virtual base::PlatformFileError QueryFile( - const ::ppapi::PepperFilePath& path, - base::PlatformFileInfo* info) = 0; - 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, FilePath* platform_path) = 0; diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index 3cae57c..5bdacb0 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -2133,6 +2133,7 @@ PP_Bool PluginInstance::GetScreenSize(PP_Instance instance, PP_Size* size) { // Flash APIs aren't implemented in-process. switch (id) { case ::ppapi::FLASH_CLIPBOARD_SINGLETON_ID: + case ::ppapi::FLASH_FILE_SINGLETON_ID: case ::ppapi::FLASH_FULLSCREEN_SINGLETON_ID: case ::ppapi::FLASH_SINGLETON_ID: NOTIMPLEMENTED(); diff --git a/webkit/plugins/ppapi/ppb_flash_impl.cc b/webkit/plugins/ppapi/ppb_flash_impl.cc index 075292e..f278473 100644 --- a/webkit/plugins/ppapi/ppb_flash_impl.cc +++ b/webkit/plugins/ppapi/ppb_flash_impl.cc @@ -7,17 +7,12 @@ #include <string> #include <vector> -#include "base/time.h" -#include "base/utf_string_conversions.h" #include "googleurl/src/gurl.h" #include "ppapi/c/private/ppb_flash.h" #include "ppapi/c/trusted/ppb_browser_font_trusted.h" -#include "ppapi/shared_impl/file_path.h" -#include "ppapi/shared_impl/file_type_conversion.h" #include "ppapi/shared_impl/time_conversion.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_file_ref_api.h" #include "ppapi/thunk/ppb_image_data_api.h" #include "ppapi/thunk/ppb_url_request_info_api.h" #include "skia/ext/platform_canvas.h" @@ -36,16 +31,12 @@ #include "webkit/plugins/ppapi/plugin_delegate.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" #include "webkit/plugins/ppapi/resource_helper.h" #include "webkit/plugins/ppapi/ppb_image_data_impl.h" using ppapi::PPTimeToTime; using ppapi::StringVar; -using ppapi::TimeToPPTime; -using ppapi::thunk::EnterResource; using ppapi::thunk::EnterResourceNoLock; -using ppapi::thunk::PPB_FileRef_API; using ppapi::thunk::PPB_ImageData_API; using ppapi::thunk::PPB_URLRequestInfo_API; @@ -214,225 +205,5 @@ PP_Var PPB_Flash_Impl::GetSetting(PP_Instance instance, } } -bool PPB_Flash_Impl::CreateThreadAdapterForInstance(PP_Instance instance) { - return false; // No multithreaded access allowed. -} - -void PPB_Flash_Impl::ClearThreadAdapterForInstance(PP_Instance instance) { -} - -int32_t PPB_Flash_Impl::OpenFile(PP_Instance pp_instance, - const char* path, - int32_t mode, - PP_FileHandle* file) { - int flags = 0; - if (!path || - !::ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || - !file) - return PP_ERROR_BADARGUMENT; - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFile base_file; - base::PlatformFileError result = instance->delegate()->OpenFile( - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path), - flags, - &base_file); - *file = base_file; - return ::ppapi::PlatformFileErrorToPepperError(result); -} - -int32_t PPB_Flash_Impl::RenameFile(PP_Instance pp_instance, - const char* path_from, - const char* path_to) { - if (!path_from || !path_to) - return PP_ERROR_BADARGUMENT; - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFileError result = instance->delegate()->RenameFile( - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path_from), - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path_to)); - return ::ppapi::PlatformFileErrorToPepperError(result); -} - -int32_t PPB_Flash_Impl::DeleteFileOrDir(PP_Instance pp_instance, - const char* path, - PP_Bool recursive) { - if (!path) - return PP_ERROR_BADARGUMENT; - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFileError result = instance->delegate()->DeleteFileOrDir( - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path), - PPBoolToBool(recursive)); - return ::ppapi::PlatformFileErrorToPepperError(result); -} - -int32_t PPB_Flash_Impl::CreateDir(PP_Instance pp_instance, const char* path) { - if (!path) - return PP_ERROR_BADARGUMENT; - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFileError result = instance->delegate()->CreateDir( - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path)); - return ::ppapi::PlatformFileErrorToPepperError(result); -} - -int32_t PPB_Flash_Impl::QueryFile(PP_Instance pp_instance, - const char* path, - PP_FileInfo* info) { - if (!path || !info) - return PP_ERROR_BADARGUMENT; - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFileInfo file_info; - base::PlatformFileError result = instance->delegate()->QueryFile( - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path), - &file_info); - if (result == 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 = PP_FILESYSTEMTYPE_EXTERNAL; - if (file_info.is_directory) - info->type = PP_FILETYPE_DIRECTORY; - else - info->type = PP_FILETYPE_REGULAR; - } - return ::ppapi::PlatformFileErrorToPepperError(result); -} - -int32_t PPB_Flash_Impl::GetDirContents(PP_Instance pp_instance, - const char* path, - PP_DirContents_Dev** contents) { - if (!path || !contents) - return PP_ERROR_BADARGUMENT; - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - *contents = NULL; - ::ppapi::DirContents pepper_contents; - base::PlatformFileError result = instance->delegate()->GetDirContents( - ::ppapi::PepperFilePath::MakeModuleLocal( - instance->module()->name(), path), - &pepper_contents); - - if (result != base::PLATFORM_FILE_OK) - return ::ppapi::PlatformFileErrorToPepperError(result); - - *contents = new PP_DirContents_Dev; - size_t count = pepper_contents.size(); - (*contents)->count = count; - (*contents)->entries = new PP_DirEntry_Dev[count]; - for (size_t i = 0; i < count; ++i) { - PP_DirEntry_Dev& entry = (*contents)->entries[i]; -#if defined(OS_WIN) - const std::string& name = UTF16ToUTF8(pepper_contents[i].name.value()); -#else - const std::string& name = pepper_contents[i].name.value(); -#endif - size_t size = name.size() + 1; - char* name_copy = new char[size]; - memcpy(name_copy, name.c_str(), size); - entry.name = name_copy; - entry.is_dir = BoolToPPBool(pepper_contents[i].is_dir); - } - 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, - PP_FileHandle* file) { - int flags = 0; - if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || !file) - return PP_ERROR_BADARGUMENT; - - EnterResourceNoLock<PPB_FileRef_API> enter(file_ref_id, true); - if (enter.failed()) - return PP_ERROR_BADRESOURCE; - PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(enter.object()); - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFile base_file; - base::PlatformFileError result = instance->delegate()->OpenFile( - ::ppapi::PepperFilePath::MakeAbsolute(file_ref->GetSystemPath()), - flags, - &base_file); - *file = base_file; - return ::ppapi::PlatformFileErrorToPepperError(result); -} - -int32_t PPB_Flash_Impl::QueryFileRef(PP_Instance pp_instance, - PP_Resource file_ref_id, - PP_FileInfo* info) { - EnterResource<PPB_FileRef_API> enter(file_ref_id, true); - if (enter.failed()) - return PP_ERROR_BADRESOURCE; - PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(enter.object()); - - PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance); - if (!instance) - return PP_ERROR_FAILED; - - base::PlatformFileInfo file_info; - base::PlatformFileError result = instance->delegate()->QueryFile( - ::ppapi::PepperFilePath::MakeAbsolute(file_ref->GetSystemPath()), - &file_info); - if (result == 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 = PP_FILESYSTEMTYPE_EXTERNAL; - if (file_info.is_directory) - info->type = PP_FILETYPE_DIRECTORY; - else - info->type = PP_FILETYPE_REGULAR; - } - return ::ppapi::PlatformFileErrorToPepperError(result); -} - } // namespace ppapi } // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_flash_impl.h b/webkit/plugins/ppapi/ppb_flash_impl.h index 7b264b0..68ff0d8 100644 --- a/webkit/plugins/ppapi/ppb_flash_impl.h +++ b/webkit/plugins/ppapi/ppb_flash_impl.h @@ -9,14 +9,14 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "build/build_config.h" -#include "ppapi/shared_impl/ppb_flash_shared.h" +#include "ppapi/thunk/ppb_flash_api.h" namespace webkit { namespace ppapi { class PluginInstance; -class PPB_Flash_Impl : public ::ppapi::PPB_Flash_Shared { +class PPB_Flash_Impl : public ::ppapi::thunk::PPB_Flash_API { public: explicit PPB_Flash_Impl(PluginInstance* instance); virtual ~PPB_Flash_Impl(); @@ -50,34 +50,6 @@ class PPB_Flash_Impl : public ::ppapi::PPB_Flash_Shared { const PP_Rect* rect) OVERRIDE; virtual PP_Var GetSetting(PP_Instance instance, PP_FlashSetting setting) OVERRIDE; - virtual bool CreateThreadAdapterForInstance(PP_Instance instance) OVERRIDE; - virtual void ClearThreadAdapterForInstance(PP_Instance instance) OVERRIDE; - virtual int32_t OpenFile(PP_Instance instance, - const char* path, - int32_t mode, - PP_FileHandle* file) OVERRIDE; - virtual int32_t RenameFile(PP_Instance instance, - const char* path_from, - const char* path_to) OVERRIDE; - virtual int32_t DeleteFileOrDir(PP_Instance instance, - const char* path, - PP_Bool recursive) OVERRIDE; - virtual int32_t CreateDir(PP_Instance instance, const char* path) OVERRIDE; - virtual int32_t QueryFile(PP_Instance instance, - const char* path, - PP_FileInfo* info) OVERRIDE; - 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, - PP_FileHandle* file) OVERRIDE; - virtual int32_t QueryFileRef(PP_Instance instance, - PP_Resource file_ref, - PP_FileInfo* info) OVERRIDE; private: PluginInstance* instance_; |