diff options
72 files changed, 2134 insertions, 653 deletions
diff --git a/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc b/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc index 4d9a24c..ca59c7ef 100644 --- a/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc +++ b/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc @@ -12,6 +12,7 @@ #include "ppapi/host/host_message_context.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" namespace chrome { @@ -27,8 +28,7 @@ PepperFlashDRMRendererHost::PepperFlashDRMRendererHost( PP_Instance instance, PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), - renderer_ppapi_host_(host), - weak_factory_(this) { + renderer_ppapi_host_(host) { } PepperFlashDRMRendererHost::~PepperFlashDRMRendererHost() { @@ -56,43 +56,13 @@ int32_t PepperFlashDRMRendererHost::OnGetVoucherFile( base::FilePath voucher_file = plugin_dir.Append( base::FilePath(kVoucherFilename)); - int renderer_pending_host_id = - plugin_instance->MakePendingFileRefRendererHost(voucher_file); - if (renderer_pending_host_id == 0) - return PP_ERROR_FAILED; - - std::vector<IPC::Message> create_msgs; - create_msgs.push_back(PpapiHostMsg_FileRef_CreateExternal(voucher_file)); - - renderer_ppapi_host_->CreateBrowserResourceHosts( - pp_instance(), - create_msgs, - base::Bind(&PepperFlashDRMRendererHost::DidCreateFileRefHosts, - weak_factory_.GetWeakPtr(), - context->MakeReplyMessageContext(), - voucher_file, - renderer_pending_host_id)); - return PP_OK_COMPLETIONPENDING; -} - -void PepperFlashDRMRendererHost::DidCreateFileRefHosts( - const ppapi::host::ReplyMessageContext& reply_context, - const base::FilePath& external_path, - int renderer_pending_host_id, - const std::vector<int>& browser_pending_host_ids) { - DCHECK(browser_pending_host_ids.size() == 1); - - int browser_pending_host_id = 0; - if (browser_pending_host_ids.size() == 1) - browser_pending_host_id = browser_pending_host_ids[0]; - - ppapi::FileRefCreateInfo create_info = - ppapi::MakeExternalFileRefCreateInfo(external_path, - std::string(), - browser_pending_host_id, - renderer_pending_host_id); - host()->SendReply(reply_context, - PpapiPluginMsg_FlashDRM_GetVoucherFileReply(create_info)); + ppapi::PPB_FileRef_CreateInfo create_info; + ppapi::proxy::PPB_FileRef_Proxy::SerializeFileRef( + plugin_instance->CreateExternalFileReference(voucher_file), + &create_info); + context->reply_msg = + PpapiPluginMsg_FlashDRM_GetVoucherFileReply(create_info); + return PP_OK; } } // namespace chrome diff --git a/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h b/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h index 73f67dc..f7247d6 100644 --- a/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h +++ b/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h @@ -7,13 +7,8 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "base/memory/weak_ptr.h" #include "ppapi/host/resource_host.h" -namespace base { -class FilePath; -} - namespace content { class RendererPpapiHost; } @@ -36,17 +31,9 @@ class PepperFlashDRMRendererHost : public ppapi::host::ResourceHost { private: int32_t OnGetVoucherFile(ppapi::host::HostMessageContext* context); - void DidCreateFileRefHosts( - const ppapi::host::ReplyMessageContext& reply_context, - const base::FilePath& external_path, - int renderer_pending_host_id, - const std::vector<int>& browser_pending_host_ids); - // Non-owning pointer. content::RendererPpapiHost* renderer_ppapi_host_; - base::WeakPtrFactory<PepperFlashDRMRendererHost> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(PepperFlashDRMRendererHost); }; diff --git a/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc b/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc index 096b908..27ba37d 100644 --- a/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc +++ b/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.cc @@ -90,16 +90,21 @@ int32_t PepperExternalFileRefBackend::GetAbsolutePath( ppapi::host::ReplyMessageContext reply_context) { host_->SendReply(reply_context, PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_.AsUTF8Unsafe())); - - // Use PP_OK_COMPLETIONPENDING instead of PP_OK since we've already sent our - // reply above. - return PP_OK_COMPLETIONPENDING; + return PP_OK; } fileapi::FileSystemURL PepperExternalFileRefBackend::GetFileSystemURL() const { return fileapi::FileSystemURL(); } +std::string PepperExternalFileRefBackend::GetFileSystemURLSpec() const { + return std::string(); +} + +base::FilePath PepperExternalFileRefBackend::GetExternalPath() const { + return path_; +} + int32_t PepperExternalFileRefBackend::CanRead() const { if (!ChildProcessSecurityPolicyImpl::GetInstance()-> CanReadFile(render_process_id_, path_)) { diff --git a/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h b/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h index cbfaf6e..e999579 100644 --- a/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h +++ b/content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h @@ -41,6 +41,8 @@ class PepperExternalFileRefBackend : public PepperFileRefBackend { virtual int32_t GetAbsolutePath(ppapi::host::ReplyMessageContext context) OVERRIDE; virtual fileapi::FileSystemURL GetFileSystemURL() const OVERRIDE; + virtual std::string GetFileSystemURLSpec() const OVERRIDE; + virtual base::FilePath GetExternalPath() const OVERRIDE; virtual int32_t CanRead() const OVERRIDE; virtual int32_t CanWrite() const OVERRIDE; diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.cc b/content/browser/renderer_host/pepper/pepper_file_ref_host.cc index c38f882..5370af9 100644 --- a/content/browser/renderer_host/pepper/pepper_file_ref_host.cc +++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.cc @@ -62,9 +62,9 @@ PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host, } fs_type_ = fs_host->GetType(); + // TODO(teravest): Add support for isolated filesystems. if ((fs_type_ != PP_FILESYSTEMTYPE_LOCALPERSISTENT) && - (fs_type_ != PP_FILESYSTEMTYPE_LOCALTEMPORARY) && - (fs_type_ != PP_FILESYSTEMTYPE_ISOLATED)) { + (fs_type_ != PP_FILESYSTEMTYPE_LOCALTEMPORARY)) { DLOG(ERROR) << "Unsupported filesystem type: " << fs_type_; return; } @@ -116,6 +116,18 @@ fileapi::FileSystemURL PepperFileRefHost::GetFileSystemURL() const { return fileapi::FileSystemURL(); } +std::string PepperFileRefHost::GetFileSystemURLSpec() const { + if (backend_) + return backend_->GetFileSystemURLSpec(); + return std::string(); +} + +base::FilePath PepperFileRefHost::GetExternalPath() const { + if (backend_) + return backend_->GetExternalPath(); + return base::FilePath(); +} + int32_t PepperFileRefHost::CanRead() const { if (backend_) return backend_->CanRead(); diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.h b/content/browser/renderer_host/pepper/pepper_file_ref_host.h index b97ff33..5d76576 100644 --- a/content/browser/renderer_host/pepper/pepper_file_ref_host.h +++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.h @@ -42,6 +42,8 @@ class PepperFileRefBackend { virtual int32_t GetAbsolutePath( ppapi::host::ReplyMessageContext context) = 0; virtual fileapi::FileSystemURL GetFileSystemURL() const = 0; + virtual std::string GetFileSystemURLSpec() const = 0; + virtual base::FilePath GetExternalPath() const = 0; // Returns an error from the pp_errors.h enum. virtual int32_t CanRead() const = 0; @@ -77,6 +79,10 @@ class CONTENT_EXPORT PepperFileRefHost PP_FileSystemType GetFileSystemType() const; fileapi::FileSystemURL GetFileSystemURL() const; + // Required to support FileIO. + std::string GetFileSystemURLSpec() const; + base::FilePath GetExternalPath() const; + int32_t CanRead() const; int32_t CanWrite() const; int32_t CanCreate() const; 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 index 3b8c801..0c3bd89 100644 --- a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc +++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc @@ -71,6 +71,19 @@ fileapi::FileSystemURL PepperInternalFileRefBackend::GetFileSystemURL() const { return fs_url_; } +std::string PepperInternalFileRefBackend::GetFileSystemURLSpec() const { + if (fs_host_.get() && fs_host_->IsOpened() && + fs_host_->GetRootUrl().is_valid()) { + return fs_host_->GetRootUrl().Resolve( + net::EscapePath(path_.substr(1))).spec(); + } + return std::string(); +} + +base::FilePath PepperInternalFileRefBackend::GetExternalPath() const { + return base::FilePath(); +} + scoped_refptr<fileapi::FileSystemContext> PepperInternalFileRefBackend::GetFileSystemContext() const { if (!fs_host_.get()) @@ -210,7 +223,7 @@ void PepperInternalFileRefBackend::ReadDirectoryComplete( context.params.set_result(ppapi::PlatformFileErrorToPepperError(error)); - std::vector<ppapi::FileRefCreateInfo> infos; + 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_; @@ -224,7 +237,7 @@ void PepperInternalFileRefBackend::ReadDirectoryComplete( else file_types.push_back(PP_FILETYPE_REGULAR); - ppapi::FileRefCreateInfo info; + ppapi::FileRef_CreateInfo info; info.file_system_type = fs_type_; info.file_system_plugin_resource = fs_host_->pp_resource(); std::string path = 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 index 81d6ab6..197a1bc 100644 --- a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h +++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h @@ -46,6 +46,8 @@ class PepperInternalFileRefBackend : public PepperFileRefBackend { OVERRIDE; virtual fileapi::FileSystemURL GetFileSystemURL() const OVERRIDE; + virtual std::string GetFileSystemURLSpec() const OVERRIDE; + virtual base::FilePath GetExternalPath() const OVERRIDE; virtual int32_t CanRead() const OVERRIDE; virtual int32_t CanWrite() const OVERRIDE; diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc index e4c8aa7..b2232fd0 100644 --- a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc @@ -16,7 +16,6 @@ #include "ppapi/host/resource_host.h" #include "ppapi/proxy/ppapi_message_utils.h" #include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/proxy/ppapi_message_utils.h" #include "ppapi/proxy/resource_message_params.h" namespace content { @@ -74,6 +73,8 @@ bool PepperRendererConnection::OnMessageReceived(const IPC::Message& msg, IPC_BEGIN_MESSAGE_MAP_EX(PepperRendererConnection, msg, *message_was_ok) IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostsFromHost, OnMsgCreateResourceHostsFromHost) + IPC_MESSAGE_HANDLER(PpapiHostMsg_FileRef_GetInfoForRenderer, + OnMsgFileRefGetInfoForRenderer) IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateInProcessInstance, OnMsgDidCreateInProcessInstance) IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteInProcessInstance, @@ -128,6 +129,40 @@ void PepperRendererConnection::OnMsgCreateResourceHostsFromHost( routing_id, params.sequence(), pending_resource_host_ids)); } +void PepperRendererConnection::OnMsgFileRefGetInfoForRenderer( + int routing_id, + int child_process_id, + int32_t sequence, + const std::vector<PP_Resource>& resources) { + std::vector<PP_Resource> out_resources; + std::vector<PP_FileSystemType> fs_types; + std::vector<std::string> file_system_url_specs; + std::vector<base::FilePath> external_paths; + + BrowserPpapiHostImpl* host = GetHostForChildProcess(child_process_id); + if (host) { + for (size_t i = 0; i < resources.size(); ++i) { + ppapi::host::ResourceHost* resource_host = + host->GetPpapiHost()->GetResourceHost(resources[i]); + if (resource_host && resource_host->IsFileRefHost()) { + PepperFileRefHost* file_ref_host = + static_cast<PepperFileRefHost*>(resource_host); + out_resources.push_back(resources[i]); + fs_types.push_back(file_ref_host->GetFileSystemType()); + file_system_url_specs.push_back(file_ref_host->GetFileSystemURLSpec()); + external_paths.push_back(file_ref_host->GetExternalPath()); + } + } + } + Send(new PpapiHostMsg_FileRef_GetInfoForRendererReply( + routing_id, + sequence, + out_resources, + fs_types, + file_system_url_specs, + external_paths)); +} + void PepperRendererConnection::OnMsgDidCreateInProcessInstance( PP_Instance instance, const PepperRendererInstanceData& instance_data) { diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.h b/content/browser/renderer_host/pepper/pepper_renderer_connection.h index 157827a..24cbc2c 100644 --- a/content/browser/renderer_host/pepper/pepper_renderer_connection.h +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.h @@ -54,6 +54,12 @@ class PepperRendererConnection : public BrowserMessageFilter { PP_Instance instance, const std::vector<IPC::Message>& nested_msgs); + void OnMsgFileRefGetInfoForRenderer( + int routing_id, + int child_process_id, + int32_t sequence_num, + const std::vector<PP_Resource>& resources); + void OnMsgDidCreateInProcessInstance( PP_Instance instance, const PepperRendererInstanceData& instance_data); diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 620fcb2..2b45e31 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -302,8 +302,6 @@ 'renderer/pepper/pepper_file_chooser_host.h', 'renderer/pepper/pepper_file_io_host.cc', 'renderer/pepper/pepper_file_io_host.h', - 'renderer/pepper/pepper_file_ref_renderer_host.cc', - 'renderer/pepper/pepper_file_ref_renderer_host.h', 'renderer/pepper/pepper_file_system_host.cc', 'renderer/pepper/pepper_file_system_host.h', 'renderer/pepper/pepper_graphics_2d_host.cc', @@ -355,6 +353,8 @@ 'renderer/pepper/ppb_broker_impl.h', 'renderer/pepper/ppb_buffer_impl.cc', 'renderer/pepper/ppb_buffer_impl.h', + 'renderer/pepper/ppb_file_ref_impl.cc', + 'renderer/pepper/ppb_file_ref_impl.h', 'renderer/pepper/ppb_flash_message_loop_impl.cc', 'renderer/pepper/ppb_flash_message_loop_impl.h', 'renderer/pepper/ppb_graphics_3d_impl.cc', diff --git a/content/public/renderer/pepper_plugin_instance.h b/content/public/renderer/pepper_plugin_instance.h index 834a55b..211752d 100644 --- a/content/public/renderer/pepper_plugin_instance.h +++ b/content/public/renderer/pepper_plugin_instance.h @@ -56,6 +56,11 @@ class PepperPluginInstance { // Returns the location of this module. virtual base::FilePath GetModulePath() = 0; + // Returns a reference to a file with the given path. + // The returned object will have a refcount of 0 (just like "new"). + virtual PP_Resource CreateExternalFileReference( + const base::FilePath& external_file_path) = 0; + // Creates a PPB_ImageData given a Skia image. virtual PP_Resource CreateImage(gfx::ImageSkia* source_image, float scale) = 0; @@ -88,8 +93,6 @@ class PepperPluginInstance { const char* target, bool from_user_action) = 0; - // Creates a pending PepperFileRefRendererHost. Returns 0 on failure. - virtual int MakePendingFileRefRendererHost(const base::FilePath& path) = 0; }; } // namespace content diff --git a/content/public/renderer/renderer_ppapi_host.h b/content/public/renderer/renderer_ppapi_host.h index 88a863fd..1275429 100644 --- a/content/public/renderer/renderer_ppapi_host.h +++ b/content/public/renderer/renderer_ppapi_host.h @@ -49,11 +49,6 @@ class RendererPpapiHost { public: // Returns the RendererPpapiHost associated with the given PP_Instance, // or NULL if the instance is invalid. - // - // Do NOT use this when dealing with an "external plugin" that serves as a - // bootstrap to load a second plugin. This is because the two will share a - // PP_Instance, and the RendererPpapiHost* for the second plugin will be - // returned after we switch the proxy on. CONTENT_EXPORT static RendererPpapiHost* GetForPPInstance( PP_Instance instance); diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc index 0b59503..983e185 100644 --- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc +++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc @@ -11,7 +11,6 @@ #include "content/renderer/pepper/pepper_audio_input_host.h" #include "content/renderer/pepper/pepper_file_chooser_host.h" #include "content/renderer/pepper/pepper_file_io_host.h" -#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_file_system_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "content/renderer/pepper/pepper_truetype_font_host.h" @@ -76,18 +75,6 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( case PpapiHostMsg_FileIO_Create::ID: return scoped_ptr<ResourceHost>(new PepperFileIOHost( 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 PepperFileRefRendererHost( - host_, instance, params.pp_resource(), file_system, internal_path)); - } case PpapiHostMsg_FileSystem_Create::ID: { PP_FileSystemType file_system_type; if (!UnpackMessage<PpapiHostMsg_FileSystem_Create>(message, diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.cc b/content/renderer/pepper/mock_renderer_ppapi_host.cc index b0ee2a7..8000d40 100644 --- a/content/renderer/pepper/mock_renderer_ppapi_host.cc +++ b/content/renderer/pepper/mock_renderer_ppapi_host.cc @@ -80,9 +80,10 @@ bool MockRendererPpapiHost::IsRunningInProcess() const { void MockRendererPpapiHost::CreateBrowserResourceHosts( PP_Instance instance, - const std::vector<IPC::Message>& nested_msgs, + const std::vector<IPC::Message>& nested_msg, const base::Callback<void(const std::vector<int>&)>& callback) const { - callback.Run(std::vector<int>(nested_msgs.size(), 0)); + NOTIMPLEMENTED(); + callback.Run(std::vector<int>()); return; } diff --git a/content/renderer/pepper/pepper_browser_connection.cc b/content/renderer/pepper/pepper_browser_connection.cc index 803f3df..6bbec3d 100644 --- a/content/renderer/pepper/pepper_browser_connection.cc +++ b/content/renderer/pepper/pepper_browser_connection.cc @@ -36,6 +36,7 @@ bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) { OnMsgCreateResourceHostsFromHostReply) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() + return handled; } @@ -73,6 +74,16 @@ void PepperBrowserConnection::SendBrowserCreate( nested_msgs)); } +void PepperBrowserConnection::SendBrowserFileRefGetInfo( + int child_process_id, + const std::vector<PP_Resource>& resources, + const FileRefGetInfoCallback& callback) { + int32_t sequence_number = GetNextSequence(); + get_info_map_[sequence_number] = callback; + Send(new PpapiHostMsg_FileRef_GetInfoForRenderer( + routing_id(), child_process_id, sequence_number, resources)); +} + void PepperBrowserConnection::OnMsgCreateResourceHostsFromHostReply( int32_t sequence_number, const std::vector<int>& pending_resource_host_ids) { @@ -88,6 +99,25 @@ void PepperBrowserConnection::OnMsgCreateResourceHostsFromHostReply( } } +void PepperBrowserConnection::OnMsgFileRefGetInfoReply( + int32_t sequence_number, + const std::vector<PP_Resource>& resources, + const std::vector<PP_FileSystemType>& types, + const std::vector<std::string>& file_system_url_specs, + const std::vector<base::FilePath>& external_paths) { + // Check that the message is destined for the plugin this object is associated + // with. + std::map<int32_t, FileRefGetInfoCallback>::iterator it = + get_info_map_.find(sequence_number); + if (it != get_info_map_.end()) { + FileRefGetInfoCallback callback = it->second; + get_info_map_.erase(it); + callback.Run(resources, types, file_system_url_specs, external_paths); + } else { + NOTREACHED(); + } +} + int32_t PepperBrowserConnection::GetNextSequence() { // Return the value with wraparound, making sure we don't make a sequence // number with a 0 ID. Note that signed wraparound is undefined in C++ so we diff --git a/content/renderer/pepper/pepper_browser_connection.h b/content/renderer/pepper/pepper_browser_connection.h index bef0ba2..ab43409 100644 --- a/content/renderer/pepper/pepper_browser_connection.h +++ b/content/renderer/pepper/pepper_browser_connection.h @@ -29,6 +29,12 @@ class PepperBrowserConnection public: typedef base::Callback<void(const std::vector<int>&)> PendingResourceIDCallback; + typedef base::Callback<void( + const std::vector<PP_Resource>&, + const std::vector<PP_FileSystemType>&, + const std::vector<std::string>&, + const std::vector<base::FilePath>&)> FileRefGetInfoCallback; + explicit PepperBrowserConnection(RenderView* render_view); virtual ~PepperBrowserConnection(); @@ -45,6 +51,13 @@ class PepperBrowserConnection const std::vector<IPC::Message>& create_messages, const PendingResourceIDCallback& callback); + // Sends a request to the browser to get information about the given FileRef + // |resource|. |callback| will be run when a reply is received with the + // file information. + void SendBrowserFileRefGetInfo(int child_process_id, + const std::vector<PP_Resource>& resource, + const FileRefGetInfoCallback& callback); + // Called when the renderer creates an in-process instance. void DidCreateInProcessInstance(PP_Instance instance, int render_view_id, @@ -59,6 +72,12 @@ class PepperBrowserConnection void OnMsgCreateResourceHostsFromHostReply( int32_t sequence_number, const std::vector<int>& pending_resource_host_ids); + void OnMsgFileRefGetInfoReply( + int32_t sequence_number, + const std::vector<PP_Resource>& resources, + const std::vector<PP_FileSystemType>& types, + const std::vector<std::string>& file_system_url_specs, + const std::vector<base::FilePath>& external_paths); // Return the next sequence number. int32_t GetNextSequence(); @@ -68,6 +87,7 @@ class PepperBrowserConnection // Maps a sequence number to the callback to be run. std::map<int32_t, PendingResourceIDCallback> pending_create_map_; + std::map<int32_t, FileRefGetInfoCallback> get_info_map_; DISALLOW_COPY_AND_ASSIGN(PepperBrowserConnection); }; diff --git a/content/renderer/pepper/pepper_file_chooser_host.cc b/content/renderer/pepper/pepper_file_chooser_host.cc index e73694a..1229d17 100644 --- a/content/renderer/pepper/pepper_file_chooser_host.cc +++ b/content/renderer/pepper/pepper_file_chooser_host.cc @@ -7,12 +7,13 @@ #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" #include "content/public/renderer/renderer_ppapi_host.h" -#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" +#include "content/renderer/pepper/ppb_file_ref_impl.h" #include "content/renderer/render_view_impl.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/proxy/ppb_file_ref_proxy.h" #include "third_party/WebKit/public/platform/WebCString.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebVector.h" @@ -80,8 +81,7 @@ PepperFileChooserHost::PepperFileChooserHost( PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), - handler_(NULL), - weak_factory_(this) { + handler_(NULL) { } PepperFileChooserHost::~PepperFileChooserHost() { @@ -98,36 +98,29 @@ int32_t PepperFileChooserHost::OnResourceMessageReceived( void PepperFileChooserHost::StoreChosenFiles( const std::vector<ChosenFileInfo>& files) { - std::vector<IPC::Message> create_msgs; - std::vector<base::FilePath> file_paths; - std::vector<std::string> display_names; + std::vector<ppapi::PPB_FileRef_CreateInfo> chosen_files; for (size_t i = 0; i < files.size(); i++) { #if defined(OS_WIN) base::FilePath file_path(UTF8ToWide(files[i].path)); #else base::FilePath file_path(files[i].path); #endif - file_paths.push_back(file_path); - create_msgs.push_back(PpapiHostMsg_FileRef_CreateExternal(file_path)); - display_names.push_back(files[i].display_name); - } - if (!files.empty()) { - renderer_ppapi_host_->CreateBrowserResourceHosts( - pp_instance(), - create_msgs, - base::Bind(&PepperFileChooserHost::DidCreateResourceHosts, - weak_factory_.GetWeakPtr(), - file_paths, - display_names)); - } else { - reply_context_.params.set_result(PP_ERROR_USERCANCEL); - std::vector<ppapi::FileRefCreateInfo> chosen_files; - host()->SendReply(reply_context_, - PpapiPluginMsg_FileChooser_ShowReply(chosen_files)); - reply_context_ = ppapi::host::ReplyMessageContext(); - handler_ = NULL; // Handler deletes itself. + PPB_FileRef_Impl* ref = PPB_FileRef_Impl::CreateExternal( + pp_instance(), file_path, files[i].display_name); + ppapi::PPB_FileRef_CreateInfo create_info; + ppapi::proxy::PPB_FileRef_Proxy::SerializeFileRef(ref->GetReference(), + &create_info); + chosen_files.push_back(create_info); } + + reply_context_.params.set_result( + (chosen_files.size() > 0) ? PP_OK : PP_ERROR_USERCANCEL); + host()->SendReply(reply_context_, + PpapiPluginMsg_FileChooser_ShowReply(chosen_files)); + + reply_context_ = ppapi::host::ReplyMessageContext(); + handler_ = NULL; // Handler deletes itself. } int32_t PepperFileChooserHost::OnShow( @@ -174,34 +167,5 @@ int32_t PepperFileChooserHost::OnShow( return PP_OK_COMPLETIONPENDING; } -void PepperFileChooserHost::DidCreateResourceHosts( - const std::vector<base::FilePath>& file_paths, - const std::vector<std::string>& display_names, - const std::vector<int>& browser_ids) { - DCHECK(file_paths.size() == display_names.size()); - DCHECK(file_paths.size() == browser_ids.size()); - - std::vector<ppapi::FileRefCreateInfo> chosen_files; - for (size_t i = 0; i < browser_ids.size(); ++i) { - PepperFileRefRendererHost* renderer_host = - new PepperFileRefRendererHost(renderer_ppapi_host_, - pp_instance(), - 0, - file_paths[i]); - int renderer_id = - renderer_ppapi_host_->GetPpapiHost()->AddPendingResourceHost( - scoped_ptr<ppapi::host::ResourceHost>(renderer_host)); - ppapi::FileRefCreateInfo info = ppapi::MakeExternalFileRefCreateInfo( - file_paths[i], display_names[i], browser_ids[i], renderer_id); - chosen_files.push_back(info); - } - - reply_context_.params.set_result(PP_OK); - host()->SendReply(reply_context_, - PpapiPluginMsg_FileChooser_ShowReply(chosen_files)); - reply_context_ = ppapi::host::ReplyMessageContext(); - handler_ = NULL; // Handler deletes itself. -} - } // namespace content diff --git a/content/renderer/pepper/pepper_file_chooser_host.h b/content/renderer/pepper/pepper_file_chooser_host.h index 52f7c5f..af27768 100644 --- a/content/renderer/pepper/pepper_file_chooser_host.h +++ b/content/renderer/pepper/pepper_file_chooser_host.h @@ -15,10 +15,6 @@ #include "ppapi/host/resource_host.h" #include "ppapi/proxy/resource_message_params.h" -namespace ppapi { -struct FileRefCreateInfo; -} - namespace content { class RendererPpapiHost; @@ -55,18 +51,12 @@ class CONTENT_EXPORT PepperFileChooserHost const std::string& suggested_file_name, const std::vector<std::string>& accept_mime_types); - void DidCreateResourceHosts(const std::vector<base::FilePath>& file_paths, - const std::vector<std::string>& display_names, - const std::vector<int>& browser_ids); - // Non-owning pointer. RendererPpapiHost* renderer_ppapi_host_; ppapi::host::ReplyMessageContext reply_context_; CompletionHandler* handler_; - base::WeakPtrFactory<PepperFileChooserHost> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(PepperFileChooserHost); }; diff --git a/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/content/renderer/pepper/pepper_file_chooser_host_unittest.cc index 98c8598..b228cd7 100644 --- a/content/renderer/pepper/pepper_file_chooser_host_unittest.cc +++ b/content/renderer/pepper/pepper_file_chooser_host_unittest.cc @@ -17,8 +17,8 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/resource_message_params.h" #include "ppapi/proxy/resource_message_test_sink.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" #include "ppapi/shared_impl/resource_tracker.h" #include "ppapi/shared_impl/test_globals.h" #include "testing/gtest/include/gtest/gtest.h" @@ -121,11 +121,13 @@ TEST_F(PepperFileChooserHostTest, Show) { PpapiPluginMsg_FileChooser_ShowReply::Schema::Param reply_msg_param; ASSERT_TRUE(PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, &reply_msg_param)); - const std::vector<ppapi::FileRefCreateInfo>& chooser_results = + const std::vector<ppapi::PPB_FileRef_CreateInfo>& chooser_results = reply_msg_param.a; ASSERT_EQ(1u, chooser_results.size()); + // Note path is empty because this is an external filesystem. + EXPECT_EQ(std::string(), chooser_results[0].path); EXPECT_EQ(FilePathToUTF8(selected_info.display_name), - chooser_results[0].display_name); + chooser_results[0].name); } TEST_F(PepperFileChooserHostTest, NoUserGesture) { diff --git a/content/renderer/pepper/pepper_file_io_host.cc b/content/renderer/pepper/pepper_file_io_host.cc index aedf882..6b9cfc5 100644 --- a/content/renderer/pepper/pepper_file_io_host.cc +++ b/content/renderer/pepper/pepper_file_io_host.cc @@ -17,11 +17,9 @@ #include "content/public/common/content_client.h" #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/pepper/host_globals.h" -#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" -#include "content/renderer/pepper/plugin_module.h" +#include "content/renderer/pepper/ppb_file_ref_impl.h" #include "content/renderer/pepper/quota_file_io.h" -#include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "content/renderer/render_thread_impl.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_file_io.h" @@ -39,6 +37,7 @@ using ppapi::FileIOStateManager; using ppapi::PPTimeToTime; using ppapi::host::ReplyMessageContext; using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_FileRef_API; namespace { @@ -138,7 +137,6 @@ PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host, PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), - plugin_instance_(HostGlobals::Get()->GetInstance(instance)), file_(base::kInvalidPlatformFileValue), file_system_type_(PP_FILESYSTEMTYPE_INVALID), quota_policy_(quota::kQuotaLimitTypeUnknown), @@ -231,19 +229,25 @@ int32_t PepperFileIOHost::OnHostMsgOpen( return PP_ERROR_BADARGUMENT; } - ppapi::host::ResourceHost* resource_host = - renderer_ppapi_host_->GetPpapiHost()->GetResourceHost(file_ref_resource); - if (!resource_host || !resource_host->IsFileRefHost()) + EnterResourceNoLock<PPB_FileRef_API> enter(file_ref_resource, true); + if (enter.failed()) return PP_ERROR_BADRESOURCE; - PepperFileRefRendererHost* file_ref_host = - static_cast<PepperFileRefRendererHost*>(resource_host); - file_system_type_ = file_ref_host->GetFileSystemType(); - if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { - file_system_url_ = file_ref_host->GetFileSystemURL(); + PPB_FileRef_API* file_ref_api = enter.object(); + PP_FileSystemType type = file_ref_api->GetFileSystemType(); + if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && + type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && + type != PP_FILESYSTEMTYPE_EXTERNAL && + type != PP_FILESYSTEMTYPE_ISOLATED) + return PP_ERROR_FAILED; + file_system_type_ = type; + + PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api); + if (file_ref->HasValidFileSystem()) { + file_system_url_ = file_ref->GetFileSystemURL(); + FileSystemDispatcher* file_system_dispatcher = ChildThread::current()->file_system_dispatcher(); - AsyncOpenFileSystemURLCallback callback = base::Bind( &PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback, weak_factory_.GetWeakPtr(), @@ -253,16 +257,16 @@ int32_t PepperFileIOHost::OnHostMsgOpen( base::Bind(&DidOpenFileSystemURL, callback), base::Bind(&DidFailOpenFileSystemURL, callback)); } else { + if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; int message_id = pending_async_open_files_.Add(new AsyncOpenFileCallback( base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback, weak_factory_.GetWeakPtr(), context->MakeReplyMessageContext()))); RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( - routing_id_, - file_ref_host->GetExternalFilePath(), - open_flags_, - message_id)); + routing_id_, file_ref->GetSystemPath(), open_flags, message_id)); } + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); return PP_OK_COMPLETIONPENDING; } diff --git a/content/renderer/pepper/pepper_file_io_host.h b/content/renderer/pepper/pepper_file_io_host.h index c394714..0e26174 100644 --- a/content/renderer/pepper/pepper_file_io_host.h +++ b/content/renderer/pepper/pepper_file_io_host.h @@ -26,7 +26,6 @@ using ppapi::host::ReplyMessageContext; namespace content { -class PepperPluginInstanceImpl; class QuotaFileIO; class PepperFileIOHost : public ppapi::host::ResourceHost, @@ -106,7 +105,7 @@ class PepperFileIOHost : public ppapi::host::ResourceHost, int bytes_written); RendererPpapiHost* renderer_ppapi_host_; - PepperPluginInstanceImpl* plugin_instance_; + base::PlatformFile file_; // The file system type specified in the Open() call. This will be diff --git a/content/renderer/pepper/pepper_file_ref_renderer_host.cc b/content/renderer/pepper/pepper_file_ref_renderer_host.cc deleted file mode 100644 index 0f1442b..0000000 --- a/content/renderer/pepper/pepper_file_ref_renderer_host.cc +++ /dev/null @@ -1,83 +0,0 @@ -// 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/renderer/pepper/pepper_file_ref_renderer_host.h" - -#include <string> - -#include "net/base/escape.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/host/ppapi_host.h" -#include "ppapi/shared_impl/file_ref_util.h" - -namespace content { - -PepperFileRefRendererHost::PepperFileRefRendererHost( - RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource, - PP_Resource file_system, - const std::string& internal_path) - : ResourceHost(host->GetPpapiHost(), instance, resource), - file_system_type_(PP_FILESYSTEMTYPE_INVALID), - internal_path_(internal_path) { - if (!ppapi::IsValidInternalPath(internal_path)) - return; - ResourceHost* fs_host = host->GetPpapiHost()->GetResourceHost(file_system); - if (fs_host && fs_host->IsFileSystemHost()) { - fs_host_ = base::AsWeakPtr(static_cast<PepperFileSystemHost*>(fs_host)); - file_system_type_ = fs_host_->GetType(); - } -} - -PepperFileRefRendererHost::PepperFileRefRendererHost( - RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource, - const base::FilePath& external_path) - : ResourceHost(host->GetPpapiHost(), instance, resource), - file_system_type_(PP_FILESYSTEMTYPE_EXTERNAL), - external_path_(external_path) { - if (!ppapi::IsValidExternalPath(external_path)) - file_system_type_ = PP_FILESYSTEMTYPE_INVALID; -} - -PepperFileRefRendererHost::~PepperFileRefRendererHost() { -} - -PP_FileSystemType PepperFileRefRendererHost::GetFileSystemType() const { - return file_system_type_; -} - -GURL PepperFileRefRendererHost::GetFileSystemURL() const { - if (fs_host_.get() && fs_host_->IsOpened() && - fs_host_->GetRootUrl().is_valid()) { - CHECK(!internal_path_.empty() && internal_path_[0] == '/'); - // We strip off the leading slash when passing the URL to Resolve(). - // Internal paths are required to be absolute, so we can require this. - return fs_host_->GetRootUrl().Resolve( - net::EscapePath(internal_path_.substr(1))); - } - return GURL(); -} - -base::FilePath PepperFileRefRendererHost::GetExternalFilePath() const { - if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) - return base::FilePath(); - return external_path_; -} - -int32_t PepperFileRefRendererHost::OnResourceMessageReceived( - const IPC::Message& msg, - ppapi::host::HostMessageContext* context) { - // We don't handle any messages from the plugin in this host. - NOTREACHED(); - return PP_ERROR_FAILED; -} - -bool PepperFileRefRendererHost::IsFileRefHost() { - return true; -} - -} // namespace content diff --git a/content/renderer/pepper/pepper_file_ref_renderer_host.h b/content/renderer/pepper/pepper_file_ref_renderer_host.h deleted file mode 100644 index 13ee763..0000000 --- a/content/renderer/pepper/pepper_file_ref_renderer_host.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 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_RENDERER_PEPPER_PEPPER_FILE_REF_RENDERER_HOST_H_ -#define CONTENT_RENDERER_PEPPER_PEPPER_FILE_REF_RENDERER_HOST_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/files/file_path.h" -#include "base/memory/weak_ptr.h" -#include "content/public/renderer/renderer_ppapi_host.h" -#include "content/renderer/pepper/pepper_file_system_host.h" -#include "ipc/ipc_message.h" -#include "ppapi/c/pp_file_info.h" -#include "ppapi/c/pp_instance.h" -#include "ppapi/c/pp_resource.h" -#include "ppapi/host/host_message_context.h" -#include "ppapi/host/resource_host.h" -#include "url/gurl.h" - -namespace content { - -class PepperFileRefRendererHost - : public ppapi::host::ResourceHost { - public: - PepperFileRefRendererHost(RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource, - PP_Resource file_system, - const std::string& internal_path); - - PepperFileRefRendererHost(RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource, - const base::FilePath& external_path); - - virtual ~PepperFileRefRendererHost(); - - PP_FileSystemType GetFileSystemType() const; - GURL GetFileSystemURL() const; - base::FilePath GetExternalFilePath() const; - - // ppapi::host::ResourceHost override. - virtual int32_t OnResourceMessageReceived( - const IPC::Message& msg, - ppapi::host::HostMessageContext* context) OVERRIDE; - virtual bool IsFileRefHost() OVERRIDE; - - private: - PP_FileSystemType file_system_type_; - std::string internal_path_; - base::FilePath external_path_; - base::WeakPtr<PepperFileSystemHost> fs_host_; - - DISALLOW_COPY_AND_ASSIGN(PepperFileRefRendererHost); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_PEPPER_PEPPER_FILE_REF_RENDERER_HOST_H_ diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.cc b/content/renderer/pepper/pepper_in_process_resource_creation.cc index cb10ff2..9743bca5 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.cc +++ b/content/renderer/pepper/pepper_in_process_resource_creation.cc @@ -19,7 +19,6 @@ #include "ppapi/proxy/ext_crx_file_system_private_resource.h" #include "ppapi/proxy/file_chooser_resource.h" #include "ppapi/proxy/file_io_resource.h" -#include "ppapi/proxy/file_ref_resource.h" #include "ppapi/proxy/file_system_resource.h" #include "ppapi/proxy/graphics_2d_resource.h" #include "ppapi/proxy/ppapi_messages.h" @@ -86,15 +85,6 @@ PP_Resource PepperInProcessResourceCreation::CreateFileIO( instance))->GetReference(); } -PP_Resource PepperInProcessResourceCreation::CreateFileRef( - PP_Instance instance, - const ppapi::FileRefCreateInfo& create_info) { - return ppapi::proxy::FileRefResource::CreateFileRef( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance, - create_info); -} - PP_Resource PepperInProcessResourceCreation::CreateFileSystem( PP_Instance instance, PP_FileSystemType type) { diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.h b/content/renderer/pepper/pepper_in_process_resource_creation.h index 847aac1..985ae09 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.h +++ b/content/renderer/pepper/pepper_in_process_resource_creation.h @@ -49,9 +49,6 @@ class PepperInProcessResourceCreation : public ResourceCreationImpl { PP_FileChooserMode_Dev mode, const PP_Var& accept_types) OVERRIDE; virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateFileRef( - PP_Instance instance, - const ppapi::FileRefCreateInfo& create_info) OVERRIDE; virtual PP_Resource CreateFileSystem(PP_Instance instance, PP_FileSystemType type) OVERRIDE; virtual PP_Resource CreateGraphics2D( diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 2820efd..49daf81 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -29,7 +29,6 @@ #include "content/renderer/pepper/message_channel.h" #include "content/renderer/pepper/npapi_glue.h" #include "content/renderer/pepper/pepper_browser_connection.h" -#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "content/renderer/pepper/pepper_in_process_router.h" #include "content/renderer/pepper/pepper_platform_context_3d.h" @@ -37,6 +36,7 @@ #include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/plugin_object.h" #include "content/renderer/pepper/ppb_buffer_impl.h" +#include "content/renderer/pepper/ppb_file_ref_impl.h" #include "content/renderer/pepper/ppb_graphics_3d_impl.h" #include "content/renderer/pepper/ppb_image_data_impl.h" #include "content/renderer/pepper/ppp_pdf.h" @@ -768,7 +768,6 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad( DCHECK(pending_host_id); DataFromWebURLResponse( - host_impl, pp_instance(), response, base::Bind(&PepperPluginInstanceImpl::DidDataFromWebURLResponse, @@ -2614,6 +2613,13 @@ base::FilePath PepperPluginInstanceImpl::GetModulePath() { return module_->path(); } +PP_Resource PepperPluginInstanceImpl::CreateExternalFileReference( + const base::FilePath& external_file_path) { + PPB_FileRef_Impl* ref = PPB_FileRef_Impl::CreateExternal( + pp_instance(), external_file_path, ""); + return ref->GetReference(); +} + PP_Resource PepperPluginInstanceImpl::CreateImage(gfx::ImageSkia* source_image, float scale) { ui::ScaleFactor scale_factor = ui::GetScaleFactorFromScale(scale); @@ -2750,12 +2756,8 @@ int32_t PepperPluginInstanceImpl::Navigate( ppapi::URLRequestInfoData completed_request = request; WebURLRequest web_request; - if (!CreateWebURLRequest(pp_instance_, - &completed_request, - frame, - &web_request)) { + if (!CreateWebURLRequest(&completed_request, frame, &web_request)) return PP_ERROR_FAILED; - } web_request.setFirstPartyForCookies(document.firstPartyForCookies()); web_request.setHasUserGesture(from_user_action); @@ -2784,15 +2786,6 @@ int32_t PepperPluginInstanceImpl::Navigate( return PP_OK; } -int PepperPluginInstanceImpl::MakePendingFileRefRendererHost( - const base::FilePath& path) { - RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host(); - PepperFileRefRendererHost* file_ref_host( - new PepperFileRefRendererHost(host_impl, pp_instance(), 0, path)); - return host_impl->GetPpapiHost()->AddPendingResourceHost( - scoped_ptr<ppapi::host::ResourceHost>(file_ref_host)); -} - bool PepperPluginInstanceImpl::CanAccessMainFrame() const { if (!container_) return false; diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index dd31b07..964b23b 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -347,6 +347,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl virtual ppapi::VarTracker* GetVarTracker() OVERRIDE; virtual const GURL& GetPluginURL() OVERRIDE; virtual base::FilePath GetModulePath() OVERRIDE; + virtual PP_Resource CreateExternalFileReference( + const base::FilePath& external_file_path) OVERRIDE; virtual PP_Resource CreateImage(gfx::ImageSkia* source_image, float scale) OVERRIDE; virtual PP_ExternalPluginResult SwitchToOutOfProcessProxy( @@ -362,8 +364,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl virtual int32_t Navigate(const ppapi::URLRequestInfoData& request, const char* target, bool from_user_action) OVERRIDE; - virtual int MakePendingFileRefRendererHost( - const base::FilePath& path) OVERRIDE; // PPB_Instance_API implementation. virtual PP_Bool BindGraphics(PP_Instance instance, diff --git a/content/renderer/pepper/pepper_url_loader_host.cc b/content/renderer/pepper/pepper_url_loader_host.cc index 3f0dbc9..ef20c27 100644 --- a/content/renderer/pepper/pepper_url_loader_host.cc +++ b/content/renderer/pepper/pepper_url_loader_host.cc @@ -252,12 +252,8 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( return PP_ERROR_FAILED; WebURLRequest web_request; - if (!CreateWebURLRequest(pp_instance(), - &filled_in_request_data, - frame, - &web_request)) { + if (!CreateWebURLRequest(&filled_in_request_data, frame, &web_request)) return PP_ERROR_FAILED; - } web_request.setTargetType(WebURLRequest::TargetIsObject); web_request.setRequestorProcessID(renderer_ppapi_host_->GetPluginPID()); @@ -397,7 +393,6 @@ void PepperURLLoaderHost::SaveResponse(const WebURLResponse& response) { pending_response_ = true; DataFromWebURLResponse( - renderer_ppapi_host_, pp_instance(), response, base::Bind(&PepperURLLoaderHost::DidDataFromWebURLResponse, diff --git a/content/renderer/pepper/pepper_url_request_unittest.cc b/content/renderer/pepper/pepper_url_request_unittest.cc index 05ca764..080c884 100644 --- a/content/renderer/pepper/pepper_url_request_unittest.cc +++ b/content/renderer/pepper/pepper_url_request_unittest.cc @@ -77,7 +77,7 @@ class URLRequestInfoTest : public RenderViewTest { bool GetDownloadToFile() { WebURLRequest web_request; URLRequestInfoData data = info_->GetData(); - if (!CreateWebURLRequest(pp_instance_, &data, GetMainFrame(), &web_request)) + if (!CreateWebURLRequest(&data, GetMainFrame(), &web_request)) return false; return web_request.downloadToFile(); } @@ -85,7 +85,7 @@ class URLRequestInfoTest : public RenderViewTest { WebCString GetURL() { WebURLRequest web_request; URLRequestInfoData data = info_->GetData(); - if (!CreateWebURLRequest(pp_instance_, &data, GetMainFrame(), &web_request)) + if (!CreateWebURLRequest(&data, GetMainFrame(), &web_request)) return WebCString(); return web_request.url().spec(); } @@ -93,7 +93,7 @@ class URLRequestInfoTest : public RenderViewTest { WebString GetMethod() { WebURLRequest web_request; URLRequestInfoData data = info_->GetData(); - if (!CreateWebURLRequest(pp_instance_, &data, GetMainFrame(), &web_request)) + if (!CreateWebURLRequest(&data, GetMainFrame(), &web_request)) return WebString(); return web_request.httpMethod(); } @@ -101,7 +101,7 @@ class URLRequestInfoTest : public RenderViewTest { WebString GetHeaderValue(const char* field) { WebURLRequest web_request; URLRequestInfoData data = info_->GetData(); - if (!CreateWebURLRequest(pp_instance_, &data, GetMainFrame(), &web_request)) + if (!CreateWebURLRequest(&data, GetMainFrame(), &web_request)) return WebString(); return web_request.httpHeaderField(WebString::fromUTF8(field)); } diff --git a/content/renderer/pepper/ppb_file_ref_impl.cc b/content/renderer/pepper/ppb_file_ref_impl.cc new file mode 100644 index 0000000..f664d79 --- /dev/null +++ b/content/renderer/pepper/ppb_file_ref_impl.cc @@ -0,0 +1,555 @@ +// 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/renderer/pepper/ppb_file_ref_impl.h" + +#include "base/files/file_util_proxy.h" +#include "base/platform_file.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "content/child/fileapi/file_system_dispatcher.h" +#include "content/common/view_messages.h" +#include "content/renderer/pepper/common.h" +#include "content/renderer/pepper/pepper_file_system_host.h" +#include "content/renderer/pepper/plugin_module.h" +#include "content/renderer/pepper/renderer_ppapi_host_impl.h" +#include "content/renderer/render_thread_impl.h" +#include "net/base/escape.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/host/ppapi_host.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_system_api.h" +#include "url/gurl.h" +#include "webkit/common/fileapi/directory_entry.h" +#include "webkit/common/fileapi/file_system_util.h" + +using ppapi::HostResource; +using ppapi::PPB_FileRef_CreateInfo; +using ppapi::PPTimeToTime; +using ppapi::StringVar; +using ppapi::TrackedCallback; +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_FileRef_API; +using ppapi::thunk::PPB_FileSystem_API; + +namespace content { + +namespace { + +bool IsValidLocalPath(const std::string& path) { + // The path must start with '/' + if (path.empty() || path[0] != '/') + return false; + + // The path must contain valid UTF-8 characters. + 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 + if (file_path.ReferencesParent()) + return false; + + return true; +} + +void TrimTrailingSlash(std::string* path) { + // If this path ends with a slash, then normalize it away unless path is the + // root path. + if (path->size() > 1 && path->at(path->size() - 1) == '/') + path->erase(path->size() - 1, 1); +} + +std::string GetNameForExternalFilePath(const base::FilePath& in_path) { + const base::FilePath::StringType& path = in_path.value(); + size_t pos = path.rfind(base::FilePath::kSeparators[0]); + CHECK(pos != base::FilePath::StringType::npos); +#if defined(OS_WIN) + return WideToUTF8(path.substr(pos + 1)); +#elif defined(OS_POSIX) + return path.substr(pos + 1); +#else +#error "Unsupported platform." +#endif +} + +std::string GetNameForVirtualFilePath(const std::string& path) { + if (path.size() == 1 && path[0] == '/') + return path; + + // There should always be a leading slash at least! + size_t pos = path.rfind('/'); + CHECK(pos != std::string::npos); + return path.substr(pos + 1); +} + +void IgnoreCloseCallback(base::PlatformFileError error_code) { +} + +void PlatformFileInfoToPPFileInfo( + const base::PlatformFileInfo& file_info, + PP_FileSystemType file_system_type, + PP_FileInfo* info) { + DCHECK(info); + ppapi::PlatformFileInfoToPepperFileInfo(file_info, file_system_type, info); +} + +void GetFileInfoCallback( + scoped_refptr<base::TaskRunner> task_runner, + base::PlatformFile file, + linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback, + base::PlatformFileError error_code, + const base::PlatformFileInfo& file_info) { + base::FileUtilProxy::Close( + task_runner.get(), file, base::Bind(&IgnoreCloseCallback)); + + if (!TrackedCallback::IsPending(callback)) + return; + + int32_t pp_error = ppapi::PlatformFileErrorToPepperError(error_code); + if (pp_error != PP_OK) { + callback->Run(pp_error); + return; + } + + PlatformFileInfoToPPFileInfo( + file_info, PP_FILESYSTEMTYPE_EXTERNAL, info.get()); + + callback->Run(PP_OK); +} + +void QueryCallback(scoped_refptr<base::TaskRunner> task_runner, + linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback, + base::PlatformFileError error_code, + base::PassPlatformFile passed_file) { + if (!TrackedCallback::IsPending(callback)) + return; + + int32_t pp_error = ppapi::PlatformFileErrorToPepperError(error_code); + if (pp_error != PP_OK) { + callback->Run(pp_error); + return; + } + base::PlatformFile file = passed_file.ReleaseValue(); + + if (!base::FileUtilProxy::GetFileInfoFromPlatformFile( + task_runner.get(), + file, + base::Bind( + &GetFileInfoCallback, task_runner, file, info, callback))) { + base::FileUtilProxy::Close( + task_runner.get(), file, base::Bind(&IgnoreCloseCallback)); + callback->Run(PP_ERROR_FAILED); + } +} + +void DidReadMetadata( + scoped_refptr<ppapi::TrackedCallback> callback, + linked_ptr<PP_FileInfo> info, + PP_FileSystemType file_system_type, + const base::PlatformFileInfo& file_info) { + if (!TrackedCallback::IsPending(callback)) + return; + + PlatformFileInfoToPPFileInfo(file_info, file_system_type, info.get()); + callback->Run(PP_OK); +} + +void DidReadDirectory( + scoped_refptr<ppapi::TrackedCallback> callback, + PPB_FileRef_Impl* dir_ref, + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > dir_files, + linked_ptr<std::vector<PP_FileType> > dir_file_types, + const std::vector<fileapi::DirectoryEntry>& entries, + bool has_more) { + if (!TrackedCallback::IsPending(callback)) + return; + + // The current filesystem backend always returns false. + DCHECK(!has_more); + + DCHECK(dir_ref); + DCHECK(dir_files.get()); + DCHECK(dir_file_types.get()); + + std::string dir_path = dir_ref->GetCreateInfo().path; + if (dir_path.empty() || dir_path[dir_path.size() - 1] != '/') + dir_path += '/'; + + for (size_t i = 0; i < entries.size(); ++i) { + const fileapi::DirectoryEntry& entry = entries[i]; + scoped_refptr<PPB_FileRef_Impl> file_ref(PPB_FileRef_Impl::CreateInternal( + dir_ref->pp_instance(), + dir_ref->file_system_resource(), + dir_path + fileapi::FilePathToString(base::FilePath(entry.name)))); + dir_files->push_back(file_ref->GetCreateInfo()); + dir_file_types->push_back( + entry.is_directory ? PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR); + // Add a ref count on behalf of the plugin side. + file_ref->GetReference(); + } + CHECK_EQ(dir_files->size(), dir_file_types->size()); + + callback->Run(PP_OK); +} + +void DidFinishFileOperation( + scoped_refptr<ppapi::TrackedCallback> callback, + base::PlatformFileError error_code) { + if (callback->completed()) + return; + callback->Run(ppapi::PlatformFileErrorToPepperError(error_code)); +} + +} // namespace + +PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, + PP_Resource file_system) + : PPB_FileRef_Shared(ppapi::OBJECT_IS_IMPL, info), + file_system_(file_system), + external_file_system_path_(), + routing_id_(MSG_ROUTING_NONE) { + if (RenderThreadImpl::current()) { // NULL in tests. + routing_id_ = RenderThreadImpl::current()->GenerateRoutingID(); + ChildThread::current()->AddRoute(routing_id_, this); + } +} + +PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, + const base::FilePath& external_file_path) + : PPB_FileRef_Shared(ppapi::OBJECT_IS_IMPL, info), + file_system_(), + external_file_system_path_(external_file_path), + routing_id_(MSG_ROUTING_NONE) { + if (RenderThreadImpl::current()) { // NULL in tests. + routing_id_ = RenderThreadImpl::current()->GenerateRoutingID(); + ChildThread::current()->AddRoute(routing_id_, this); + } +} + +PPB_FileRef_Impl::~PPB_FileRef_Impl() { + if (RenderThreadImpl::current()) + ChildThread::current()->RemoveRoute(routing_id_); +} + +// static +PPB_FileRef_Impl* PPB_FileRef_Impl::CreateInternal(PP_Instance instance, + PP_Resource pp_file_system, + const std::string& path) { + PepperFileSystemHost* fs_host = GetFileSystemHostInternal( + instance, pp_file_system); + if (!fs_host) + return 0; + + PP_FileSystemType type = fs_host->GetType(); + if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && + type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && + type != PP_FILESYSTEMTYPE_EXTERNAL && + type != PP_FILESYSTEMTYPE_ISOLATED) + return 0; + + PPB_FileRef_CreateInfo info; + info.resource = HostResource::MakeInstanceOnly(instance); + info.file_system_plugin_resource = pp_file_system; + info.file_system_type = type; + + // Validate the path. + info.path = path; + if (!IsValidLocalPath(info.path)) + return 0; + TrimTrailingSlash(&info.path); + + info.name = GetNameForVirtualFilePath(info.path); + + PPB_FileRef_Impl* file_ref = new PPB_FileRef_Impl(info, pp_file_system); + + RendererPpapiHostImpl* renderer_host = + RendererPpapiHostImpl::GetForPPInstance(instance); + if (renderer_host && renderer_host->IsRunningInProcess()) + file_ref->AddFileSystemRefCount(); + return file_ref; +} + +// static +PPB_FileRef_Impl* PPB_FileRef_Impl::CreateExternal( + PP_Instance instance, + const base::FilePath& external_file_path, + const std::string& display_name) { + PPB_FileRef_CreateInfo info; + info.resource = HostResource::MakeInstanceOnly(instance); + info.file_system_plugin_resource = 0; + info.file_system_type = PP_FILESYSTEMTYPE_EXTERNAL; + if (display_name.empty()) + info.name = GetNameForExternalFilePath(external_file_path); + else + info.name = display_name; + + return new PPB_FileRef_Impl(info, external_file_path); +} + +PP_Resource PPB_FileRef_Impl::GetParent() { + if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return 0; + + const std::string& virtual_path = GetCreateInfo().path; + + // There should always be a leading slash at least! + size_t pos = virtual_path.rfind('/'); + CHECK(pos != std::string::npos); + + // If the path is "/foo", then we want to include the slash. + if (pos == 0) + pos++; + std::string parent_path = virtual_path.substr(0, pos); + + scoped_refptr<PPB_FileRef_Impl> parent_ref( + CreateInternal(pp_instance(), file_system_, parent_path)); + if (!parent_ref.get()) + return 0; + return parent_ref->GetReference(); +} + +int32_t PPB_FileRef_Impl::MakeDirectory( + PP_Bool make_ancestors, + scoped_refptr<TrackedCallback> callback) { + if (!IsValidNonExternalFileSystem()) + return PP_ERROR_NOACCESS; + + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + file_system_dispatcher->CreateDirectory( + GetFileSystemURL(), false /* exclusive */, PP_ToBool(make_ancestors), + base::Bind(&DidFinishFileOperation, callback)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PPB_FileRef_Impl::Touch(PP_Time last_access_time, + PP_Time last_modified_time, + scoped_refptr<TrackedCallback> callback) { + if (!IsValidNonExternalFileSystem()) + return PP_ERROR_NOACCESS; + + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + file_system_dispatcher->TouchFile( + GetFileSystemURL(), + PPTimeToTime(last_access_time), + PPTimeToTime(last_modified_time), + base::Bind(&DidFinishFileOperation, callback)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PPB_FileRef_Impl::Delete(scoped_refptr<TrackedCallback> callback) { + if (!IsValidNonExternalFileSystem()) + return PP_ERROR_NOACCESS; + + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + file_system_dispatcher->Remove( + GetFileSystemURL(), + false /* recursive */, + base::Bind(&DidFinishFileOperation, callback)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PPB_FileRef_Impl::Rename(PP_Resource new_pp_file_ref, + scoped_refptr<TrackedCallback> callback) { + EnterResourceNoLock<PPB_FileRef_API> enter(new_pp_file_ref, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; + PPB_FileRef_Impl* new_file_ref = + static_cast<PPB_FileRef_Impl*>(enter.object()); + + if (!IsValidNonExternalFileSystem() || + file_system_ != new_file_ref->file_system_) + return PP_ERROR_NOACCESS; + + // TODO(viettrungluu): Also cancel when the new file ref is destroyed? + // http://crbug.com/67624 + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + file_system_dispatcher->Move( + GetFileSystemURL(), new_file_ref->GetFileSystemURL(), + base::Bind(&DidFinishFileOperation, callback)); + return PP_OK_COMPLETIONPENDING; +} + +PP_Var PPB_FileRef_Impl::GetAbsolutePath() { + if (GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL) + return GetPath(); + if (!external_path_var_.get()) { + external_path_var_ = + new StringVar(external_file_system_path_.AsUTF8Unsafe()); + } + return external_path_var_->GetPPVar(); +} + +base::FilePath PPB_FileRef_Impl::GetSystemPath() const { + if (GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL) { + NOTREACHED(); + return base::FilePath(); + } + return external_file_system_path_; +} + +GURL PPB_FileRef_Impl::GetFileSystemURL() const { + if (GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT && + GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY && + GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL && + GetFileSystemType() != PP_FILESYSTEMTYPE_ISOLATED) { + NOTREACHED(); + return GURL(); + } + + const std::string& virtual_path = GetCreateInfo().path; + CHECK(!virtual_path.empty()); // Should always be at least "/". + + // Since |virtual_path_| starts with a '/', it looks like an absolute path. + // We need to trim off the '/' before calling Resolve, as FileSystem URLs + // start with a storage type identifier that looks like a path segment. + + PepperFileSystemHost* host = GetFileSystemHost(); + if (!host) + return GURL(); + + return GURL(host->GetRootUrl()).Resolve(net::EscapePath( + virtual_path.substr(1))); +} + +bool PPB_FileRef_Impl::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_FileRef_Impl, msg) + IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenPepperFile_ACK, OnAsyncFileOpened) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void PPB_FileRef_Impl::OnAsyncFileOpened( + base::PlatformFileError error_code, + IPC::PlatformFileForTransit file_for_transit, + int message_id) { + AsyncOpenFileCallback* callback = + pending_async_open_files_.Lookup(message_id); + DCHECK(callback); + pending_async_open_files_.Remove(message_id); + + base::PlatformFile file = + IPC::PlatformFileForTransitToPlatformFile(file_for_transit); + callback->Run(error_code, base::PassPlatformFile(&file)); + // Make sure we won't leak file handle if the requester has died. + if (file != base::kInvalidPlatformFileValue) { + base::FileUtilProxy::Close( + RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(), + file, + base::FileUtilProxy::StatusCallback()); + } + delete callback; +} + +bool PPB_FileRef_Impl::IsValidNonExternalFileSystem() const { + PepperFileSystemHost* host = GetFileSystemHost(); + return HasValidFileSystem() && host && + host->GetType() != PP_FILESYSTEMTYPE_EXTERNAL; +} + +bool PPB_FileRef_Impl::HasValidFileSystem() const { + PepperFileSystemHost* host = GetFileSystemHost(); + return host && host->IsOpened(); +} + +int32_t PPB_FileRef_Impl::Query(PP_FileInfo* info, + scoped_refptr<TrackedCallback> callback) { + NOTREACHED(); + return PP_ERROR_FAILED; +} + +int32_t PPB_FileRef_Impl::QueryInHost( + linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback) { + if (!file_system_) { + // External file system + // We have to do something totally different for external file systems. + + // TODO(teravest): Use the SequencedWorkerPool instead. + scoped_refptr<base::TaskRunner> task_runner = + RenderThreadImpl::current()->GetFileThreadMessageLoopProxy(); + + int message_id = pending_async_open_files_.Add(new AsyncOpenFileCallback( + base::Bind(&QueryCallback, task_runner, info, callback))); + RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( + routing_id_, + GetSystemPath(), + PP_FILEOPENFLAG_READ, + message_id)); + } else { + // Non-external file system + if (!HasValidFileSystem()) + return PP_ERROR_NOACCESS; + + PP_FileSystemType file_system_type = GetFileSystemHost()->GetType(); + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + file_system_dispatcher->ReadMetadata( + GetFileSystemURL(), + base::Bind(&DidReadMetadata, callback, info, file_system_type), + base::Bind(&DidFinishFileOperation, callback)); + } + return PP_OK_COMPLETIONPENDING; +} + +int32_t PPB_FileRef_Impl::ReadDirectoryEntries( + const PP_ArrayOutput& output, + scoped_refptr<TrackedCallback> callback) { + NOTREACHED(); + return PP_ERROR_FAILED; +} + +int32_t PPB_FileRef_Impl::ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<TrackedCallback> callback) { + if (!IsValidNonExternalFileSystem()) + return PP_ERROR_NOACCESS; + + // TODO(yzshen): Passing base::Unretained(this) to the callback could + // be dangerous. + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + file_system_dispatcher->ReadDirectory( + GetFileSystemURL(), + base::Bind(&DidReadDirectory, + callback, base::Unretained(this), files, file_types), + base::Bind(&DidFinishFileOperation, callback)); + return PP_OK_COMPLETIONPENDING; +} + +PepperFileSystemHost* PPB_FileRef_Impl::GetFileSystemHost() const { + return GetFileSystemHostInternal(pp_instance(), file_system_); +} + +PepperFileSystemHost* PPB_FileRef_Impl::GetFileSystemHostInternal( + PP_Instance instance, PP_Resource resource) { + const ppapi::host::PpapiHost* ppapi_host = + RendererPpapiHost::GetForPPInstance(instance)->GetPpapiHost(); + if (!resource || !ppapi_host) + return NULL; + ppapi::host::ResourceHost* resource_host = + ppapi_host->GetResourceHost(resource); + if (resource_host && resource_host->IsFileSystemHost()) + return static_cast<PepperFileSystemHost*>(resource_host); + return NULL; +} + +} // namespace content diff --git a/content/renderer/pepper/ppb_file_ref_impl.h b/content/renderer/pepper/ppb_file_ref_impl.h new file mode 100644 index 0000000..9c31885 --- /dev/null +++ b/content/renderer/pepper/ppb_file_ref_impl.h @@ -0,0 +1,155 @@ +// 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_RENDERER_PEPPER_PPB_FILE_REF_IMPL_H_ +#define CONTENT_RENDERER_PEPPER_PPB_FILE_REF_IMPL_H_ + +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/files/file_path.h" +#include "base/id_map.h" +#include "base/memory/linked_ptr.h" +#include "base/platform_file.h" +#include "ipc/ipc_listener.h" +#include "ipc/ipc_platform_file.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/ppb_file_ref.h" +#include "ppapi/shared_impl/ppb_file_ref_shared.h" +#include "ppapi/shared_impl/scoped_pp_resource.h" +#include "ppapi/shared_impl/var.h" +#include "url/gurl.h" + +namespace ppapi { +namespace host { +class ResourceHost; +} +} + +namespace content { + +using ppapi::StringVar; + +class PepperFileSystemHost; + +class PPB_FileRef_Impl : public ppapi::PPB_FileRef_Shared, + public IPC::Listener { + public: + PPB_FileRef_Impl(const ppapi::PPB_FileRef_CreateInfo& info, + PP_Resource file_system); + PPB_FileRef_Impl(const ppapi::PPB_FileRef_CreateInfo& info, + const base::FilePath& external_file_path); + + // The returned object will have a refcount of 0 (just like "new"). + static PPB_FileRef_Impl* CreateInternal(PP_Instance instance, + PP_Resource pp_file_system, + const std::string& path); + + // The returned object will have a refcount of 0 (just like "new"). + static PPB_FileRef_Impl* CreateExternal( + PP_Instance instance, + const base::FilePath& external_file_path, + const std::string& display_name); + + // PPB_FileRef_API implementation (not provided by PPB_FileRef_Shared). + virtual PP_Resource GetParent() OVERRIDE; + virtual int32_t MakeDirectory( + PP_Bool make_ancestors, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t Touch( + PP_Time last_access_time, + PP_Time last_modified_time, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t Delete( + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t Rename( + PP_Resource new_file_ref, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t Query( + PP_FileInfo* info, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t ReadDirectoryEntries( + const PP_ArrayOutput& output, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t QueryInHost( + linked_ptr<PP_FileInfo> info, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual PP_Var GetAbsolutePath() OVERRIDE; + + PP_Resource file_system_resource() const { return file_system_; } + + // Returns the system path corresponding to this file. Valid only for + // external filesystems. + base::FilePath GetSystemPath() const; + + // Returns the FileSystem API URL corresponding to this file. + GURL GetFileSystemURL() const; + + // Checks if file ref has file system instance and if the instance is opened. + bool HasValidFileSystem() const; + + void AddFileSystemRefCount() { + file_system_ref_ = file_system_; + } + + private: + virtual ~PPB_FileRef_Impl(); + + // IPC::Listener implementation. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + void OnAsyncFileOpened( + base::PlatformFileError error_code, + IPC::PlatformFileForTransit file_for_transit, + int message_id); + + // Many mutation functions are allow only to non-external filesystems, This + // function returns true if the filesystem is opened and isn't external as an + // access check for these functions. + bool IsValidNonExternalFileSystem() const; + + PepperFileSystemHost* GetFileSystemHost() const; + static PepperFileSystemHost* GetFileSystemHostInternal( + PP_Instance instance, PP_Resource resource); + + // 0 for external filesystems. This is a plugin side resource that we don't + // hold a reference here, so file_system_ could be destroyed earlier than + // this object. Right now we checked the existance in plugin delegate before + // use. But it's better to hold a reference once we migrate FileRef to the + // new design. + PP_Resource file_system_; + + // Holds a reference of FileSystem when running in process. See + // PPB_FileRef_Proxy for corresponding code for out-of-process mode. Note + // that this ScopedPPResource is only expected to be used when running in + // process (since PPB_FileRef_Proxy takes care of out-of-process case). + // Also note that this workaround will be no longer needed after FileRef + // refactoring. + ppapi::ScopedPPResource file_system_ref_; + + // Used only for external filesystems. + base::FilePath external_file_system_path_; + + // Lazily initialized var created from the external path. This is so we can + // return the identical string object every time it is requested. + scoped_refptr<StringVar> external_path_var_; + + int routing_id_; + + typedef base::Callback<void (base::PlatformFileError, base::PassPlatformFile)> + AsyncOpenFileCallback; + + IDMap<AsyncOpenFileCallback> pending_async_open_files_; + + DISALLOW_COPY_AND_ASSIGN(PPB_FileRef_Impl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PPB_FILE_REF_IMPL_H_ diff --git a/content/renderer/pepper/resource_creation_impl.cc b/content/renderer/pepper/resource_creation_impl.cc index 3e81b0b..a9ec20d 100644 --- a/content/renderer/pepper/resource_creation_impl.cc +++ b/content/renderer/pepper/resource_creation_impl.cc @@ -8,6 +8,7 @@ #include "content/renderer/pepper/ppb_audio_impl.h" #include "content/renderer/pepper/ppb_broker_impl.h" #include "content/renderer/pepper/ppb_buffer_impl.h" +#include "content/renderer/pepper/ppb_file_ref_impl.h" #include "content/renderer/pepper/ppb_flash_message_loop_impl.h" #include "content/renderer/pepper/ppb_graphics_3d_impl.h" #include "content/renderer/pepper/ppb_image_data_impl.h" @@ -69,6 +70,22 @@ PP_Resource ResourceCreationImpl::CreateBuffer(PP_Instance instance, return PPB_Buffer_Impl::Create(instance, size); } +PP_Resource ResourceCreationImpl::CreateFileRef( + PP_Instance instance, + PP_Resource file_system, + const char* path) { + PPB_FileRef_Impl* res = PPB_FileRef_Impl::CreateInternal( + instance, file_system, path); + return res ? res->GetReference() : 0; +} + +PP_Resource ResourceCreationImpl::CreateFileRef( + const ppapi::PPB_FileRef_CreateInfo& serialized) { + // When we're in-process, the host resource in the create info *is* the + // resource, so we don't need to do anything. + return serialized.resource.host_resource(); +} + PP_Resource ResourceCreationImpl::CreateFlashDRM(PP_Instance instance) { return 0; // Not supported in-process. } diff --git a/content/renderer/pepper/resource_creation_impl.h b/content/renderer/pepper/resource_creation_impl.h index 4253d22..baaf1a0 100644 --- a/content/renderer/pepper/resource_creation_impl.h +++ b/content/renderer/pepper/resource_creation_impl.h @@ -35,6 +35,11 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { virtual PP_Resource CreateBroker(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateBuffer(PP_Instance instance, uint32_t size) OVERRIDE; + virtual PP_Resource CreateFileRef(PP_Instance instance, + PP_Resource file_system, + const char* path) OVERRIDE; + virtual PP_Resource CreateFileRef( + const ppapi::PPB_FileRef_CreateInfo& serialized) OVERRIDE; virtual PP_Resource CreateFlashDRM(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateFlashFontFile( PP_Instance instance, diff --git a/content/renderer/pepper/url_request_info_util.cc b/content/renderer/pepper/url_request_info_util.cc index 92ecdfb..72365fd 100644 --- a/content/renderer/pepper/url_request_info_util.cc +++ b/content/renderer/pepper/url_request_info_util.cc @@ -8,14 +8,10 @@ #include "base/strings/string_util.h" #include "content/common/fileapi/file_system_messages.h" #include "content/renderer/pepper/common.h" -#include "content/renderer/pepper/host_globals.h" -#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" -#include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_module.h" -#include "content/renderer/pepper/renderer_ppapi_host_impl.h" +#include "content/renderer/pepper/ppb_file_ref_impl.h" #include "content/renderer/render_thread_impl.h" #include "net/http/http_util.h" -#include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/url_request_info_data.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" @@ -29,9 +25,10 @@ #include "url/url_util.h" #include "webkit/child/weburlrequest_extradata_impl.h" -using ppapi::Resource; using ppapi::URLRequestInfoData; +using ppapi::Resource; using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_FileRef_API; using WebKit::WebData; using WebKit::WebHTTPBody; using WebKit::WebString; @@ -46,39 +43,32 @@ namespace { // Appends the file ref given the Resource pointer associated with it to the // given HTTP body, returning true on success. bool AppendFileRefToBody( - PP_Instance instance, - PP_Resource resource, + Resource* file_ref_resource, int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time, WebHTTPBody *http_body) { - base::FilePath platform_path; - PepperPluginInstanceImpl* instance_impl = - HostGlobals::Get()->GetInstance(instance); - if (!instance_impl) + // Get the underlying file ref impl. + if (!file_ref_resource) return false; - - RendererPpapiHost* renderer_ppapi_host = - instance_impl->module()->renderer_ppapi_host(); - if (!renderer_ppapi_host) - return false; - ppapi::host::ResourceHost* resource_host = - renderer_ppapi_host->GetPpapiHost()->GetResourceHost(resource); - if (!resource_host || !resource_host->IsFileRefHost()) + PPB_FileRef_API* file_ref_api = file_ref_resource->AsPPB_FileRef_API(); + if (!file_ref_api) return false; - PepperFileRefRendererHost* file_ref_host = - static_cast<PepperFileRefRendererHost*>(resource_host); - switch (file_ref_host->GetFileSystemType()) { + const PPB_FileRef_Impl* file_ref = + static_cast<PPB_FileRef_Impl*>(file_ref_api); + + base::FilePath platform_path; + switch (file_ref->GetFileSystemType()) { case PP_FILESYSTEMTYPE_LOCALTEMPORARY: case PP_FILESYSTEMTYPE_LOCALPERSISTENT: // TODO(kinuko): remove this sync IPC when we fully support // AppendURLRange for FileSystem URL. RenderThreadImpl::current()->Send( new FileSystemHostMsg_SyncGetPlatformPath( - file_ref_host->GetFileSystemURL(), &platform_path)); + file_ref->GetFileSystemURL(), &platform_path)); break; case PP_FILESYSTEMTYPE_EXTERNAL: - platform_path = file_ref_host->GetExternalFilePath(); + platform_path = file_ref->GetSystemPath(); break; default: NOTREACHED(); @@ -94,7 +84,7 @@ bool AppendFileRefToBody( // Checks that the request data is valid. Returns false on failure. Note that // method and header validation is done by the URL loader when the request is // opened, and any access errors are returned asynchronously. -bool ValidateURLRequestData(const URLRequestInfoData& data) { +bool ValidateURLRequestData(const ppapi::URLRequestInfoData& data) { if (data.prefetch_buffer_lower_threshold < 0 || data.prefetch_buffer_upper_threshold < 0 || data.prefetch_buffer_upper_threshold <= @@ -104,16 +94,33 @@ bool ValidateURLRequestData(const URLRequestInfoData& data) { return true; } +// Ensures that the file_ref members of the given request info data are +// populated from the resource IDs. Returns true on success. +bool EnsureFileRefObjectsPopulated(ppapi::URLRequestInfoData* data) { + // Get the Resource objects for any file refs with only host resource (this + // is the state of the request as it comes off IPC). + for (size_t i = 0; i < data->body.size(); ++i) { + URLRequestInfoData::BodyItem& item = data->body[i]; + if (item.is_file && !item.file_ref.get()) { + EnterResourceNoLock<PPB_FileRef_API> enter( + item.file_ref_host_resource.host_resource(), false); + if (!enter.succeeded()) + return false; + item.file_ref = enter.resource(); + } + } + return true; +} + } // namespace -bool CreateWebURLRequest(PP_Instance instance, - URLRequestInfoData* data, +bool CreateWebURLRequest(ppapi::URLRequestInfoData* data, WebFrame* frame, WebURLRequest* dest) { // In the out-of-process case, we've received the URLRequestInfoData // from the untrusted plugin and done no validation on it. We need to be // sure it's not being malicious by checking everything for consistency. - if (!ValidateURLRequestData(*data)) + if (!ValidateURLRequestData(*data) || !EnsureFileRefObjectsPopulated(data)) return false; dest->initialize(); @@ -141,18 +148,15 @@ bool CreateWebURLRequest(PP_Instance instance, if (!data->body.empty()) { WebHTTPBody http_body; http_body.initialize(); - int file_index = 0; for (size_t i = 0; i < data->body.size(); ++i) { const URLRequestInfoData::BodyItem& item = data->body[i]; if (item.is_file) { - if (!AppendFileRefToBody(instance, - item.file_ref_pp_resource, + if (!AppendFileRefToBody(item.file_ref.get(), item.start_offset, item.number_of_bytes, item.expected_last_modified_time, &http_body)) return false; - file_index++; } else { DCHECK(!item.data.empty()); http_body.appendData(WebData(item.data)); @@ -185,7 +189,7 @@ bool CreateWebURLRequest(PP_Instance instance, return true; } -bool URLRequestRequiresUniversalAccess(const URLRequestInfoData& data) { +bool URLRequestRequiresUniversalAccess(const ppapi::URLRequestInfoData& data) { return data.has_custom_referrer_url || data.has_custom_content_transfer_encoding || diff --git a/content/renderer/pepper/url_request_info_util.h b/content/renderer/pepper/url_request_info_util.h index 2fb40e6..2a93fe6 100644 --- a/content/renderer/pepper/url_request_info_util.h +++ b/content/renderer/pepper/url_request_info_util.h @@ -7,7 +7,6 @@ #include "base/memory/ref_counted.h" #include "content/common/content_export.h" -#include "ppapi/c/pp_instance.h" namespace ppapi { struct URLRequestInfoData; @@ -24,8 +23,7 @@ namespace content { // on success, false if the request is invalid (in which case *dest may be // partially initialized). Any upload files with only resource IDs (no file ref // pointers) will be populated by this function on success. -CONTENT_EXPORT bool CreateWebURLRequest(PP_Instance instance, - ppapi::URLRequestInfoData* data, +CONTENT_EXPORT bool CreateWebURLRequest(ppapi::URLRequestInfoData* data, WebKit::WebFrame* frame, WebKit::WebURLRequest* dest); diff --git a/content/renderer/pepper/url_response_info_util.cc b/content/renderer/pepper/url_response_info_util.cc index eda54d4..a9eccef 100644 --- a/content/renderer/pepper/url_response_info_util.cc +++ b/content/renderer/pepper/url_response_info_util.cc @@ -7,11 +7,7 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/message_loop/message_loop.h" -#include "content/public/renderer/renderer_ppapi_host.h" -#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" -#include "content/renderer/pepper/renderer_ppapi_host_impl.h" -#include "ipc/ipc_message.h" -#include "ppapi/proxy/ppapi_messages.h" +#include "content/renderer/pepper/ppb_file_ref_impl.h" #include "ppapi/shared_impl/url_response_info_data.h" #include "third_party/WebKit/public/platform/WebCString.h" #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" @@ -47,34 +43,13 @@ bool IsRedirect(int32_t status) { return status >= 300 && status <= 399; } -void DidCreateResourceHosts(const ppapi::URLResponseInfoData& in_data, - const base::FilePath& external_path, - int renderer_pending_host_id, - const DataFromWebURLResponseCallback& callback, - const std::vector<int>& browser_pending_host_ids) { - DCHECK(browser_pending_host_ids.size() == 1); - int browser_pending_host_id = 0; - - if (browser_pending_host_ids.size() == 1) - browser_pending_host_id = browser_pending_host_ids[0]; - - ppapi::URLResponseInfoData data = in_data; - - data.body_as_file_ref = ppapi::MakeExternalFileRefCreateInfo( - external_path, - std::string(), - browser_pending_host_id, - renderer_pending_host_id); - callback.Run(data); -} - } // namespace -void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl, - PP_Instance pp_instance, +void DataFromWebURLResponse(PP_Instance pp_instance, const WebURLResponse& response, const DataFromWebURLResponseCallback& callback) { ppapi::URLResponseInfoData data; + data.url = response.url().spec(); data.status_code = response.httpStatusCode(); data.status_text = response.httpStatusText().utf8(); @@ -89,30 +64,18 @@ void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl, WebString file_path = response.downloadFilePath(); if (!file_path.isEmpty()) { - base::FilePath external_path = base::FilePath::FromUTF16Unsafe(file_path); - // TODO(teravest): Write a utility function to create resource hosts in the - // renderer and browser. - PepperFileRefRendererHost* renderer_host = - new PepperFileRefRendererHost(host_impl, pp_instance, 0, external_path); - int renderer_pending_host_id = - host_impl->GetPpapiHost()->AddPendingResourceHost( - scoped_ptr<ppapi::host::ResourceHost>(renderer_host)); - - std::vector<IPC::Message> create_msgs; - create_msgs.push_back(PpapiHostMsg_FileRef_CreateExternal(external_path)); - host_impl->CreateBrowserResourceHosts( - pp_instance, - create_msgs, - base::Bind(&DidCreateResourceHosts, - data, - external_path, - renderer_pending_host_id, - callback)); - } else { - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(callback, data)); + scoped_refptr<PPB_FileRef_Impl> file_ref( + PPB_FileRef_Impl::CreateExternal( + pp_instance, + base::FilePath::FromUTF16Unsafe(file_path), + std::string())); + data.body_as_file_ref = file_ref->GetCreateInfo(); + file_ref->GetReference(); // The returned data has one ref for the plugin. } + + // We post data to a callback instead of returning it here because the new + // implementation for FileRef is asynchronous when creating the resource. + base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, data)); } } // namespace content diff --git a/content/renderer/pepper/url_response_info_util.h b/content/renderer/pepper/url_response_info_util.h index ee0c2383..21eba4c 100644 --- a/content/renderer/pepper/url_response_info_util.h +++ b/content/renderer/pepper/url_response_info_util.h @@ -14,7 +14,6 @@ class WebURLResponse; } namespace content { -class RendererPpapiHostImpl; typedef base::Callback<void(const ppapi::URLResponseInfoData&)> DataFromWebURLResponseCallback; @@ -22,8 +21,7 @@ typedef base::Callback<void(const ppapi::URLResponseInfoData&)> // The returned object will have one plugin reference to the "body_as_file_ref" // if it's non-null. It's expected that the result of this function will be // passed to the plugin. -void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl, - PP_Instance pp_instance, +void DataFromWebURLResponse(PP_Instance pp_instance, const WebKit::WebURLResponse& response, const DataFromWebURLResponseCallback& callback); diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index ab4b34a..52b97e9 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -115,6 +115,8 @@ 'proxy/ppb_buffer_proxy.h', 'proxy/ppb_core_proxy.cc', 'proxy/ppb_core_proxy.h', + 'proxy/ppb_file_ref_proxy.cc', + 'proxy/ppb_file_ref_proxy.h', 'proxy/ppb_flash_message_loop_proxy.cc', 'proxy/ppb_flash_message_loop_proxy.h', 'proxy/ppb_graphics_3d_proxy.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index cf91e3d..7d0dc85 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -23,7 +23,6 @@ 'shared_impl/file_io_state_manager.h', 'shared_impl/file_path.cc', 'shared_impl/file_path.h', - 'shared_impl/file_ref_create_info.cc', 'shared_impl/file_ref_create_info.h', 'shared_impl/file_ref_util.cc', 'shared_impl/file_ref_util.h', @@ -54,6 +53,8 @@ 'shared_impl/ppb_crypto_shared.cc', 'shared_impl/ppb_device_ref_shared.cc', 'shared_impl/ppb_device_ref_shared.h', + 'shared_impl/ppb_file_ref_shared.cc', + 'shared_impl/ppb_file_ref_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/file_chooser_resource.cc b/ppapi/proxy/file_chooser_resource.cc index 9847e29..ebd545c 100644 --- a/ppapi/proxy/file_chooser_resource.cc +++ b/ppapi/proxy/file_chooser_resource.cc @@ -9,8 +9,8 @@ #include "ipc/ipc_message.h" #include "ppapi/c/pp_errors.h" #include "ppapi/proxy/dispatch_reply_message.h" -#include "ppapi/proxy/file_ref_resource.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/shared_impl/var.h" namespace ppapi { @@ -100,25 +100,19 @@ void FileChooserResource::PopulateAcceptTypes( void FileChooserResource::OnPluginMsgShowReply( const ResourceMessageReplyParams& params, - const std::vector<FileRefCreateInfo>& chosen_files) { + const std::vector<PPB_FileRef_CreateInfo>& chosen_files) { if (output_.is_valid()) { // Using v0.6 of the API with the output array. std::vector<PP_Resource> files; - for (size_t i = 0; i < chosen_files.size(); i++) { - files.push_back(FileRefResource::CreateFileRef( - connection(), - pp_instance(), - chosen_files[i])); - } + for (size_t i = 0; i < chosen_files.size(); i++) + files.push_back(PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i])); output_.StoreResourceVector(files); } else { // Convert each of the passed in file infos to resources. These will be // owned by the FileChooser object until they're passed to the plugin. DCHECK(file_queue_.empty()); for (size_t i = 0; i < chosen_files.size(); i++) { - file_queue_.push(FileRefResource::CreateFileRef( - connection(), - pp_instance(), + file_queue_.push(PPB_FileRef_Proxy::DeserializeFileRef( chosen_files[i])); } } diff --git a/ppapi/proxy/file_chooser_resource.h b/ppapi/proxy/file_chooser_resource.h index b744e91..58331db 100644 --- a/ppapi/proxy/file_chooser_resource.h +++ b/ppapi/proxy/file_chooser_resource.h @@ -17,7 +17,7 @@ namespace ppapi { -struct FileRefCreateInfo; +struct PPB_FileRef_CreateInfo; namespace proxy { @@ -56,7 +56,7 @@ class PPAPI_PROXY_EXPORT FileChooserResource private: void OnPluginMsgShowReply( const ResourceMessageReplyParams& params, - const std::vector<FileRefCreateInfo>& chosen_files); + const std::vector<PPB_FileRef_CreateInfo>& chosen_files); int32_t ShowInternal(PP_Bool save_as, const PP_Var& suggested_file_name, diff --git a/ppapi/proxy/file_chooser_resource_unittest.cc b/ppapi/proxy/file_chooser_resource_unittest.cc index 4ba5bd9..a5801ee 100644 --- a/ppapi/proxy/file_chooser_resource_unittest.cc +++ b/ppapi/proxy/file_chooser_resource_unittest.cc @@ -5,7 +5,6 @@ #include "base/message_loop/message_loop.h" #include "ppapi/c/dev/ppb_file_chooser_dev.h" #include "ppapi/c/pp_errors.h" -#include "ppapi/c/ppb_file_ref.h" #include "ppapi/proxy/file_chooser_resource.h" #include "ppapi/proxy/locking_resource_releaser.h" #include "ppapi/proxy/ppapi_messages.h" @@ -92,14 +91,13 @@ TEST_F(FileChooserResourceTest, Show) { reply_params.set_result(PP_OK); // Synthesize a response with one file ref in it. Note that it must have a - // pending_host_resource_id set. Since there isn't actually a host, this can - // be whatever we want. - std::vector<FileRefCreateInfo> create_info_array; - FileRefCreateInfo create_info; - create_info.file_system_type = PP_FILESYSTEMTYPE_EXTERNAL; - create_info.display_name = "bar"; - create_info.browser_pending_host_resource_id = 12; - create_info.renderer_pending_host_resource_id = 15; + // host resource value set or deserialization will fail. Since there isn't + // actually a host, this can be whatever we want. + std::vector<PPB_FileRef_CreateInfo> create_info_array; + PPB_FileRef_CreateInfo create_info; + create_info.resource.SetHostResource(pp_instance(), 123); + create_info.path = "foo/bar"; + create_info.name = "baz"; create_info_array.push_back(create_info); ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( PpapiPluginMsg_ResourceReply(reply_params, @@ -117,8 +115,9 @@ TEST_F(FileChooserResourceTest, Show) { { ProxyAutoLock lock; ScopedPPVar release_name_var(ScopedPPVar::PassRef(), name_var); - EXPECT_VAR_IS_STRING("bar", name_var); + EXPECT_VAR_IS_STRING(create_info.name, name_var); } + // Path should be undefined since it's external filesystem. PP_Var path_var(file_ref_iface->GetPath(dest[0])); { ProxyAutoLock lock; diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc index fc53fb0..76ee51c 100644 --- a/ppapi/proxy/file_io_resource.cc +++ b/ppapi/proxy/file_io_resource.cc @@ -111,13 +111,9 @@ int32_t FileIOResource::Open(PP_Resource file_ref, if (rv != PP_OK) return rv; - // Take a reference on the FileRef resource while we're opening the file; we - // don't want the plugin destroying it during the Open operation. - file_ref_ = enter.resource(); - Call<PpapiPluginMsg_FileIO_OpenReply>(RENDERER, PpapiHostMsg_FileIO_Open( - file_ref, + enter.resource()->host_resource().host_resource(), open_flags), base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, callback)); @@ -414,9 +410,6 @@ void FileIOResource::OnPluginMsgOpenFileComplete( const ResourceMessageReplyParams& params) { DCHECK(state_manager_.get_pending_operation() == FileIOStateManager::OPERATION_EXCLUSIVE); - - // Release the FileRef resource. - file_ref_ = NULL; if (params.result() == PP_OK) state_manager_.SetOpenSucceed(); diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h index 26c4abb..1a888d1 100644 --- a/ppapi/proxy/file_io_resource.h +++ b/ppapi/proxy/file_io_resource.h @@ -7,13 +7,11 @@ #include <string> -#include "base/memory/scoped_ptr.h" #include "ppapi/c/private/pp_file_handle.h" #include "ppapi/proxy/connection.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_proxy_export.h" #include "ppapi/shared_impl/file_io_state_manager.h" -#include "ppapi/shared_impl/resource.h" #include "ppapi/thunk/ppb_file_io_api.h" namespace ppapi { @@ -139,8 +137,6 @@ class PPAPI_PROXY_EXPORT FileIOResource PP_FileSystemType file_system_type_; FileIOStateManager state_manager_; - scoped_refptr<Resource> file_ref_; - DISALLOW_COPY_AND_ASSIGN(FileIOResource); }; diff --git a/ppapi/proxy/file_ref_resource.cc b/ppapi/proxy/file_ref_resource.cc index 7cd96bc..4c098a5 100644 --- a/ppapi/proxy/file_ref_resource.cc +++ b/ppapi/proxy/file_ref_resource.cc @@ -22,7 +22,7 @@ namespace proxy { FileRefResource::FileRefResource( Connection connection, PP_Instance instance, - const FileRefCreateInfo& create_info) + const FileRef_CreateInfo& create_info) : PluginResource(connection, instance), create_info_(create_info), file_system_resource_(create_info.file_system_plugin_resource) { @@ -34,26 +34,19 @@ FileRefResource::FileRefResource( create_info_.internal_path.erase(path_size - 1, 1); path_var_ = new StringVar(create_info_.internal_path); + create_info_.display_name = GetNameForInternalFilePath( create_info_.internal_path); } name_var_ = new StringVar(create_info_.display_name); - if (create_info_.browser_pending_host_resource_id != 0 && - create_info_.renderer_pending_host_resource_id != 0) { - AttachToPendingHost(BROWSER, create_info_.browser_pending_host_resource_id); - AttachToPendingHost(RENDERER, - create_info_.renderer_pending_host_resource_id); + if (create_info_.pending_host_resource_id != 0) { + AttachToPendingHost(BROWSER, create_info_.pending_host_resource_id); } else { - CHECK(create_info_.browser_pending_host_resource_id == 0); - CHECK(create_info_.renderer_pending_host_resource_id == 0); CHECK(create_info_.file_system_type != PP_FILESYSTEMTYPE_EXTERNAL); SendCreate(BROWSER, PpapiHostMsg_FileRef_CreateInternal( create_info.file_system_plugin_resource, create_info.internal_path)); - SendCreate(RENDERER, PpapiHostMsg_FileRef_CreateInternal( - create_info.file_system_plugin_resource, - create_info.internal_path)); } } @@ -64,7 +57,7 @@ FileRefResource::~FileRefResource() { PP_Resource FileRefResource::CreateFileRef( Connection connection, PP_Instance instance, - const FileRefCreateInfo& create_info) { + const FileRef_CreateInfo& create_info) { // If we have a valid file_system resource, ensure that its type matches that // of the fs_type parameter. if (create_info.file_system_plugin_resource != 0) { @@ -89,7 +82,9 @@ PP_Resource FileRefResource::CreateFileRef( } thunk::PPB_FileRef_API* FileRefResource::AsPPB_FileRef_API() { - return this; + // TODO: return "this" once we update PPB_FileRef_API. + NOTREACHED(); + return NULL; } PP_FileSystemType FileRefResource::GetFileSystemType() const { @@ -116,7 +111,7 @@ PP_Resource FileRefResource::GetParent() { pos++; std::string parent_path = create_info_.internal_path.substr(0, pos); - ppapi::FileRefCreateInfo parent_info; + ppapi::FileRef_CreateInfo parent_info; parent_info.file_system_type = create_info_.file_system_type; parent_info.internal_path = parent_path; parent_info.display_name = GetNameForInternalFilePath(parent_path); @@ -189,9 +184,33 @@ int32_t FileRefResource::ReadDirectoryEntries( return PP_OK_COMPLETIONPENDING; } -const FileRefCreateInfo& FileRefResource::GetCreateInfo() const { +/* +const FileRef_CreateInfo& FileRefResource::GetCreateInfo() const { return create_info_; } +*/ +const PPB_FileRef_CreateInfo& FileRefResource::GetCreateInfo() const { + // FIXME + NOTREACHED(); + PPB_FileRef_CreateInfo *info = new PPB_FileRef_CreateInfo(); + return *info; +} + +// TODO(teravest): Remove this when we are finished moving to the new proxy. +int32_t FileRefResource::QueryInHost(linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback) { + NOTREACHED(); + return PP_ERROR_FAILED; +} + +// TODO(teravest): Remove this when we are finished moving to the new proxy. +int32_t FileRefResource::ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<TrackedCallback> callback) { + NOTREACHED(); + return PP_ERROR_FAILED; +} PP_Var FileRefResource::GetAbsolutePath() { if (!absolute_path_var_.get()) { @@ -229,7 +248,7 @@ void FileRefResource::OnDirectoryEntriesReply( const PP_ArrayOutput& output, scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params, - const std::vector<ppapi::FileRefCreateInfo>& infos, + const std::vector<ppapi::FileRef_CreateInfo>& infos, const std::vector<PP_FileType>& file_types) { if (!TrackedCallback::IsPending(callback)) return; diff --git a/ppapi/proxy/file_ref_resource.h b/ppapi/proxy/file_ref_resource.h index f982438..82570fb 100644 --- a/ppapi/proxy/file_ref_resource.h +++ b/ppapi/proxy/file_ref_resource.h @@ -29,7 +29,7 @@ class PPAPI_PROXY_EXPORT FileRefResource public: static PP_Resource CreateFileRef(Connection connection, PP_Instance instance, - const FileRefCreateInfo& info); + const FileRef_CreateInfo& info); virtual ~FileRefResource(); @@ -55,7 +55,13 @@ class PPAPI_PROXY_EXPORT FileRefResource virtual int32_t ReadDirectoryEntries( const PP_ArrayOutput& output, scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual const FileRefCreateInfo& GetCreateInfo() const OVERRIDE; + virtual const PPB_FileRef_CreateInfo& GetCreateInfo() const OVERRIDE; + virtual int32_t QueryInHost(linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<TrackedCallback> callback) OVERRIDE; // Private API virtual PP_Var GetAbsolutePath() OVERRIDE; @@ -63,7 +69,7 @@ class PPAPI_PROXY_EXPORT FileRefResource private: FileRefResource(Connection connection, PP_Instance instance, - const FileRefCreateInfo& info); + const FileRef_CreateInfo& info); void RunTrackedCallback(scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params); @@ -77,11 +83,11 @@ class PPAPI_PROXY_EXPORT FileRefResource const PP_ArrayOutput& output, scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params, - const std::vector<ppapi::FileRefCreateInfo>& infos, + const std::vector<ppapi::FileRef_CreateInfo>& infos, const std::vector<PP_FileType>& file_types); // Populated after creation. - FileRefCreateInfo create_info_; + FileRef_CreateInfo create_info_; // Some file ref operations may fail if the the file system resource inside // create_info_ is destroyed. Therefore, we explicitly hold a reference to diff --git a/ppapi/proxy/flash_drm_resource.cc b/ppapi/proxy/flash_drm_resource.cc index 889aa72..a4be23b 100644 --- a/ppapi/proxy/flash_drm_resource.cc +++ b/ppapi/proxy/flash_drm_resource.cc @@ -7,8 +7,9 @@ #include "base/bind.h" #include "ppapi/c/pp_errors.h" #include "ppapi/proxy/dispatch_reply_message.h" -#include "ppapi/proxy/file_ref_resource.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" +#include "ppapi/shared_impl/ppb_file_ref_shared.h" #include "ppapi/shared_impl/var.h" namespace ppapi { @@ -87,14 +88,10 @@ void FlashDRMResource::OnPluginMsgGetVoucherFileReply( PP_Resource* dest, scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params, - const FileRefCreateInfo& file_info) { + const PPB_FileRef_CreateInfo& file_info) { if (TrackedCallback::IsPending(callback)) { - if (params.result() == PP_OK) { - *dest = FileRefResource::CreateFileRef( - connection(), - pp_instance(), - file_info); - } + if (params.result() == PP_OK) + *dest = PPB_FileRef_Proxy::DeserializeFileRef(file_info); callback->Run(params.result()); } } diff --git a/ppapi/proxy/flash_drm_resource.h b/ppapi/proxy/flash_drm_resource.h index 9a4b31c..12c71e8 100644 --- a/ppapi/proxy/flash_drm_resource.h +++ b/ppapi/proxy/flash_drm_resource.h @@ -11,7 +11,7 @@ #include "ppapi/thunk/ppb_flash_drm_api.h" namespace ppapi { -struct FileRefCreateInfo; +struct PPB_FileRef_CreateInfo; } namespace ppapi { @@ -44,7 +44,7 @@ class FlashDRMResource void OnPluginMsgGetVoucherFileReply(PP_Resource* dest, scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params, - const FileRefCreateInfo& file_info); + const PPB_FileRef_CreateInfo& file_info); DISALLOW_COPY_AND_ASSIGN(FlashDRMResource); }; diff --git a/ppapi/proxy/flash_file_resource.cc b/ppapi/proxy/flash_file_resource.cc index ce7a2ce..1387eb7 100644 --- a/ppapi/proxy/flash_file_resource.cc +++ b/ppapi/proxy/flash_file_resource.cc @@ -13,7 +13,6 @@ #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" namespace ppapi { namespace proxy { diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index a72f472..115516f 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -101,6 +101,7 @@ #include "ppapi/proxy/ppb_broker_proxy.h" #include "ppapi/proxy/ppb_buffer_proxy.h" #include "ppapi/proxy/ppb_core_proxy.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/proxy/ppb_flash_message_loop_proxy.h" #include "ppapi/proxy/ppb_graphics_3d_proxy.h" #include "ppapi/proxy/ppb_image_data_proxy.h" diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 2793e5f..f108812 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -202,12 +202,11 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::DirEntry) IPC_STRUCT_TRAITS_MEMBER(is_dir) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(ppapi::FileRefCreateInfo) +IPC_STRUCT_TRAITS_BEGIN(ppapi::FileRef_CreateInfo) IPC_STRUCT_TRAITS_MEMBER(file_system_type) IPC_STRUCT_TRAITS_MEMBER(internal_path) IPC_STRUCT_TRAITS_MEMBER(display_name) - IPC_STRUCT_TRAITS_MEMBER(browser_pending_host_resource_id) - IPC_STRUCT_TRAITS_MEMBER(renderer_pending_host_resource_id) + IPC_STRUCT_TRAITS_MEMBER(pending_host_resource_id) IPC_STRUCT_TRAITS_MEMBER(file_system_plugin_resource) IPC_STRUCT_TRAITS_END() @@ -299,7 +298,8 @@ IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(ppapi::URLRequestInfoData::BodyItem) IPC_STRUCT_TRAITS_MEMBER(is_file) IPC_STRUCT_TRAITS_MEMBER(data) - IPC_STRUCT_TRAITS_MEMBER(file_ref_pp_resource) + // Note: we don't serialize file_ref. + IPC_STRUCT_TRAITS_MEMBER(file_ref_host_resource) IPC_STRUCT_TRAITS_MEMBER(start_offset) IPC_STRUCT_TRAITS_MEMBER(number_of_bytes) IPC_STRUCT_TRAITS_MEMBER(expected_last_modified_time) @@ -486,6 +486,30 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, ppapi::proxy::SerializedHandle /* socket_handle */, 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 */, + uint32_t /* callback_id */, + int32_t /* result */) + +IPC_MESSAGE_ROUTED4( + PpapiMsg_PPBFileRef_QueryCallbackComplete, + ppapi::HostResource /* resource */, + PP_FileInfo /* file_info */, + uint32_t /* callback_id */, + int32_t /* result */) + +IPC_MESSAGE_ROUTED5( + PpapiMsg_PPBFileRef_ReadDirectoryEntriesCallbackComplete, + ppapi::HostResource /* resource */, + std::vector<ppapi::PPB_FileRef_CreateInfo> /* files */, + std::vector<PP_FileType> /* file_types */, + uint32_t /* callback_id */, + int32_t /* result */) + // PPB_FileSystem. IPC_MESSAGE_ROUTED2( PpapiMsg_PPBFileSystem_OpenComplete, @@ -748,6 +772,43 @@ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_AddRefResource, 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 */, + std::string /* path */, + ppapi::PPB_FileRef_CreateInfo /* result */) +IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBFileRef_GetParent, + ppapi::HostResource /* file_ref */, + ppapi::PPB_FileRef_CreateInfo /* result */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileRef_MakeDirectory, + ppapi::HostResource /* file_ref */, + PP_Bool /* make_ancestors */, + uint32_t /* callback_id */) +IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBFileRef_Touch, + ppapi::HostResource /* file_ref */, + PP_Time /* last_access */, + PP_Time /* last_modified */, + uint32_t /* callback_id */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBFileRef_Delete, + ppapi::HostResource /* file_ref */, + uint32_t /* callback_id */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileRef_Rename, + ppapi::HostResource /* file_ref */, + ppapi::HostResource /* new_file_ref */, + uint32_t /* callback_id */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBFileRef_Query, + ppapi::HostResource /* file_ref */, + uint32_t /* callback_id */) +IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBFileRef_GetAbsolutePath, + ppapi::HostResource /* file_ref */, + ppapi::proxy::SerializedVar /* result */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBFileRef_ReadDirectoryEntries, + ppapi::HostResource /* file_ref */, + uint32_t /* callback_id */) + // PPB_Graphics3D. IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBGraphics3D_Create, PP_Instance /* instance */, @@ -1141,6 +1202,7 @@ IPC_MESSAGE_ROUTED2( ppapi::proxy::ResourceMessageReplyParams /* reply_params */, IPC::Message /* nested_msg */) + IPC_SYNC_MESSAGE_CONTROL2_2(PpapiHostMsg_ResourceSyncCall, ppapi::proxy::ResourceMessageCallParams /* call_params */, IPC::Message /* nested_msg */, @@ -1214,7 +1276,7 @@ IPC_MESSAGE_CONTROL4(PpapiHostMsg_FileChooser_Show, std::string /* suggested_file_name */, std::vector<std::string> /* accept_mime_types */) IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileChooser_ShowReply, - std::vector<ppapi::FileRefCreateInfo> /* files */) + std::vector<ppapi::PPB_FileRef_CreateInfo> /* files */) // FileIO IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Create) @@ -1290,10 +1352,10 @@ IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileRef_QueryReply, // location indicated by the FileRef. IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileRef_ReadDirectoryEntries) -// FileRefCreateInfo does not provide file type information, so two +// FileRef_CreateInfo does not provide file type information, so two // corresponding vectors are returned. IPC_MESSAGE_CONTROL2(PpapiPluginMsg_FileRef_ReadDirectoryEntriesReply, - std::vector<ppapi::FileRefCreateInfo> /* files */, + std::vector<ppapi::FileRef_CreateInfo> /* files */, std::vector<PP_FileType> /* file_types */) // Requests that the browser reply with the absolute path to the indicated @@ -1334,7 +1396,7 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_FlashDRM_GetVoucherFile) // Reply message for GetVoucherFile which contains the CreateInfo for a // PPB_FileRef which points to the voucher file. IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FlashDRM_GetVoucherFileReply, - ppapi::FileRefCreateInfo /* file_info */) + ppapi::PPB_FileRef_CreateInfo /* file_info */) // Gamepad. IPC_MESSAGE_CONTROL0(PpapiHostMsg_Gamepad_Create) @@ -1713,6 +1775,30 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_BrowserFontSingleton_GetFontFamilies) IPC_MESSAGE_CONTROL1(PpapiPluginMsg_BrowserFontSingleton_GetFontFamiliesReply, std::string /* families */) +// FileRef. +// Requests that the browser reply with file system and path information about +// the resource indicated in |params| which exists in the given +// |child_process_id|. |routing_id| is sent so that the reply can be routed +// properly in the renderer. +// Only sent from the renderer to the browser. +IPC_MESSAGE_CONTROL4(PpapiHostMsg_FileRef_GetInfoForRenderer, + int /* routing_id */, + int /* child_process_id */, + int32_t /* sequence */, + std::vector<PP_Resource> /* resources */) + +// Reply to PpapiHostMsg_FileRef_GetInfoForRenderer with a sequence number for +// invoking the right callback, |fs_type| which indicates the file system, and +// path information in either |file_system_url_spec| (for internal file systems) +// or |external_path| (for external file systems). +// Only sent from the browser to the renderer. +IPC_MESSAGE_ROUTED5(PpapiHostMsg_FileRef_GetInfoForRendererReply, + int32_t /* sequence */, + std::vector<PP_Resource> /* resources */, + std::vector<PP_FileSystemType> /* fs_type */, + std::vector<std::string> /* file_system_url_spec */, + std::vector<base::FilePath> /* external_path */) + // Flash ----------------------------------------------------------------------- IPC_MESSAGE_CONTROL0(PpapiHostMsg_Flash_Create) diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc index 5d4345f..ca25f82 100644 --- a/ppapi/proxy/ppapi_param_traits.cc +++ b/ppapi/proxy/ppapi_param_traits.cc @@ -175,6 +175,36 @@ 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 +void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Write(Message* m, + const param_type& p) { + ParamTraits<ppapi::HostResource>::Write(m, p.resource); + ParamTraits<int>::Write(m, p.file_system_type); + ParamTraits<std::string>::Write(m, p.path); + ParamTraits<std::string>::Write(m, p.name); + ParamTraits<PP_Resource>::Write(m, p.file_system_plugin_resource); +} + +// static +bool ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Read(const Message* m, + PickleIterator* iter, + param_type* r) { + return + ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) && + ParamTraits<int>::Read(m, iter, &r->file_system_type) && + ParamTraits<std::string>::Read(m, iter, &r->path) && + ParamTraits<std::string>::Read(m, iter, &r->name) && + ParamTraits<PP_Resource>::Read(m, iter, &r->file_system_plugin_resource); +} + +// static +void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Log(const param_type& p, + std::string* l) { +} + // HostResource ---------------------------------------------------------------- // static @@ -244,6 +274,28 @@ void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Log( std::string* l) { } +// std::vector<PPB_FileRef_CreateInfo> ----------------------------------------- + +void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Write( + Message* m, + const param_type& p) { + WriteVectorWithoutCopy(m, p); +} + +// static +bool ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Read( + const Message* m, + PickleIterator* iter, + param_type* r) { + return ReadVectorWithoutCopy(m, iter, r); +} + +// static +void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Log( + const param_type& p, + std::string* l) { +} + // ppapi::PpapiPermissions ----------------------------------------------------- void ParamTraits<ppapi::PpapiPermissions>::Write(Message* m, diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h index b56ec3e..f56415a8 100644 --- a/ppapi/proxy/ppapi_param_traits.h +++ b/ppapi/proxy/ppapi_param_traits.h @@ -17,6 +17,7 @@ #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" #include "ppapi/shared_impl/socket_option_data.h" struct PP_FileInfo; @@ -76,6 +77,15 @@ 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; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + template<> struct PPAPI_PROXY_EXPORT ParamTraits< ppapi::proxy::PPBURLLoader_UpdateProgress_Params> { @@ -144,6 +154,15 @@ struct PPAPI_PROXY_EXPORT ParamTraits< }; template<> +struct PPAPI_PROXY_EXPORT ParamTraits< std::vector< + ppapi::PPB_FileRef_CreateInfo> > { + typedef std::vector<ppapi::PPB_FileRef_CreateInfo> param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template<> struct PPAPI_PROXY_EXPORT ParamTraits<ppapi::PpapiPermissions> { typedef ppapi::PpapiPermissions param_type; static void Write(Message* m, const param_type& p); diff --git a/ppapi/proxy/ppb_file_ref_proxy.cc b/ppapi/proxy/ppb_file_ref_proxy.cc new file mode 100644 index 0000000..62c55da --- /dev/null +++ b/ppapi/proxy/ppb_file_ref_proxy.cc @@ -0,0 +1,549 @@ +// 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/ppb_file_ref_proxy.h" + +#include <map> + +#include "base/bind.h" +#include "ppapi/c/pp_directory_entry.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_file_ref.h" +#include "ppapi/c/private/ppb_file_ref_private.h" +#include "ppapi/c/private/ppb_proxy_private.h" +#include "ppapi/proxy/enter_proxy.h" +#include "ppapi/proxy/host_dispatcher.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/serialized_var.h" +#include "ppapi/shared_impl/array_writer.h" +#include "ppapi/shared_impl/ppb_file_ref_shared.h" +#include "ppapi/shared_impl/scoped_pp_resource.h" +#include "ppapi/shared_impl/tracked_callback.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_FileRef_API; +using ppapi::thunk::ResourceCreationAPI; + +namespace ppapi { +namespace proxy { + +namespace { + +void ReleaseEntries(const std::vector<PP_DirectoryEntry>& entries) { + ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker(); + for (std::vector<PP_DirectoryEntry>::const_iterator it = entries.begin(); + it != entries.end(); ++it) + tracker->ReleaseResource(it->file_ref); +} + +} // namespace + +class FileRef : public PPB_FileRef_Shared { + public: + explicit FileRef(const PPB_FileRef_CreateInfo& info); + virtual ~FileRef(); + + // Resource overrides. + virtual void LastPluginRefWasDeleted() OVERRIDE; + + // PPB_FileRef_API implementation (not provided by PPB_FileRef_Shared). + virtual PP_Resource GetParent() OVERRIDE; + virtual int32_t MakeDirectory( + PP_Bool make_ancestors, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Touch(PP_Time last_access_time, + PP_Time last_modified_time, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Delete(scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Rename(PP_Resource new_file_ref, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t Query(PP_FileInfo* info, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t ReadDirectoryEntries( + const PP_ArrayOutput& output, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t QueryInHost( + linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual int32_t ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<TrackedCallback> callback) OVERRIDE; + virtual PP_Var GetAbsolutePath() OVERRIDE; + + // Executes the pending callback with the given ID. See pending_callbacks_. + void ExecuteCallback(uint32_t callback_id, int32_t result); + int32_t SetFileInfo(uint32_t callback_id, const PP_FileInfo& info); + int32_t SetReadDirectoryEntriesOutput( + uint32_t callback_id, + const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, + const std::vector<PP_FileType>& file_types); + + private: + PluginDispatcher* GetDispatcher() const { + return PluginDispatcher::GetForResource(this); + } + + // Adds a callback to the list and returns its ID. + uint32_t SendCallback(scoped_refptr<TrackedCallback> callback); + + // This class can have any number of out-standing requests with completion + // callbacks, in contrast to most resources which have one possible pending + // callback pending (like a Flush callback). + // + // To keep track of them, assign integer IDs to the callbacks, which is how + // the callback will be identified when it's passed to the host and then + // back here. Use unsigned so that overflow is well-defined. + uint32_t next_callback_id_; + typedef std::map<uint32_t, + scoped_refptr<TrackedCallback> > PendingCallbackMap; + PendingCallbackMap pending_callbacks_; + + // Used to keep pointers to PP_FileInfo instances that are written before + // callbacks are invoked. The id of a pending file info will match that of + // the corresponding callback. + typedef std::map<uint32_t, PP_FileInfo*> PendingFileInfoMap; + PendingFileInfoMap pending_file_infos_; + + // Used to keep PP_ArrayOutput instances that are written before callbacks + // are invoked. The id of a pending array output will match that of the + // corresponding callback. + typedef std::map<uint32_t, PP_ArrayOutput> + PendingReadDirectoryEntriesOutputMap; + PendingReadDirectoryEntriesOutputMap pending_read_entries_outputs_; + + // Holds a reference on plugin side when running out of process, so that + // FileSystem won't die before FileRef. See PPB_FileRef_Impl for + // corresponding code for in-process mode. Note that this workaround will + // be no longer needed after FileRef refactoring. + ScopedPPResource file_system_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef); +}; + +FileRef::FileRef(const PPB_FileRef_CreateInfo& info) + : PPB_FileRef_Shared(OBJECT_IS_PROXY, info), + next_callback_id_(0u), + file_system_(info.file_system_plugin_resource) { +} + +FileRef::~FileRef() { + // The callbacks map should have been cleared by LastPluginRefWasDeleted. + DCHECK(pending_callbacks_.empty()); + DCHECK(pending_file_infos_.empty()); + DCHECK(pending_read_entries_outputs_.empty()); +} + +void FileRef::LastPluginRefWasDeleted() { + // The callback tracker will abort our callbacks for us. + pending_callbacks_.clear(); + pending_file_infos_.clear(); + pending_read_entries_outputs_.clear(); +} + +PP_Resource FileRef::GetParent() { + PPB_FileRef_CreateInfo create_info; + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent( + API_ID_PPB_FILE_REF, host_resource(), &create_info)); + return PPB_FileRef_Proxy::DeserializeFileRef(create_info); +} + +int32_t FileRef::MakeDirectory(PP_Bool make_ancestors, + scoped_refptr<TrackedCallback> callback) { + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_MakeDirectory( + API_ID_PPB_FILE_REF, host_resource(), make_ancestors, + SendCallback(callback))); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileRef::Touch(PP_Time last_access_time, + PP_Time last_modified_time, + scoped_refptr<TrackedCallback> callback) { + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Touch( + API_ID_PPB_FILE_REF, host_resource(), last_access_time, + last_modified_time, SendCallback(callback))); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileRef::Delete(scoped_refptr<TrackedCallback> callback) { + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Delete( + API_ID_PPB_FILE_REF, host_resource(), SendCallback(callback))); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileRef::Rename(PP_Resource new_file_ref, + scoped_refptr<TrackedCallback> callback) { + Resource* new_file_ref_object = + PpapiGlobals::Get()->GetResourceTracker()->GetResource(new_file_ref); + if (!new_file_ref_object || + new_file_ref_object->host_resource().instance() != pp_instance()) + return PP_ERROR_BADRESOURCE; + + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename( + API_ID_PPB_FILE_REF, host_resource(), + new_file_ref_object->host_resource(), SendCallback(callback))); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileRef::Query(PP_FileInfo* info, + scoped_refptr<TrackedCallback> callback) { + // Store the pending file info id. + uint32_t id = SendCallback(callback); + pending_file_infos_[id] = info; + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Query( + API_ID_PPB_FILE_REF, host_resource(), id)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileRef::ReadDirectoryEntries( + const PP_ArrayOutput& output, + scoped_refptr<TrackedCallback> callback) { + // Store the pending read entries output id. + uint32_t id = SendCallback(callback); + pending_read_entries_outputs_[id] = output; + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_ReadDirectoryEntries( + API_ID_PPB_FILE_REF, host_resource(), id)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t FileRef::QueryInHost( + linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback) { + NOTREACHED(); + return PP_ERROR_FAILED; +} + +int32_t FileRef::ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<TrackedCallback> callback) { + NOTREACHED(); + return PP_ERROR_FAILED; +} + +PP_Var FileRef::GetAbsolutePath() { + ReceiveSerializedVarReturnValue result; + GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetAbsolutePath( + API_ID_PPB_FILE_REF, host_resource(), &result)); + return result.Return(GetDispatcher()); +} + +void FileRef::ExecuteCallback(uint32_t callback_id, int32_t result) { + PendingCallbackMap::iterator found = pending_callbacks_.find(callback_id); + if (found == pending_callbacks_.end()) { + // This will happen when the plugin deletes its resource with a pending + // callback. The callback will be locally issued with an ABORTED call while + // the operation may still be pending in the renderer. + return; + } + + // Executing the callback may mutate the callback list. + scoped_refptr<TrackedCallback> callback = found->second; + pending_callbacks_.erase(found); + callback->Run(result); +} + +int32_t FileRef::SetFileInfo(uint32_t callback_id, const PP_FileInfo& info) { + PendingFileInfoMap::iterator found = pending_file_infos_.find(callback_id); + if (found == pending_file_infos_.end()) + return PP_ERROR_FAILED; + PP_FileInfo* target_info = found->second; + *target_info = info; + pending_file_infos_.erase(found); + return PP_OK; +} + +int32_t FileRef::SetReadDirectoryEntriesOutput( + uint32_t callback_id, + const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, + const std::vector<PP_FileType>& file_types) { + PendingReadDirectoryEntriesOutputMap::iterator found = + pending_read_entries_outputs_.find(callback_id); + if (found == pending_read_entries_outputs_.end()) + return PP_ERROR_FAILED; + + PP_ArrayOutput output = found->second; + pending_read_entries_outputs_.erase(found); + + std::vector<PP_DirectoryEntry> entries; + for (size_t i = 0; i < infos.size(); ++i) { + PP_DirectoryEntry entry; + entry.file_ref = PPB_FileRef_Proxy::DeserializeFileRef(infos[i]); + entry.file_type = file_types[i]; + entries.push_back(entry); + } + + ArrayWriter writer(output); + if (!writer.is_valid()) { + ReleaseEntries(entries); + return PP_ERROR_BADARGUMENT; + } + + writer.StoreVector(entries); + return PP_OK; +} + +uint32_t FileRef::SendCallback(scoped_refptr<TrackedCallback> callback) { + // In extreme cases the IDs may wrap around, so avoid duplicates. + while (pending_callbacks_.count(next_callback_id_)) + ++next_callback_id_; + + pending_callbacks_[next_callback_id_] = callback; + return next_callback_id_++; +} + +PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher) + : InterfaceProxy(dispatcher), + callback_factory_(this) { +} + +PPB_FileRef_Proxy::~PPB_FileRef_Proxy() { +} + +// static +PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Instance instance, + PP_Resource file_system, + const char* path) { + PPB_FileRef_CreateInfo create_info; + PluginDispatcher::GetForInstance(instance)->Send( + new PpapiHostMsg_PPBFileRef_Create( + API_ID_PPB_FILE_REF, instance, file_system, path, &create_info)); + return PPB_FileRef_Proxy::DeserializeFileRef(create_info); +} + +bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_FileRef_Proxy, msg) +#if !defined(OS_NACL) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Create, OnMsgCreate) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetParent, OnMsgGetParent) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_MakeDirectory, + OnMsgMakeDirectory) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Touch, OnMsgTouch) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Delete, OnMsgDelete) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Rename, OnMsgRename) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Query, OnMsgQuery) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_ReadDirectoryEntries, + OnMsgReadDirectoryEntries) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetAbsolutePath, + OnMsgGetAbsolutePath) +#endif // !defined(OS_NACL) + + IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_CallbackComplete, + OnMsgCallbackComplete) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_QueryCallbackComplete, + OnMsgQueryCallbackComplete) + IPC_MESSAGE_HANDLER( + PpapiMsg_PPBFileRef_ReadDirectoryEntriesCallbackComplete, + OnMsgReadDirectoryEntriesCallbackComplete) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +// static +void PPB_FileRef_Proxy::SerializeFileRef(PP_Resource file_ref, + PPB_FileRef_CreateInfo* result) { + EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, false); + if (enter.succeeded()) + *result = enter.object()->GetCreateInfo(); +} + +// static +PP_Resource PPB_FileRef_Proxy::DeserializeFileRef( + const PPB_FileRef_CreateInfo& serialized) { + if (serialized.resource.is_null()) + return 0; // Resource invalid. + return (new FileRef(serialized))->GetReference(); +} + +#if !defined(OS_NACL) +void PPB_FileRef_Proxy::OnMsgCreate(PP_Instance pp_instance, + PP_Resource file_system, + const std::string& path, + PPB_FileRef_CreateInfo* result) { + thunk::EnterResourceCreation enter(pp_instance); + if (enter.failed()) + return; + + PP_Resource resource = enter.functions()->CreateFileRef( + pp_instance, file_system, path.c_str()); + if (!resource) + return; // CreateInfo default constructor initializes to 0. + SerializeFileRef(resource, result); +} + +void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource, + PPB_FileRef_CreateInfo* result) { + EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); + if (enter.succeeded()) + SerializeFileRef(enter.object()->GetParent(), result); +} + +void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource, + PP_Bool make_ancestors, + uint32_t callback_id) { + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( + host_resource, callback_factory_, + &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); + if (enter.succeeded()) { + enter.SetResult(enter.object()->MakeDirectory(make_ancestors, + enter.callback())); + } +} + +void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource, + PP_Time last_access, + PP_Time last_modified, + uint32_t callback_id) { + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( + host_resource, callback_factory_, + &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); + if (enter.succeeded()) { + enter.SetResult(enter.object()->Touch(last_access, last_modified, + enter.callback())); + } +} + +void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource, + uint32_t callback_id) { + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( + host_resource, callback_factory_, + &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); + if (enter.succeeded()) + enter.SetResult(enter.object()->Delete(enter.callback())); +} + +void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref, + const HostResource& new_file_ref, + uint32_t callback_id) { + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( + file_ref, callback_factory_, + &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id); + if (enter.succeeded()) { + enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(), + enter.callback())); + } +} + +void PPB_FileRef_Proxy::OnMsgQuery(const HostResource& file_ref, + uint32_t callback_id) { + linked_ptr<PP_FileInfo> info(new PP_FileInfo()); + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( + file_ref, callback_factory_, + &PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost, file_ref, + info, callback_id); + if (enter.succeeded()) + enter.SetResult(enter.object()->QueryInHost(info, enter.callback())); +} + +void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource, + SerializedVarReturnValue result) { + EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); + if (enter.succeeded()) + result.Return(dispatcher(), enter.object()->GetAbsolutePath()); +} + +void PPB_FileRef_Proxy::OnMsgReadDirectoryEntries(const HostResource& file_ref, + uint32_t callback_id) { + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files( + new std::vector<ppapi::PPB_FileRef_CreateInfo>()); + linked_ptr<std::vector<PP_FileType> > file_types( + new std::vector<PP_FileType>()); + HostCallbackParams params(file_ref, callback_id); + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( + file_ref, callback_factory_, + &PPB_FileRef_Proxy::OnReadDirectoryEntriesCallbackCompleteInHost, + params, files, file_types); + if (enter.succeeded()) { + enter.SetResult(enter.object()->ReadDirectoryEntriesInHost( + files, file_types, enter.callback())); + } +} + +#endif // !defined(OS_NACL) + +void PPB_FileRef_Proxy::OnMsgCallbackComplete( + const HostResource& host_resource, + uint32_t callback_id, + int32_t result) { + // Forward the callback info to the plugin resource. + EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); + if (enter.succeeded()) + static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result); +} + +void PPB_FileRef_Proxy::OnMsgQueryCallbackComplete( + const HostResource& host_resource, + const PP_FileInfo& info, + uint32_t callback_id, + int32_t result) { + EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); + if (!enter.succeeded()) + return; + + if (result == PP_OK) { + result = static_cast<FileRef*>(enter.object())->SetFileInfo( + callback_id, info); + } + static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result); +} + +void PPB_FileRef_Proxy::OnMsgReadDirectoryEntriesCallbackComplete( + const HostResource& host_resource, + const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, + const std::vector<PP_FileType>& file_types, + uint32_t callback_id, + int32_t result) { + CHECK_EQ(infos.size(), file_types.size()); + + EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); + if (!enter.succeeded()) + return; + + if (result == PP_OK) { + result = + static_cast<FileRef*>(enter.object())->SetReadDirectoryEntriesOutput( + callback_id, infos, file_types); + } + static_cast<FileRef*>(enter.object())->ExecuteCallback( + callback_id, result); +} + +#if !defined(OS_NACL) +void PPB_FileRef_Proxy::OnCallbackCompleteInHost( + int32_t result, + const HostResource& host_resource, + uint32_t callback_id) { + // Execute OnMsgCallbackComplete in the plugin process. + Send(new PpapiMsg_PPBFileRef_CallbackComplete( + API_ID_PPB_FILE_REF, host_resource, callback_id, result)); +} + +void PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost( + int32_t result, + const HostResource& host_resource, + linked_ptr<PP_FileInfo> info, + uint32_t callback_id) { + Send(new PpapiMsg_PPBFileRef_QueryCallbackComplete( + API_ID_PPB_FILE_REF, host_resource, *info, callback_id, result)); +} + +void PPB_FileRef_Proxy::OnReadDirectoryEntriesCallbackCompleteInHost( + int32_t result, + HostCallbackParams params, + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types) { + Send(new PpapiMsg_PPBFileRef_ReadDirectoryEntriesCallbackComplete( + API_ID_PPB_FILE_REF, params.host_resource, + *files, *file_types, params.callback_id, result)); +} + +#endif // !defined(OS_NACL) + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/ppb_file_ref_proxy.h b/ppapi/proxy/ppb_file_ref_proxy.h new file mode 100644 index 0000000..cbfadb5 --- /dev/null +++ b/ppapi/proxy/ppb_file_ref_proxy.h @@ -0,0 +1,138 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PROXY_PPB_FILE_REF_PROXY_H_ +#define PPAPI_PROXY_PPB_FILE_REF_PROXY_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/linked_ptr.h" +#include "ppapi/c/pp_file_info.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_time.h" +#include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/ppapi_proxy_export.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" +#include "ppapi/shared_impl/host_resource.h" +#include "ppapi/utility/completion_callback_factory.h" + +namespace ppapi { + +struct PPB_FileRef_CreateInfo; + +namespace proxy { + +class SerializedVarReturnValue; + +class PPAPI_PROXY_EXPORT PPB_FileRef_Proxy + : public NON_EXPORTED_BASE(InterfaceProxy) { + public: + explicit PPB_FileRef_Proxy(Dispatcher* dispatcher); + virtual ~PPB_FileRef_Proxy(); + + static PP_Resource CreateProxyResource(PP_Instance instance, + PP_Resource file_system, + const char* path); + static PP_Resource CreateProxyResource( + const PPB_FileRef_CreateInfo& serialized); + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + // Takes a resource in the host and converts it into a serialized file ref + // "create info" for reconstitution in the plugin. This struct contains all + // the necessary information about the file ref. + // + // Various PPAPI functions return file refs from various interfaces, so this + // function is public so anybody can send a file ref. + static void SerializeFileRef(PP_Resource file_ref, + PPB_FileRef_CreateInfo* result); + + // Creates a plugin resource from the given CreateInfo sent from the host. + // The value will be the result of calling SerializeFileRef on the host. + // This represents passing the resource ownership to the plugin. This + // function also checks the validity of the result and returns 0 on failure. + // + // Various PPAPI functions return file refs from various interfaces, so this + // function is public so anybody can receive a file ref. + static PP_Resource DeserializeFileRef( + const PPB_FileRef_CreateInfo& serialized); + + static const ApiID kApiID = API_ID_PPB_FILE_REF; + + private: + // Plugin -> host message handlers. + void OnMsgCreate(PP_Instance instance, + PP_Resource file_system, + const std::string& path, + PPB_FileRef_CreateInfo* result); + void OnMsgGetParent(const HostResource& host_resource, + PPB_FileRef_CreateInfo* result); + void OnMsgMakeDirectory(const HostResource& host_resource, + PP_Bool make_ancestors, + uint32_t callback_id); + void OnMsgTouch(const HostResource& host_resource, + PP_Time last_access, + PP_Time last_modified, + uint32_t callback_id); + void OnMsgDelete(const HostResource& host_resource, + uint32_t callback_id); + void OnMsgRename(const HostResource& file_ref, + const HostResource& new_file_ref, + uint32_t callback_id); + void OnMsgQuery(const HostResource& file_ref, + uint32_t callback_id); + void OnMsgGetAbsolutePath(const HostResource& host_resource, + SerializedVarReturnValue result); + void OnMsgReadDirectoryEntries(const HostResource& file_ref, + uint32_t callback_id); + + // Host -> Plugin message handlers. + void OnMsgCallbackComplete(const HostResource& host_resource, + uint32_t callback_id, + int32_t result); + void OnMsgQueryCallbackComplete(const HostResource& host_resource, + const PP_FileInfo& info, + uint32_t callback_id, + int32_t result); + void OnMsgReadDirectoryEntriesCallbackComplete( + const HostResource& host_resource, + const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, + const std::vector<PP_FileType>& file_types, + uint32_t callback_id, + int32_t result); + + struct HostCallbackParams { + HostCallbackParams(const HostResource& host_res, uint32_t cb_id) + : host_resource(host_res), callback_id(cb_id) { + } + HostResource host_resource; + uint32_t callback_id; + }; + + void OnCallbackCompleteInHost(int32_t result, + const HostResource& host_resource, + uint32_t callback_id); + void OnQueryCallbackCompleteInHost( + int32_t result, + const HostResource& host_resource, + linked_ptr<PP_FileInfo> info, + uint32_t callback_id); + void OnReadDirectoryEntriesCallbackCompleteInHost( + int32_t result, + HostCallbackParams params, + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types); + + ProxyCompletionCallbackFactory<PPB_FileRef_Proxy> callback_factory_; + + DISALLOW_COPY_AND_ASSIGN(PPB_FileRef_Proxy); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_PPB_FILE_REF_PROXY_H_ diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 88f99e32..4814c97 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -11,7 +11,6 @@ #include "ppapi/proxy/ext_crx_file_system_private_resource.h" #include "ppapi/proxy/file_chooser_resource.h" #include "ppapi/proxy/file_io_resource.h" -#include "ppapi/proxy/file_ref_resource.h" #include "ppapi/proxy/file_system_resource.h" #include "ppapi/proxy/flash_drm_resource.h" #include "ppapi/proxy/flash_font_file_resource.h" @@ -27,6 +26,7 @@ #include "ppapi/proxy/ppb_audio_proxy.h" #include "ppapi/proxy/ppb_broker_proxy.h" #include "ppapi/proxy/ppb_buffer_proxy.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/proxy/ppb_flash_message_loop_proxy.h" #include "ppapi/proxy/ppb_graphics_3d_proxy.h" #include "ppapi/proxy/ppb_image_data_proxy.h" @@ -78,10 +78,15 @@ PP_Resource ResourceCreationProxy::CreateFileIO(PP_Instance instance) { return (new FileIOResource(GetConnection(), instance))->GetReference(); } +PP_Resource ResourceCreationProxy::CreateFileRef(PP_Instance instance, + PP_Resource file_system, + const char* path) { + return PPB_FileRef_Proxy::CreateProxyResource(instance, file_system, path); +} + PP_Resource ResourceCreationProxy::CreateFileRef( - PP_Instance instance, - const FileRefCreateInfo& create_info) { - return FileRefResource::CreateFileRef(GetConnection(), instance, create_info); + const PPB_FileRef_CreateInfo& create_info) { + return PPB_FileRef_Proxy::DeserializeFileRef(create_info); } PP_Resource ResourceCreationProxy::CreateFileSystem( diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index a8101db..edca902 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -38,9 +38,11 @@ class ResourceCreationProxy : public InterfaceProxy, // ResourceCreationAPI (called in plugin). virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateFileRef(PP_Instance instance, + PP_Resource file_system, + const char* path) OVERRIDE; virtual PP_Resource CreateFileRef( - PP_Instance instance, - const FileRefCreateInfo& create_info) OVERRIDE; + const PPB_FileRef_CreateInfo& create_info) OVERRIDE; virtual PP_Resource CreateFileSystem(PP_Instance instance, PP_FileSystemType type) OVERRIDE; virtual PP_Resource CreateIMEInputEvent(PP_Instance instance, diff --git a/ppapi/proxy/url_loader_resource.cc b/ppapi/proxy/url_loader_resource.cc index 1ff0a5e..5bbc937 100644 --- a/ppapi/proxy/url_loader_resource.cc +++ b/ppapi/proxy/url_loader_resource.cc @@ -9,8 +9,8 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_url_loader.h" #include "ppapi/proxy/dispatch_reply_message.h" -#include "ppapi/proxy/file_ref_resource.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/proxy/url_request_info_resource.h" #include "ppapi/proxy/url_response_info_resource.h" #include "ppapi/shared_impl/ppapi_globals.h" @@ -158,14 +158,9 @@ int32_t URLLoaderResource::ReadResponseBody( int32_t rv = ValidateCallback(callback); if (rv != PP_OK) return rv; - if (!response_info_.get()) + if (!response_info_.get() || + !response_info_->data().body_as_file_ref.resource.is_null()) return PP_ERROR_FAILED; - - // Fail if we have a valid file ref. - // ReadResponseBody() is for reading to a user-provided buffer. - if (response_info_->data().body_as_file_ref.IsValid()) - return PP_ERROR_FAILED; - if (bytes_to_read <= 0 || !buffer) return PP_ERROR_BADARGUMENT; @@ -191,11 +186,8 @@ int32_t URLLoaderResource::FinishStreamingToFile( int32_t rv = ValidateCallback(callback); if (rv != PP_OK) return rv; - if (!response_info_.get()) - return PP_ERROR_FAILED; - - // Fail if we do not have a valid file ref. - if (!response_info_->data().body_as_file_ref.IsValid()) + if (!response_info_.get() || + response_info_->data().body_as_file_ref.resource.is_null()) return PP_ERROR_FAILED; // We may have already reached EOF. @@ -365,10 +357,10 @@ void URLLoaderResource::RunCallback(int32_t result) { void URLLoaderResource::SaveResponseInfo(const URLResponseInfoData& data) { // Create a proxy resource for the the file ref host resource if needed. PP_Resource body_as_file_ref = 0; - if (data.body_as_file_ref.IsValid()) { - body_as_file_ref = FileRefResource::CreateFileRef(connection(), - pp_instance(), - data.body_as_file_ref); + if (!data.body_as_file_ref.resource.is_null()) { + thunk::EnterResourceCreationNoLock enter(pp_instance()); + body_as_file_ref = + enter.functions()->CreateFileRef(data.body_as_file_ref); } response_info_ = new URLResponseInfoResource( connection(), pp_instance(), data, body_as_file_ref); @@ -397,4 +389,4 @@ size_t URLLoaderResource::FillUserBuffer() { } } // namespace proxy -} // namespace ppapi +} // namespace ppapi
\ No newline at end of file diff --git a/ppapi/proxy/url_response_info_resource.cc b/ppapi/proxy/url_response_info_resource.cc index 315b4a1..85dae9a 100644 --- a/ppapi/proxy/url_response_info_resource.cc +++ b/ppapi/proxy/url_response_info_resource.cc @@ -4,7 +4,7 @@ #include "ppapi/proxy/url_response_info_resource.h" -#include "ppapi/proxy/file_ref_resource.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/resource_creation_api.h" diff --git a/ppapi/shared_impl/file_ref_create_info.cc b/ppapi/shared_impl/file_ref_create_info.cc deleted file mode 100644 index 2fd3e13..0000000 --- a/ppapi/shared_impl/file_ref_create_info.cc +++ /dev/null @@ -1,50 +0,0 @@ -// 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 "ppapi/shared_impl/file_ref_create_info.h" - -#include "base/logging.h" -#include "base/strings/utf_string_conversions.h" -#include "ppapi/c/pp_file_info.h" - -namespace ppapi { - -namespace { - -std::string GetNameForExternalFilePath(const base::FilePath& in_path) { - const base::FilePath::StringType& path = in_path.value(); - size_t pos = path.rfind(base::FilePath::kSeparators[0]); - CHECK(pos != base::FilePath::StringType::npos); -#if defined(OS_WIN) - return base::WideToUTF8(path.substr(pos + 1)); -#elif defined(OS_POSIX) - return path.substr(pos + 1); -#else -#error "Unsupported platform." -#endif -} - -} // namespace - -bool FileRefCreateInfo::IsValid() const { - return file_system_type != PP_FILESYSTEMTYPE_INVALID; -} - -FileRefCreateInfo -MakeExternalFileRefCreateInfo(const base::FilePath& external_path, - const std::string& display_name, - int browser_pending_host_resource_id, - int renderer_pending_host_resource_id) { - FileRefCreateInfo info; - info.file_system_type = PP_FILESYSTEMTYPE_EXTERNAL; - if (!display_name.empty()) - info.display_name = display_name; - else - info.display_name = GetNameForExternalFilePath(external_path); - info.browser_pending_host_resource_id = browser_pending_host_resource_id; - info.renderer_pending_host_resource_id = renderer_pending_host_resource_id; - return info; -} - -} // namespace ppapi diff --git a/ppapi/shared_impl/file_ref_create_info.h b/ppapi/shared_impl/file_ref_create_info.h index 02fc8cc..a3599f7 100644 --- a/ppapi/shared_impl/file_ref_create_info.h +++ b/ppapi/shared_impl/file_ref_create_info.h @@ -10,42 +10,24 @@ #include "base/files/file_path.h" #include "ppapi/c/pp_file_info.h" #include "ppapi/c/pp_resource.h" -#include "ppapi/shared_impl/ppapi_shared_export.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 FileRefCreateInfo { - FileRefCreateInfo() : file_system_type(PP_FILESYSTEMTYPE_INVALID), - browser_pending_host_resource_id(0), - renderer_pending_host_resource_id(0), - file_system_plugin_resource(0) { } - - PPAPI_SHARED_EXPORT bool IsValid() const; - +struct FileRef_CreateInfo { PP_FileSystemType file_system_type; std::string internal_path; std::string display_name; // Used when a FileRef is created in the Renderer. - int browser_pending_host_resource_id; - int renderer_pending_host_resource_id; + int pending_host_resource_id; // Since FileRef needs to hold a FileSystem reference, we need to pass the - // resource in this CreateInfo. This struct doesn't hold any refrence on the - // file_system_plugin_resource. + // resource in this CreateInfo. PP_Resource file_system_plugin_resource; }; -// Used in the renderer when sending a FileRefCreateInfo to a plugin for a -// FileRef on an external filesystem. -PPAPI_SHARED_EXPORT FileRefCreateInfo -MakeExternalFileRefCreateInfo(const base::FilePath& external_path, - const std::string& display_name, - int browser_pending_host_resource_id, - int renderer_pending_host_resource_id); - } // namespace ppapi #endif // PPAPI_SHARED_IMPL_FILE_REF_CREATE_INFO_H diff --git a/ppapi/shared_impl/ppb_file_ref_shared.cc b/ppapi/shared_impl/ppb_file_ref_shared.cc new file mode 100644 index 0000000..a47cdb8 --- /dev/null +++ b/ppapi/shared_impl/ppb_file_ref_shared.cc @@ -0,0 +1,54 @@ +// 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_file_ref_shared.h" + +#include "base/logging.h" +#include "ppapi/shared_impl/var.h" + +namespace ppapi { + +PPB_FileRef_Shared::PPB_FileRef_Shared(ResourceObjectType type, + const PPB_FileRef_CreateInfo& info) + : Resource(type, info.resource), + create_info_(info) { + if (type == OBJECT_IS_IMPL) { + // Resource's constructor assigned a PP_Resource, so we can fill out our + // host resource now. + create_info_.resource = host_resource(); + } +} + +PPB_FileRef_Shared::~PPB_FileRef_Shared() { +} + +thunk::PPB_FileRef_API* PPB_FileRef_Shared::AsPPB_FileRef_API() { + return this; +} + +PP_FileSystemType PPB_FileRef_Shared::GetFileSystemType() const { + return static_cast<PP_FileSystemType>(create_info_.file_system_type); +} + +PP_Var PPB_FileRef_Shared::GetName() const { + if (!name_var_.get()) { + name_var_ = new StringVar(create_info_.name); + } + return name_var_->GetPPVar(); +} + +PP_Var PPB_FileRef_Shared::GetPath() const { + if (create_info_.file_system_type == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_MakeUndefined(); + if (!path_var_.get()) { + path_var_ = new StringVar(create_info_.path); + } + return path_var_->GetPPVar(); +} + +const PPB_FileRef_CreateInfo& PPB_FileRef_Shared::GetCreateInfo() const { + return create_info_; +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/ppb_file_ref_shared.h b/ppapi/shared_impl/ppb_file_ref_shared.h new file mode 100644 index 0000000..5025eb3 --- /dev/null +++ b/ppapi/shared_impl/ppb_file_ref_shared.h @@ -0,0 +1,70 @@ +// 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_FILE_REF_SHARED_H_ +#define PPAPI_SHARED_IMPL_PPB_FILE_REF_SHARED_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/ppb_file_ref_api.h" + +namespace ppapi { + +class StringVar; + +// FileRefs are created in a number of places and they include a number of +// return values. This struct encapsulates everything in one place. +struct PPB_FileRef_CreateInfo { + PPB_FileRef_CreateInfo() + : file_system_type(PP_FILESYSTEMTYPE_EXTERNAL), + file_system_plugin_resource(0) {} + + ppapi::HostResource resource; + int file_system_type; // One of PP_FileSystemType values. + std::string path; + std::string name; + + // Since FileRef needs to hold a FileSystem reference, we need to pass the + // resource in this CreateInfo. Note that this is a plugin resource as + // FileSystem is already in new design. + PP_Resource file_system_plugin_resource; +}; + +// This class provides the shared implementation of a FileRef. The functions +// that actually "do stuff" like Touch and MakeDirectory are implemented +// differently for the proxied and non-proxied derived classes. +class PPAPI_SHARED_EXPORT PPB_FileRef_Shared + : public Resource, + public thunk::PPB_FileRef_API { + public: + PPB_FileRef_Shared(ResourceObjectType type, + const PPB_FileRef_CreateInfo& info); + virtual ~PPB_FileRef_Shared(); + + // Resource overrides. + virtual thunk::PPB_FileRef_API* AsPPB_FileRef_API() OVERRIDE; + + // PPB_FileRef_API implementation (partial). + virtual PP_FileSystemType GetFileSystemType() const OVERRIDE; + virtual PP_Var GetName() const OVERRIDE; + virtual PP_Var GetPath() const OVERRIDE; + virtual const PPB_FileRef_CreateInfo& GetCreateInfo() const OVERRIDE; + virtual PP_Var GetAbsolutePath() = 0; + + private: + PPB_FileRef_CreateInfo create_info_; + + // Lazily initialized vars created from the create_info_. This is so we can + // return the identical string object every time they're requested. + mutable scoped_refptr<StringVar> name_var_; + mutable scoped_refptr<StringVar> path_var_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(PPB_FileRef_Shared); +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_PPB_FILE_REF_SHARED_H_ diff --git a/ppapi/shared_impl/url_request_info_data.cc b/ppapi/shared_impl/url_request_info_data.cc index 15b2787..8bb02a4 100644 --- a/ppapi/shared_impl/url_request_info_data.cc +++ b/ppapi/shared_impl/url_request_info_data.cc @@ -17,7 +17,6 @@ const int32_t kDefaultPrefetchBufferLowerThreshold = 50 * 1000 * 1000; URLRequestInfoData::BodyItem::BodyItem() : is_file(false), - file_ref_pp_resource(0), start_offset(0), number_of_bytes(-1), expected_last_modified_time(0.0) { @@ -26,7 +25,6 @@ URLRequestInfoData::BodyItem::BodyItem() URLRequestInfoData::BodyItem::BodyItem(const std::string& data) : is_file(false), data(data), - file_ref_pp_resource(0), start_offset(0), number_of_bytes(-1), expected_last_modified_time(0.0) { @@ -38,8 +36,8 @@ URLRequestInfoData::BodyItem::BodyItem( int64_t number_of_bytes, PP_Time expected_last_modified_time) : is_file(true), - file_ref_resource(file_ref), - file_ref_pp_resource(file_ref->pp_resource()), + file_ref(file_ref), + file_ref_host_resource(file_ref->host_resource()), start_offset(start_offset), number_of_bytes(number_of_bytes), expected_last_modified_time(expected_last_modified_time) { diff --git a/ppapi/shared_impl/url_request_info_data.h b/ppapi/shared_impl/url_request_info_data.h index d0acf4b..501251a 100644 --- a/ppapi/shared_impl/url_request_info_data.h +++ b/ppapi/shared_impl/url_request_info_data.h @@ -9,12 +9,10 @@ #include <vector> #include "base/memory/ref_counted.h" -#include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/c/pp_time.h" -#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/host_resource.h" #include "ppapi/shared_impl/ppapi_shared_export.h" -#include "ppapi/shared_impl/resource_tracker.h" namespace ppapi { @@ -34,12 +32,19 @@ struct PPAPI_SHARED_EXPORT URLRequestInfoData { std::string data; - // Only set on the plugin-side, for refcounting purposes. Only valid when - // |is_file| is set. - scoped_refptr<Resource> file_ref_resource; - // This struct holds no ref to this resource. Only valid when |is_file| is - // set. - PP_Resource file_ref_pp_resource; + // Is is_file is set, these variables are set. Note that the resource + // may still be NULL in some cases, such as deserialization errors. + // + // This is a bit tricky. In the plugin side of the proxy, both the file ref + // and the file_ref_host_resource will be set and valid. The scoped_refptr + // ensures that the resource is alive for as long as the BodyItem is. + // + // When we deserialize this in the renderer, only the + // file_ref_host_resource's are serialized over IPC. The file_refs won't be + // valid until the host resources are converted to Resource pointers in the + // PPB_URLRequestInfo_Impl. + scoped_refptr<Resource> file_ref; + HostResource file_ref_host_resource; int64_t start_offset; int64_t number_of_bytes; diff --git a/ppapi/shared_impl/url_response_info_data.h b/ppapi/shared_impl/url_response_info_data.h index c6f7dbd..a40ca50 100644 --- a/ppapi/shared_impl/url_response_info_data.h +++ b/ppapi/shared_impl/url_response_info_data.h @@ -8,7 +8,7 @@ #include <string> #include "ppapi/c/pp_stdint.h" -#include "ppapi/shared_impl/file_ref_create_info.h" +#include "ppapi/shared_impl/ppb_file_ref_shared.h" #include "ppapi/shared_impl/ppapi_shared_export.h" namespace ppapi { @@ -23,8 +23,8 @@ struct PPAPI_SHARED_EXPORT URLResponseInfoData { std::string status_text; std::string redirect_url; - // Valid when streaming to a file. - FileRefCreateInfo body_as_file_ref; + // Nonzero when streaming to a file. + PPB_FileRef_CreateInfo body_as_file_ref; }; } // namespace ppapi diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h index 391904d3..3e0289c 100644 --- a/ppapi/thunk/interfaces_ppb_private.h +++ b/ppapi/thunk/interfaces_ppb_private.h @@ -33,7 +33,7 @@ PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_5, PPB_FileChooserTrusted_0_5) PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_6, PPB_FileChooserTrusted_0_6) -PROXIED_IFACE(NoAPIName, PPB_FILEREFPRIVATE_INTERFACE_0_1, +PROXIED_IFACE(PPB_FileRef, PPB_FILEREFPRIVATE_INTERFACE_0_1, PPB_FileRefPrivate_0_1) // TODO(xhwang): Move PPB_Flash_DeviceID back to interfaces_ppb_private_flash.h. PROXIED_IFACE(NoAPIName, PPB_FLASH_DEVICEID_INTERFACE_1_0, diff --git a/ppapi/thunk/interfaces_ppb_public_stable.h b/ppapi/thunk/interfaces_ppb_public_stable.h index 5addc759..19626aa 100644 --- a/ppapi/thunk/interfaces_ppb_public_stable.h +++ b/ppapi/thunk/interfaces_ppb_public_stable.h @@ -19,6 +19,7 @@ // that exist in the webkit/plugins/ppapi/*_impl.h, but not in the proxy. PROXIED_API(PPB_Audio) PROXIED_API(PPB_Core) +PROXIED_API(PPB_FileRef) PROXIED_API(PPB_Graphics3D) PROXIED_API(PPB_ImageData) PROXIED_API(PPB_Instance) @@ -44,8 +45,8 @@ UNPROXIED_API(PPB_AudioConfig) // interface string. // Note: Core is special and is registered manually. PROXIED_IFACE(PPB_Audio, PPB_AUDIO_INTERFACE_1_0, PPB_Audio_1_0) -PROXIED_IFACE(NoAPIName, PPB_FILEREF_INTERFACE_1_0, PPB_FileRef_1_0) -PROXIED_IFACE(NoAPIName, PPB_FILEREF_INTERFACE_1_1, PPB_FileRef_1_1) +PROXIED_IFACE(PPB_FileRef, PPB_FILEREF_INTERFACE_1_0, PPB_FileRef_1_0) +PROXIED_IFACE(PPB_FileRef, PPB_FILEREF_INTERFACE_1_1, PPB_FileRef_1_1) PROXIED_IFACE(NoAPIName, PPB_FILESYSTEM_INTERFACE_1_0, PPB_FileSystem_1_0) PROXIED_IFACE(PPB_Graphics3D, PPB_GRAPHICS_3D_INTERFACE_1_0, PPB_Graphics3D_1_0) PROXIED_IFACE(PPB_ImageData, PPB_IMAGEDATA_INTERFACE_1_0, PPB_ImageData_1_0) diff --git a/ppapi/thunk/ppb_file_ref_api.h b/ppapi/thunk/ppb_file_ref_api.h index b473ae2..ba92b63 100644 --- a/ppapi/thunk/ppb_file_ref_api.h +++ b/ppapi/thunk/ppb_file_ref_api.h @@ -10,12 +10,11 @@ #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "ppapi/c/ppb_file_ref.h" -#include "ppapi/shared_impl/file_ref_create_info.h" #include "ppapi/thunk/ppapi_thunk_export.h" namespace ppapi { -struct FileRefCreateInfo; +struct PPB_FileRef_CreateInfo; class TrackedCallback; namespace thunk { @@ -41,10 +40,25 @@ class PPAPI_THUNK_EXPORT PPB_FileRef_API { virtual int32_t ReadDirectoryEntries( const PP_ArrayOutput& output, scoped_refptr<TrackedCallback> callback) = 0; + // We define variants of Query and ReadDirectoryEntries because + // 1. we need to take linked_ptr instead of raw pointers to avoid + // use-after-free, and 2. we don't use PP_ArrayOutput for the + // communication between renderers and the browser in + // ReadDirectoryEntries. The *InHost functions must not be called in + // plugins, and Query and ReadDirectoryEntries must not be called in + // renderers. + // TODO(hamaji): These functions must be removed when we move + // FileRef to the new resource design. http://crbug.com/225441 + virtual int32_t QueryInHost(linked_ptr<PP_FileInfo> info, + scoped_refptr<TrackedCallback> callback) = 0; + virtual int32_t ReadDirectoryEntriesInHost( + linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, + linked_ptr<std::vector<PP_FileType> > file_types, + scoped_refptr<TrackedCallback> callback) = 0; // 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 FileRefCreateInfo& GetCreateInfo() const = 0; + virtual const PPB_FileRef_CreateInfo& GetCreateInfo() const = 0; // Private API virtual PP_Var GetAbsolutePath() = 0; diff --git a/ppapi/thunk/ppb_file_ref_thunk.cc b/ppapi/thunk/ppb_file_ref_thunk.cc index 64c90b5..beb0e41 100644 --- a/ppapi/thunk/ppb_file_ref_thunk.cc +++ b/ppapi/thunk/ppb_file_ref_thunk.cc @@ -7,7 +7,6 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_file_ref_private.h" -#include "ppapi/shared_impl/file_ref_create_info.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/tracked_callback.h" #include "ppapi/thunk/enter.h" @@ -33,13 +32,7 @@ PP_Resource Create(PP_Resource file_system, const char* path) { EnterResourceCreationNoLock enter(instance); if (enter.failed()) return 0; - FileRefCreateInfo info; - info.file_system_type = enter_file_system.object()->GetType(); - info.internal_path = std::string(path); - info.browser_pending_host_resource_id = 0; - info.renderer_pending_host_resource_id = 0; - info.file_system_plugin_resource = file_system; - return enter.functions()->CreateFileRef(instance, info); + return enter.functions()->CreateFileRef(instance, file_system, path); } PP_Bool IsFileRef(PP_Resource resource) { diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index 262a294..4930755 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -33,7 +33,7 @@ struct PP_Size; namespace ppapi { -struct FileRefCreateInfo; +struct PPB_FileRef_CreateInfo; struct URLRequestInfoData; struct URLResponseInfoData; @@ -49,9 +49,15 @@ class ResourceCreationAPI { virtual ~ResourceCreationAPI() {} virtual PP_Resource CreateFileIO(PP_Instance instance) = 0; + virtual PP_Resource CreateFileRef(PP_Instance instance, + PP_Resource file_system, + const char* path) = 0; + // Like the above version but takes a serialized file ref. The resource + // in the serialized file ref is passed into this, which takes ownership of + // the reference. In the proxy, the return value will be a plugin resource. + // In the impl, the return value will be the same resource ID. virtual PP_Resource CreateFileRef( - PP_Instance instance, - const FileRefCreateInfo& serialized) = 0; + const PPB_FileRef_CreateInfo& serialized) = 0; virtual PP_Resource CreateFileSystem(PP_Instance instance, PP_FileSystemType type) = 0; virtual PP_Resource CreateIMEInputEvent(PP_Instance instance, |