diff options
19 files changed, 1074 insertions, 13 deletions
diff --git a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc index 56e6e32..cbfde3d 100644 --- a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc +++ b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc @@ -130,6 +130,9 @@ int32_t PepperCrxFileSystemMessageFilter::OnOpenFileSystem( return PP_ERROR_NOACCESS; } + // TODO(raymes): When we remove FileSystem from the renderer, we should create + // a pending PepperFileSystemBrowserHost here with the fsid and send the + // pending host ID back to the plugin. const std::string fsid = CreateIsolatedFileSystem(profile); if (fsid.empty()) { context->reply_msg = 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 3ed14d12..61c0f75 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,8 @@ #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h" +#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h" +#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h" #include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_gamepad_host.h" #include "content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.h" @@ -22,6 +24,7 @@ using ppapi::host::MessageFilterHost; using ppapi::host::ResourceHost; using ppapi::host::ResourceMessageFilter; +using ppapi::UnpackMessage; namespace content { @@ -46,9 +49,30 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( // Public interfaces. switch (message.type()) { + case PpapiHostMsg_FileSystem_Create::ID: { + PP_FileSystemType file_system_type; + if (!ppapi::UnpackMessage<PpapiHostMsg_FileSystem_Create>(message, + &file_system_type)) { + NOTREACHED(); + return scoped_ptr<ResourceHost>(); + } + return scoped_ptr<ResourceHost>(new PepperFileSystemBrowserHost( + host_, instance, params.pp_resource(), file_system_type)); + } case PpapiHostMsg_Gamepad_Create::ID: return scoped_ptr<ResourceHost>(new PepperGamepadHost( host_, instance, params.pp_resource())); + case PpapiHostMsg_FileRef_CreateInternal::ID: { + PP_Resource file_system; + std::string internal_path; + if (!UnpackMessage<PpapiHostMsg_FileRef_CreateInternal>( + message, &file_system, &internal_path)) { + NOTREACHED(); + return scoped_ptr<ResourceHost>(); + } + return scoped_ptr<ResourceHost>(new PepperFileRefHost( + host_, instance, params.pp_resource(), file_system, internal_path)); + } } // Dev interfaces. diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.cc b/content/browser/renderer_host/pepper/pepper_file_ref_host.cc new file mode 100644 index 0000000..fbb2286 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.cc @@ -0,0 +1,162 @@ +// Copyright 2013 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_ref_host.h" + +#include <string> + +#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h" +#include "content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_ref_util.h" + +using ppapi::host::ResourceHost; + +namespace content { + +PepperFileRefBackend::~PepperFileRefBackend() { +} + +PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + PP_Resource file_system, + const std::string& path) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host), + fs_type_(PP_FILESYSTEMTYPE_INVALID) { + if (!ppapi::IsValidInternalPath(path)) + return; + + int render_process_id; + int unused; + if (!host->GetRenderViewIDsForInstance(instance, + &render_process_id, + &unused)) { + return; + } + + ResourceHost* fs_resource_host = + host->GetPpapiHost()->GetResourceHost(file_system); + if (fs_resource_host == NULL) { + DLOG(ERROR) << "Couldn't find FileSystem host: " << resource + << " path: " << path; + return; + } + + PepperFileSystemBrowserHost* fs_host = + fs_resource_host->AsPepperFileSystemBrowserHost(); + if (fs_host == NULL) { + DLOG(ERROR) << "Filesystem PP_Resource is not PepperFileSystemBrowserHost"; + return; + } + + fs_type_ = fs_host->GetType(); + // TODO(teravest): Add support for isolated filesystems. + if ((fs_type_ != PP_FILESYSTEMTYPE_LOCALPERSISTENT) && + (fs_type_ != PP_FILESYSTEMTYPE_LOCALTEMPORARY)) { + DLOG(ERROR) << "Unsupported filesystem type: " << fs_type_; + return; + } + + backend_.reset(new PepperInternalFileRefBackend( + host->GetPpapiHost(), + render_process_id, + base::AsWeakPtr(fs_host), + path)); +} + +PepperFileRefHost::~PepperFileRefHost() { +} + +PepperFileRefHost* PepperFileRefHost::AsPepperFileRefHost() { + return this; +} + +PP_FileSystemType PepperFileRefHost::GetFileSystemType() const { + return fs_type_; +} + +fileapi::FileSystemURL PepperFileRefHost::GetFileSystemURL() const { + if (backend_) + return backend_->GetFileSystemURL(); + return fileapi::FileSystemURL(); +} + +int32_t PepperFileRefHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + if (!backend_) + return PP_ERROR_FAILED; + + IPC_BEGIN_MESSAGE_MAP(PepperFileRefHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_MakeDirectory, + OnMakeDirectory); + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_Touch, + OnTouch); + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_Delete, + OnDelete); + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_Rename, + OnRename); + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_Query, + OnQuery); + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( + PpapiHostMsg_FileRef_ReadDirectoryEntries, + OnReadDirectoryEntries); + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_GetAbsolutePath, + OnGetAbsolutePath); + + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFileRefHost::OnMakeDirectory( + ppapi::host::HostMessageContext* context, + bool make_ancestors) { + return backend_->MakeDirectory(context->MakeReplyMessageContext(), + make_ancestors); +} + +int32_t PepperFileRefHost::OnTouch(ppapi::host::HostMessageContext* context, + PP_Time last_access_time, + PP_Time last_modified_time) { + return backend_->Touch(context->MakeReplyMessageContext(), + last_access_time, + last_modified_time); +} + +int32_t PepperFileRefHost::OnDelete(ppapi::host::HostMessageContext* context) { + return backend_->Delete(context->MakeReplyMessageContext()); +} + +int32_t PepperFileRefHost::OnRename(ppapi::host::HostMessageContext* context, + PP_Resource new_file_ref) { + return backend_->Rename(context->MakeReplyMessageContext(), + new_file_ref); +} + +int32_t PepperFileRefHost::OnQuery(ppapi::host::HostMessageContext* context) { + return backend_->Query(context->MakeReplyMessageContext()); +} + +int32_t PepperFileRefHost::OnReadDirectoryEntries( + ppapi::host::HostMessageContext* context) { + return backend_->ReadDirectoryEntries(context->MakeReplyMessageContext()); +} + +int32_t PepperFileRefHost::OnGetAbsolutePath( + ppapi::host::HostMessageContext* context) { + if (!host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_PRIVATE)) + return PP_ERROR_NOACCESS; + return backend_->GetAbsolutePath(context->MakeReplyMessageContext()); +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.h b/content/browser/renderer_host/pepper/pepper_file_ref_host.h new file mode 100644 index 0000000..cb02e4a --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.h @@ -0,0 +1,92 @@ +// Copyright 2013 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_REF_HOST_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_REF_HOST_H_ + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_time.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" +#include "webkit/browser/fileapi/file_system_url.h" + +namespace content { + +// Internal and external filesystems have very different codepaths for +// performing FileRef operations. The logic is split into separate classes +// to make it easier to read. +class PepperFileRefBackend { + public: + virtual ~PepperFileRefBackend(); + + virtual int32_t MakeDirectory(ppapi::host::ReplyMessageContext context, + bool make_ancestors) = 0; + virtual int32_t Touch(ppapi::host::ReplyMessageContext context, + PP_Time last_accessed_time, + PP_Time last_modified_time) = 0; + virtual int32_t Delete(ppapi::host::ReplyMessageContext context) = 0; + virtual int32_t Rename(ppapi::host::ReplyMessageContext context, + PP_Resource new_file_ref) = 0; + virtual int32_t Query(ppapi::host::ReplyMessageContext context) = 0; + virtual int32_t ReadDirectoryEntries( + ppapi::host::ReplyMessageContext context) = 0; + virtual int32_t GetAbsolutePath( + ppapi::host::ReplyMessageContext context) = 0; + + virtual fileapi::FileSystemURL GetFileSystemURL() const = 0; +}; + +class CONTENT_EXPORT PepperFileRefHost + : public ppapi::host::ResourceHost, + public base::SupportsWeakPtr<PepperFileRefHost> { + public: + PepperFileRefHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + PP_Resource file_system, + const std::string& internal_path); + + // TODO(teravest): Add a constructor for external paths. + + virtual ~PepperFileRefHost(); + + // ResourceHost overrides. + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + virtual PepperFileRefHost* AsPepperFileRefHost() OVERRIDE; + + // Required to support Rename(). + PP_FileSystemType GetFileSystemType() const; + fileapi::FileSystemURL GetFileSystemURL() const; + + private: + int32_t OnMakeDirectory(ppapi::host::HostMessageContext* context, + bool make_ancestors); + int32_t OnTouch(ppapi::host::HostMessageContext* context, + PP_Time last_access_time, + PP_Time last_modified_time); + int32_t OnDelete(ppapi::host::HostMessageContext* context); + int32_t OnRename(ppapi::host::HostMessageContext* context, + PP_Resource new_file_ref); + int32_t OnQuery(ppapi::host::HostMessageContext* context); + int32_t OnReadDirectoryEntries(ppapi::host::HostMessageContext* context); + int32_t OnGetAbsolutePath(ppapi::host::HostMessageContext* context); + + BrowserPpapiHost* host_; + scoped_ptr<PepperFileRefBackend> backend_; + PP_FileSystemType fs_type_; + + DISALLOW_COPY_AND_ASSIGN(PepperFileRefHost); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_REF_HOST_H_ diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc new file mode 100644 index 0000000..96180cb --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc @@ -0,0 +1,184 @@ +// Copyright 2013 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_system_browser_host.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/storage_partition.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_type_conversion.h" +#include "webkit/browser/fileapi/file_system_context.h" +#include "webkit/browser/fileapi/file_system_operation_runner.h" +#include "webkit/common/fileapi/file_system_util.h" + +namespace content { + +namespace { + +// TODO(teravest): Move this function to be shared and public in fileapi. +bool LooksLikeAGuid(const std::string& fsid) { + const size_t kExpectedFsIdSize = 32; + if (fsid.size() != kExpectedFsIdSize) + return false; + for (std::string::const_iterator it = fsid.begin(); it != fsid.end(); ++it) { + if (('A' <= *it && *it <= 'F') || ('0' <= *it && *it <= '9')) + continue; + return false; + } + return true; +} + +scoped_refptr<fileapi::FileSystemContext> +GetFileSystemContextFromRenderId(int render_process_id) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(render_process_id); + if (!render_process_host) + return NULL; + StoragePartition* storage_partition = + render_process_host->GetStoragePartition(); + if (!storage_partition) + return NULL; + return storage_partition->GetFileSystemContext(); +} + +} // namespace + +PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + PP_FileSystemType type) + : ResourceHost(host->GetPpapiHost(), instance, resource), + browser_ppapi_host_(host), + weak_factory_(this), + type_(type), + opened_(false), + fs_context_(NULL), + called_open_(false) { +} + +PepperFileSystemBrowserHost::~PepperFileSystemBrowserHost() { + if (fs_context_) + fs_context_->operation_runner()->Shutdown(); +} + +int32_t PepperFileSystemBrowserHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + IPC_BEGIN_MESSAGE_MAP(PepperFileSystemBrowserHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_FileSystem_Open, + OnHostMsgOpen) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_FileSystem_InitIsolatedFileSystem, + OnHostMsgInitIsolatedFileSystem) + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +PepperFileSystemBrowserHost* +PepperFileSystemBrowserHost::AsPepperFileSystemBrowserHost() { + return this; +} + +int32_t PepperFileSystemBrowserHost::OnHostMsgOpen( + ppapi::host::HostMessageContext* context, + int64_t /* unused */) { + // TODO(raymes): The file system size is now unused by FileSystemDispatcher. + // Figure out why. Why is the file system size signed? + + // Not allow multiple opens. + if (called_open_) + return PP_ERROR_INPROGRESS; + called_open_ = true; + + fileapi::FileSystemType file_system_type; + switch (type_) { + case PP_FILESYSTEMTYPE_LOCALTEMPORARY: + file_system_type = fileapi::kFileSystemTypeTemporary; + break; + case PP_FILESYSTEMTYPE_LOCALPERSISTENT: + file_system_type = fileapi::kFileSystemTypePersistent; + break; + case PP_FILESYSTEMTYPE_EXTERNAL: + file_system_type = fileapi::kFileSystemTypeExternal; + break; + default: + return PP_ERROR_FAILED; + } + + int render_process_id = 0; + int unused; + if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), + &render_process_id, + &unused)) { + return PP_ERROR_FAILED; + } + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::UI, + FROM_HERE, + base::Bind(&GetFileSystemContextFromRenderId, render_process_id), + base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext(), + file_system_type)); + return PP_OK_COMPLETIONPENDING; +} + +void PepperFileSystemBrowserHost::GotFileSystemContext( + ppapi::host::ReplyMessageContext reply_context, + fileapi::FileSystemType file_system_type, + scoped_refptr<fileapi::FileSystemContext> fs_context) { + if (!fs_context) { + OpenFileSystemComplete(reply_context, base::PLATFORM_FILE_ERROR_FAILED, + std::string(), GURL()); + return; + } + GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( + pp_instance()).GetOrigin(); + fs_context->OpenFileSystem(origin, file_system_type, + fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, + base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, + weak_factory_.GetWeakPtr(), + reply_context)); + fs_context_ = fs_context; +} + +void PepperFileSystemBrowserHost::OpenFileSystemComplete( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error, + const std::string& /* unused */, + const GURL& root) { + int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); + if (pp_error == PP_OK) { + opened_ = true; + root_url_ = root; + } + reply_context.params.set_result(pp_error); + host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply()); +} + +int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( + ppapi::host::HostMessageContext* context, + const std::string& fsid) { + called_open_ = true; + // Do a sanity check. + if (!LooksLikeAGuid(fsid)) + return PP_ERROR_BADARGUMENT; + const GURL& url = + browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); + root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( + url.GetOrigin(), fsid, "crxfs")); + opened_ = true; + return PP_OK; +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h new file mode 100644 index 0000000..63e733f --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h @@ -0,0 +1,76 @@ +// Copyright 2013 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_SYSTEM_BROWSER_HOST_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_ + +#include "base/basictypes.h" +#include "base/memory/weak_ptr.h" +#include "googleurl/src/gurl.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" +#include "webkit/browser/fileapi/file_system_context.h" +#include "webkit/common/fileapi/file_system_types.h" + +namespace content { + +class BrowserPpapiHost; + +class PepperFileSystemBrowserHost : + public ppapi::host::ResourceHost, + public base::SupportsWeakPtr<PepperFileSystemBrowserHost> { + public: + PepperFileSystemBrowserHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + PP_FileSystemType type); + virtual ~PepperFileSystemBrowserHost(); + + // ppapi::host::ResourceHost override. + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + virtual PepperFileSystemBrowserHost* AsPepperFileSystemBrowserHost() OVERRIDE; + + // Supports FileRefs direct access on the host side. + PP_FileSystemType GetType() const { return type_; } + bool IsOpened() const { return opened_; } + GURL GetRootUrl() const { return root_url_; } + scoped_refptr<fileapi::FileSystemContext> GetFileSystemContext() const { + return fs_context_; + } + + private: + void GotFileSystemContext( + ppapi::host::ReplyMessageContext reply_context, + fileapi::FileSystemType file_system_type, + scoped_refptr<fileapi::FileSystemContext> fs_context); + void OpenFileSystemComplete( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error, + const std::string& name, + const GURL& root); + + int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context, + int64_t expected_size); + int32_t OnHostMsgInitIsolatedFileSystem( + ppapi::host::HostMessageContext* context, + const std::string& fsid); + + BrowserPpapiHost* browser_ppapi_host_; + base::WeakPtrFactory<PepperFileSystemBrowserHost> weak_factory_; + + PP_FileSystemType type_; + bool opened_; // whether open is successful. + GURL root_url_; + scoped_refptr<fileapi::FileSystemContext> fs_context_; + bool called_open_; // whether open has been called. + + DISALLOW_COPY_AND_ASSIGN(PepperFileSystemBrowserHost); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_ diff --git a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc new file mode 100644 index 0000000..77c7f86 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc @@ -0,0 +1,318 @@ +// Copyright 2013 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_internal_file_ref_backend.h" + +#include <string> + +#include "base/callback.h" +#include "base/file_util.h" +#include "base/files/file_util_proxy.h" +#include "content/browser/fileapi/browser_file_system_helper.h" +#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/storage_partition.h" +#include "net/base/escape.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_ref_create_info.h" +#include "ppapi/shared_impl/file_ref_util.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" +#include "ppapi/thunk/ppb_file_ref_api.h" +#include "ppapi/thunk/ppb_file_system_api.h" +#include "webkit/browser/fileapi/file_permission_policy.h" +#include "webkit/browser/fileapi/file_system_operation.h" +#include "webkit/browser/fileapi/file_system_operation_runner.h" +#include "webkit/browser/fileapi/file_system_url.h" +#include "webkit/common/fileapi/file_system_util.h" + +using ppapi::host::PpapiHost; +using ppapi::host::ResourceHost; + +namespace content { + +PepperInternalFileRefBackend::PepperInternalFileRefBackend( + PpapiHost* host, + int render_process_id, + base::WeakPtr<PepperFileSystemBrowserHost> fs_host, + const std::string& path) : host_(host), + render_process_id_(render_process_id), + fs_host_(fs_host), + fs_type_(fs_host->GetType()), + path_(path), + weak_factory_(this) { + ppapi::NormalizeInternalPath(&path_); +} + +PepperInternalFileRefBackend::~PepperInternalFileRefBackend() { +} + +fileapi::FileSystemURL PepperInternalFileRefBackend::GetFileSystemURL() const { + if (!fs_url_.is_valid() && fs_host_.get()) { + GURL fs_path = fs_host_->GetRootUrl().Resolve( + net::EscapePath(path_.substr(1))); + fs_url_ = GetFileSystemContext()->CrackURL(fs_path); + } + return fs_url_; +} + +scoped_refptr<fileapi::FileSystemContext> +PepperInternalFileRefBackend::GetFileSystemContext() const { + // TODO(teravest): Make this work for CRX file systems. + if (!fs_host_.get()) + return NULL; + return fs_host_->GetFileSystemContext(); +} + +void PepperInternalFileRefBackend::DidFinish( + ppapi::host::ReplyMessageContext context, + const IPC::Message& msg, + base::PlatformFileError error) { + context.params.set_result(ppapi::PlatformFileErrorToPepperError(error)); + host_->SendReply(context, msg); +} + +int32_t PepperInternalFileRefBackend::MakeDirectory( + ppapi::host::ReplyMessageContext reply_context, + bool make_ancestors) { + if (!GetFileSystemURL().is_valid()) + return PP_ERROR_FAILED; + + base::PlatformFileError error; + if (!HasPermissionsForFile(GetFileSystemURL(), + fileapi::kCreateFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + GetFileSystemContext()->operation_runner()->CreateDirectory( + GetFileSystemURL(), + false, + make_ancestors, + base::Bind(&PepperInternalFileRefBackend::DidFinish, + weak_factory_.GetWeakPtr(), + reply_context, + PpapiPluginMsg_FileRef_MakeDirectoryReply())); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperInternalFileRefBackend::Touch( + ppapi::host::ReplyMessageContext reply_context, + PP_Time last_access_time, + PP_Time last_modified_time) { + if (!GetFileSystemURL().is_valid()) + return PP_ERROR_FAILED; + + // TODO(teravest): Change this to be kWriteFilePermissions here and in + // fileapi_message_filter. + base::PlatformFileError error; + if (!HasPermissionsForFile(GetFileSystemURL(), + fileapi::kCreateFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + GetFileSystemContext()->operation_runner()->TouchFile( + GetFileSystemURL(), + ppapi::PPTimeToTime(last_access_time), + ppapi::PPTimeToTime(last_modified_time), + base::Bind(&PepperInternalFileRefBackend::DidFinish, + weak_factory_.GetWeakPtr(), + reply_context, + PpapiPluginMsg_FileRef_TouchReply())); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperInternalFileRefBackend::Delete( + ppapi::host::ReplyMessageContext reply_context) { + if (!GetFileSystemURL().is_valid()) + return PP_ERROR_FAILED; + + base::PlatformFileError error; + if (!HasPermissionsForFile(GetFileSystemURL(), + fileapi::kWriteFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + GetFileSystemContext()->operation_runner()->Remove( + GetFileSystemURL(), + false, + base::Bind(&PepperInternalFileRefBackend::DidFinish, + weak_factory_.GetWeakPtr(), + reply_context, + PpapiPluginMsg_FileRef_DeleteReply())); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperInternalFileRefBackend::Rename( + ppapi::host::ReplyMessageContext reply_context, + PP_Resource new_file_ref) { + if (!GetFileSystemURL().is_valid()) + return PP_ERROR_FAILED; + + base::PlatformFileError error; + if (!HasPermissionsForFile( + GetFileSystemURL(), + fileapi::kReadFilePermissions | fileapi::kWriteFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + ResourceHost* resource_host = host_->GetResourceHost(new_file_ref); + if (!resource_host) + return PP_ERROR_BADRESOURCE; + + PepperFileRefHost* file_ref_host = resource_host->AsPepperFileRefHost(); + if (!file_ref_host) + return PP_ERROR_BADRESOURCE; + + fileapi::FileSystemURL new_url = file_ref_host->GetFileSystemURL(); + if (!new_url.is_valid()) + return PP_ERROR_FAILED; + if (!new_url.IsInSameFileSystem(GetFileSystemURL())) + return PP_ERROR_FAILED; + + if (!HasPermissionsForFile(GetFileSystemURL(), + fileapi::kCreateFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + + GetFileSystemContext()->operation_runner()->Move( + GetFileSystemURL(), + new_url, + base::Bind(&PepperInternalFileRefBackend::DidFinish, + weak_factory_.GetWeakPtr(), + reply_context, + PpapiPluginMsg_FileRef_RenameReply())); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperInternalFileRefBackend::Query( + ppapi::host::ReplyMessageContext reply_context) { + if (!GetFileSystemURL().is_valid()) + return PP_ERROR_FAILED; + + base::PlatformFileError error; + if (!HasPermissionsForFile(GetFileSystemURL(), + fileapi::kReadFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + GetFileSystemContext()->operation_runner()->GetMetadata( + GetFileSystemURL(), + base::Bind(&PepperInternalFileRefBackend::GetMetadataComplete, + weak_factory_.GetWeakPtr(), + reply_context)); + return PP_OK_COMPLETIONPENDING; +} + +void PepperInternalFileRefBackend::GetMetadataComplete( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error, + const base::PlatformFileInfo& file_info) { + reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error)); + + PP_FileInfo pp_file_info; + if (error == base::PLATFORM_FILE_OK) + ppapi::PlatformFileInfoToPepperFileInfo(file_info, fs_type_, &pp_file_info); + else + memset(&pp_file_info, 0, sizeof(pp_file_info)); + + host_->SendReply(reply_context, + PpapiPluginMsg_FileRef_QueryReply(pp_file_info)); +} + +int32_t PepperInternalFileRefBackend::ReadDirectoryEntries( + ppapi::host::ReplyMessageContext reply_context) { + if (!GetFileSystemURL().is_valid()) + return PP_ERROR_FAILED; + + base::PlatformFileError error; + if (!HasPermissionsForFile(GetFileSystemURL(), + fileapi::kReadFilePermissions, + &error)) { + return ppapi::PlatformFileErrorToPepperError(error); + } + + GetFileSystemContext()->operation_runner()->ReadDirectory( + GetFileSystemURL(), + base::Bind(&PepperInternalFileRefBackend::ReadDirectoryComplete, + weak_factory_.GetWeakPtr(), + reply_context)); + return PP_OK_COMPLETIONPENDING; +} + +void PepperInternalFileRefBackend::ReadDirectoryComplete( + ppapi::host::ReplyMessageContext context, + base::PlatformFileError error, + const fileapi::FileSystemOperation::FileEntryList& file_list, + bool has_more) { + // The current filesystem backend always returns false. + DCHECK(!has_more); + + context.params.set_result(ppapi::PlatformFileErrorToPepperError(error)); + + std::vector<ppapi::FileRef_CreateInfo> infos; + std::vector<PP_FileType> file_types; + if (error == base::PLATFORM_FILE_OK && fs_host_.get()) { + std::string dir_path = path_; + if (dir_path.empty() || dir_path[dir_path.size() - 1] != '/') + dir_path += '/'; + + for (fileapi::FileSystemOperation::FileEntryList::const_iterator it = + file_list.begin(); it != file_list.end(); ++it) { + if (it->is_directory) + file_types.push_back(PP_FILETYPE_DIRECTORY); + else + file_types.push_back(PP_FILETYPE_REGULAR); + + ppapi::FileRef_CreateInfo info; + info.file_system_type = fs_type_; + info.file_system_plugin_resource = fs_host_->pp_resource(); + std::string path = + dir_path + fileapi::FilePathToString(base::FilePath(it->name)); + info.internal_path = path; + info.display_name = ppapi::GetNameForInternalFilePath(path); + infos.push_back(info); + } + } + + host_->SendReply(context, + PpapiPluginMsg_FileRef_ReadDirectoryEntriesReply(infos, file_types)); +} + +int32_t PepperInternalFileRefBackend::GetAbsolutePath( + ppapi::host::ReplyMessageContext reply_context) { + host_->SendReply(reply_context, + PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_)); + return PP_OK_COMPLETIONPENDING; +} + +bool PepperInternalFileRefBackend::HasPermissionsForFile( + const fileapi::FileSystemURL& url, + int permissions, + base::PlatformFileError* error) const { + return CheckFileSystemPermissionsForProcess(GetFileSystemContext(), + render_process_id_, + url, + permissions, + error); +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h new file mode 100644 index 0000000..9aa904c --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h @@ -0,0 +1,84 @@ +// Copyright 2013 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_INTERNAL_FILE_REF_BACKEND_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_INTERNAL_FILE_REF_BACKEND_H_ + +#include <string> + +#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_time.h" +#include "ppapi/host/ppapi_host.h" +#include "webkit/browser/fileapi/file_system_context.h" +#include "webkit/browser/fileapi/file_system_operation.h" +#include "webkit/browser/fileapi/file_system_url.h" + +namespace content { + +// Implementations of FileRef operations for internal filesystems. +class PepperInternalFileRefBackend : public PepperFileRefBackend { + public: + PepperInternalFileRefBackend( + ppapi::host::PpapiHost* host, + int render_process_id, + base::WeakPtr<PepperFileSystemBrowserHost> fs_host, + const std::string& path); + virtual ~PepperInternalFileRefBackend(); + + // PepperFileRefBackend overrides. + virtual int32_t MakeDirectory(ppapi::host::ReplyMessageContext context, + bool make_ancestors) OVERRIDE; + virtual int32_t Touch(ppapi::host::ReplyMessageContext context, + PP_Time last_accessed_time, + PP_Time last_modified_time) OVERRIDE; + virtual int32_t Delete(ppapi::host::ReplyMessageContext context) OVERRIDE; + virtual int32_t Rename(ppapi::host::ReplyMessageContext context, + PP_Resource new_file_ref) OVERRIDE; + virtual int32_t Query(ppapi::host::ReplyMessageContext context) OVERRIDE; + virtual int32_t ReadDirectoryEntries( + ppapi::host::ReplyMessageContext context) OVERRIDE; + virtual int32_t GetAbsolutePath(ppapi::host::ReplyMessageContext context) + OVERRIDE; + + virtual fileapi::FileSystemURL GetFileSystemURL() const OVERRIDE; + + private: + // Generic reply callback. + void DidFinish(ppapi::host::ReplyMessageContext reply_context, + const IPC::Message& msg, + base::PlatformFileError error); + + // Operation specific callbacks. + void GetMetadataComplete( + ppapi::host::ReplyMessageContext reply_context, + base::PlatformFileError error, + const base::PlatformFileInfo& file_info); + void ReadDirectoryComplete( + ppapi::host::ReplyMessageContext context, + base::PlatformFileError error, + const fileapi::FileSystemOperation::FileEntryList& file_list, + bool has_more); + + scoped_refptr<fileapi::FileSystemContext> GetFileSystemContext() const; + + bool HasPermissionsForFile(const fileapi::FileSystemURL& url, + int permissions, + base::PlatformFileError* error) const; + + ppapi::host::PpapiHost* host_; + int render_process_id_; + base::WeakPtr<PepperFileSystemBrowserHost> fs_host_; + PP_FileSystemType fs_type_; + std::string path_; + + mutable fileapi::FileSystemURL fs_url_; + + base::WeakPtrFactory<PepperInternalFileRefBackend> weak_factory_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_INTERNAL_FILE_REF_BACKEND_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index cbaad69..78d1cda 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -828,12 +828,18 @@ 'browser/renderer_host/pepper/content_browser_pepper_host_factory.h', 'browser/renderer_host/pepper/pepper_browser_font_singleton_host.cc', 'browser/renderer_host/pepper/pepper_browser_font_singleton_host.h', + 'browser/renderer_host/pepper/pepper_file_ref_host.cc', + 'browser/renderer_host/pepper/pepper_file_ref_host.h', + 'browser/renderer_host/pepper/pepper_file_system_browser_host.cc', + 'browser/renderer_host/pepper/pepper_file_system_browser_host.h', 'browser/renderer_host/pepper/pepper_flash_file_message_filter.cc', 'browser/renderer_host/pepper/pepper_flash_file_message_filter.h', 'browser/renderer_host/pepper/pepper_gamepad_host.cc', 'browser/renderer_host/pepper/pepper_gamepad_host.h', 'browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc', 'browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.h', + 'browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc', + 'browser/renderer_host/pepper/pepper_internal_file_ref_backend.h', 'browser/renderer_host/pepper/pepper_lookup_request.h', 'browser/renderer_host/pepper/pepper_message_filter.cc', 'browser/renderer_host/pepper/pepper_message_filter.h', diff --git a/content/renderer/pepper/pepper_file_system_host.cc b/content/renderer/pepper/pepper_file_system_host.cc index e4c9d93..6ec8eca 100644 --- a/content/renderer/pepper/pepper_file_system_host.cc +++ b/content/renderer/pepper/pepper_file_system_host.cc @@ -142,6 +142,7 @@ int32_t PepperFileSystemHost::OnHostMsgOpen( int32_t PepperFileSystemHost::OnHostMsgInitIsolatedFileSystem( ppapi::host::HostMessageContext* context, const std::string& fsid) { + called_open_ = true; // Do a sanity check. if (!LooksLikeAGuid(fsid)) return PP_ERROR_BADARGUMENT; diff --git a/ppapi/host/resource_host.cc b/ppapi/host/resource_host.cc index 96d8849..6e08c01 100644 --- a/ppapi/host/resource_host.cc +++ b/ppapi/host/resource_host.cc @@ -48,6 +48,15 @@ void ResourceHost::SendReply(const ReplyMessageContext& context, host_->SendReply(context, msg); } +content::PepperFileRefHost* ResourceHost::AsPepperFileRefHost() { + return NULL; +} + +content::PepperFileSystemBrowserHost* +ResourceHost::AsPepperFileSystemBrowserHost() { + return NULL; +} + content::PepperFileSystemHost* ResourceHost::AsPepperFileSystemHost() { return NULL; } diff --git a/ppapi/host/resource_host.h b/ppapi/host/resource_host.h index 583766e..2c40f62 100644 --- a/ppapi/host/resource_host.h +++ b/ppapi/host/resource_host.h @@ -15,6 +15,8 @@ #include "ppapi/shared_impl/host_resource.h" namespace content { +class PepperFileRefHost; +class PepperFileSystemBrowserHost; class PepperFileSystemHost; class PepperGraphics2DHost; } @@ -60,6 +62,8 @@ class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler { const IPC::Message& msg) OVERRIDE; // Simple RTTI. Overidden by subclasses that implement the interface. + virtual content::PepperFileRefHost* AsPepperFileRefHost(); + virtual content::PepperFileSystemBrowserHost* AsPepperFileSystemBrowserHost(); virtual content::PepperFileSystemHost* AsPepperFileSystemHost(); virtual content::PepperGraphics2DHost* AsPepperGraphics2DHost(); diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index 23c9dd1..7a26be8 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -23,6 +23,7 @@ 'shared_impl/file_io_state_manager.h', 'shared_impl/file_path.cc', 'shared_impl/file_path.h', + 'shared_impl/file_ref_create_info.h', 'shared_impl/file_ref_util.cc', 'shared_impl/file_ref_util.h', 'shared_impl/file_type_conversion.cc', diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index a54a9560..99691f0e 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -195,6 +195,15 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::DirEntry) IPC_STRUCT_TRAITS_MEMBER(is_dir) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ppapi::FileRef_CreateInfo) + IPC_STRUCT_TRAITS_MEMBER(file_system_type) + IPC_STRUCT_TRAITS_MEMBER(internal_path) + IPC_STRUCT_TRAITS_MEMBER(external_path) + IPC_STRUCT_TRAITS_MEMBER(display_name) + IPC_STRUCT_TRAITS_MEMBER(pending_host_resource_id) + IPC_STRUCT_TRAITS_MEMBER(file_system_plugin_resource) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(ppapi::FlashSiteSetting) IPC_STRUCT_TRAITS_MEMBER(site) IPC_STRUCT_TRAITS_MEMBER(permission) @@ -472,6 +481,8 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, ppapi::proxy::SerializedHandle /* handle */) // PPB_FileRef. +// TODO(teravest): Remove these messages when we've switched over to the "new" +// proxy. IPC_MESSAGE_ROUTED3( PpapiMsg_PPBFileRef_CallbackComplete, ppapi::HostResource /* resource */, @@ -806,6 +817,8 @@ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_ReleaseResource, ppapi::HostResource) // PPB_FileRef. +// TODO(teravest): Remove these messages when we've switched over to the "new" +// proxy. IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBFileRef_Create, PP_Instance /* instance */, PP_Resource /* file_system */, @@ -1400,6 +1413,57 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_RequestOSFileHandle) IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_RequestOSFileHandleReply) IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_GeneralReply) +// FileRef +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileRef_CreateInternal, + PP_Resource /* file_system */, + std::string /* internal_path */) + +// Requests that the browser create a directory at the location indicated by +// the FileRef. +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileRef_MakeDirectory, + bool /* make_ancestors */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileRef_MakeDirectoryReply) + +// Requests that the browser update the last accessed and last modified times +// at the location indicated by the FileRef. +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileRef_Touch, + PP_Time /* last_accessed */, + PP_Time /* last_modified */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileRef_TouchReply) + +// Requests that the browser delete a file or directory at the location +// indicated by the FileRef. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileRef_Delete) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileRef_DeleteReply) + +// Requests that the browser rename a file or directory at the location +// indicated by the FileRef. +IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileRef_Rename, + PP_Resource /* new_file_ref */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileRef_RenameReply) + +// Requests that the browser retrieve metadata information for a file or +// directory at the location indicated by the FileRef. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileRef_Query) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileRef_QueryReply, + PP_FileInfo /* file_info */) + +// Requests that the browser retrieve then entries in a directory at the +// location indicated by the FileRef. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileRef_ReadDirectoryEntries) + +// FileRef_CreateInfo does not provide file type information, so two +// corresponding vectors are returned. +IPC_MESSAGE_CONTROL2(PpapiPluginMsg_FileRef_ReadDirectoryEntriesReply, + std::vector<ppapi::FileRef_CreateInfo> /* files */, + std::vector<PP_FileType> /* file_types */) + +// Requests that the browser reply with the absolute path to the indicated +// file. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileRef_GetAbsolutePath) +IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileRef_GetAbsolutePathReply, + std::string /* absolute_path */) + // FileSystem IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileSystem_Create, PP_FileSystemType /* type */) diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc index c3197a9..564eacc 100644 --- a/ppapi/proxy/ppapi_param_traits.cc +++ b/ppapi/proxy/ppapi_param_traits.cc @@ -175,6 +175,7 @@ void ParamTraits<PP_NetAddress_Private>::Log(const param_type& p, l->append(" bytes)>"); } +// TODO(teravest): Remove this when FileRef is moved to the "new" proxy. // PPB_FileRef_CreateInfo ------------------------------------------------------ // static diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h index 196ef9e..95a64f1 100644 --- a/ppapi/proxy/ppapi_param_traits.h +++ b/ppapi/proxy/ppapi_param_traits.h @@ -15,6 +15,7 @@ #include "ppapi/c/pp_var.h" #include "ppapi/proxy/ppapi_proxy_export.h" #include "ppapi/shared_impl/file_path.h" +#include "ppapi/shared_impl/file_ref_create_info.h" #include "ppapi/shared_impl/ppapi_permissions.h" #include "ppapi/shared_impl/ppb_file_ref_shared.h" @@ -75,6 +76,7 @@ struct PPAPI_PROXY_EXPORT ParamTraits< static void Log(const param_type& p, std::string* l); }; +// TODO(teravest): Remove this when we've switched over to the new proxy. template<> struct PPAPI_PROXY_EXPORT ParamTraits<ppapi::PPB_FileRef_CreateInfo> { typedef ppapi::PPB_FileRef_CreateInfo param_type; diff --git a/ppapi/shared_impl/file_ref_create_info.h b/ppapi/shared_impl/file_ref_create_info.h new file mode 100644 index 0000000..edf6eef --- /dev/null +++ b/ppapi/shared_impl/file_ref_create_info.h @@ -0,0 +1,34 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_FILE_REF_CREATE_INFO_H +#define PPAPI_SHARED_IMPL_FILE_REF_CREATE_INFO_H + +#include <string> + +#include "base/files/file_path.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_resource.h" + +namespace ppapi { + +// FileRefs are created in a number of places and they include a number of +// return values. This struct encapsulates everything in one place. +struct FileRef_CreateInfo { + PP_FileSystemType file_system_type; + std::string internal_path; + base::FilePath external_path; + std::string display_name; + + // Used when a FileRef is created in the Renderer. + int pending_host_resource_id; + + // Since FileRef needs to hold a FileSystem reference, we need to pass the + // resource in this CreateInfo. + PP_Resource file_system_plugin_resource; +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_FILE_REF_CREATE_INFO_H diff --git a/ppapi/shared_impl/file_ref_util.cc b/ppapi/shared_impl/file_ref_util.cc index 16ed060..ff2e362 100644 --- a/ppapi/shared_impl/file_ref_util.cc +++ b/ppapi/shared_impl/file_ref_util.cc @@ -35,16 +35,9 @@ bool IsValidInternalPath(const std::string& path) { // The path starts with '/' // The path must contain valid UTF-8 characters. // It must not FilePath::ReferencesParent(). - if (path.empty() || path[0] != '/') + if (path.empty() || !IsStringUTF8(path) || path[0] != '/') return false; - if (!IsStringUTF8(path)) - return false; -#if defined(OS_WIN) - base::FilePath::StringType path_win(path.begin(), path.end()); - base::FilePath file_path(path_win); -#else - base::FilePath file_path(path); -#endif + base::FilePath file_path = base::FilePath::FromUTF8Unsafe(path); if (file_path.ReferencesParent()) return false; return true; diff --git a/ppapi/shared_impl/file_ref_util.h b/ppapi/shared_impl/file_ref_util.h index 7633916..11f03ad 100644 --- a/ppapi/shared_impl/file_ref_util.h +++ b/ppapi/shared_impl/file_ref_util.h @@ -8,18 +8,21 @@ #include <string> #include "base/files/file_path.h" +#include "ppapi/shared_impl/ppapi_shared_export.h" namespace ppapi { // Routines to generate display names for internal and external file paths. -std::string GetNameForInternalFilePath(const std::string& path); -std::string GetNameForExternalFilePath(const base::FilePath& path); +PPAPI_SHARED_EXPORT std::string GetNameForInternalFilePath( + const std::string& path); +PPAPI_SHARED_EXPORT std::string GetNameForExternalFilePath( + const base::FilePath& path); // Determines whether an internal file path is valid. -bool IsValidInternalPath(const std::string& path); +PPAPI_SHARED_EXPORT bool IsValidInternalPath(const std::string& path); // If path ends with a slash, normalize it away unless it's the root path. -void NormalizeInternalPath(std::string* path); +PPAPI_SHARED_EXPORT void NormalizeInternalPath(std::string* path); } // namespace ppapi |