diff options
author | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-29 02:15:49 +0000 |
---|---|---|
committer | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-29 02:15:49 +0000 |
commit | 2498c499249ef946517e2238a8f688c6d0f0a086 (patch) | |
tree | c7498fea0ef897dcee9411674aaca62194522344 | |
parent | 25df6cd8013abc840d3906eedbefd850e264a86e (diff) | |
download | chromium_src-2498c499249ef946517e2238a8f688c6d0f0a086.zip chromium_src-2498c499249ef946517e2238a8f688c6d0f0a086.tar.gz chromium_src-2498c499249ef946517e2238a8f688c6d0f0a086.tar.bz2 |
Revert 219911 "Pepper: Move FileRef to the "new" resource proxy."
There have been multiple test failures among users of the CRX filesystem, which
is not adequately tested by existing tests. I'm not sure at all what's broken,
but I guess I'll have to do manual testing to sort it out.
> Pepper: Move FileRef to the "new" resource proxy.
>
> This change moves the FileRef implementation from the previous one in the "old"
> resource model (ppb_file_ref_impl.cc) to the "new" resource model
> (pepper_file_ref_host.cc), and from the renderer to the browser.
>
> As many as possible of the supporting changes were split off to other changes
> to minimize the size of this change. Unfortunately, a lot of changes for
> URLLoader had to be rolled into this change.
>
> The data structures for CreateInfo have changed, and all users of FileRef have
> to be moved over, which is what causes this change to be so large.
>
> TBR=dmichael@chromium.org, jschuh@chromium.org, yzshen@chromium.org
> BUG=225441
>
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=216744
>
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=218305
>
> Review URL: https://chromiumcodereview.appspot.com/21966004
TBR=teravest@chromium.org
Review URL: https://codereview.chromium.org/23462016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220165 0039d316-1c4b-4281-b951-d872f2087c98
67 files changed, 2012 insertions, 547 deletions
diff --git a/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc b/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc index 243a9bb..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,35 +56,13 @@ int32_t PepperFlashDRMRendererHost::OnGetVoucherFile( base::FilePath voucher_file = plugin_dir.Append( base::FilePath(kVoucherFilename)); - 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)); - return PP_OK_COMPLETIONPENDING; -} - -void PepperFlashDRMRendererHost::DidCreateFileRefHosts( - const ppapi::host::ReplyMessageContext& reply_context, - const base::FilePath& external_path, - const std::vector<int>& pending_resource_ids) { - DCHECK(pending_resource_ids.size() == 1); - - int pending_resource_id = 0; - if (pending_resource_ids.size() == 1) - pending_resource_id = pending_resource_ids[0]; - - ppapi::FileRefCreateInfo create_info = - ppapi::MakeExternalFileRefCreateInfo(external_path, - std::string(), - pending_resource_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 4e39c71..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,16 +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, - const std::vector<int>& pending_resource_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 2bd44c1..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,10 +90,7 @@ 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 { 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 32ef0ac..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; } 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 0bfd328..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 @@ -223,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_; @@ -237,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_renderer_connection.cc b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc index 4573acf..b2232fd0 100644 --- a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc @@ -16,9 +16,7 @@ #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" -#include "ppapi/shared_impl/file_ref_detailed_info.h" namespace content { @@ -77,8 +75,6 @@ bool PepperRendererConnection::OnMessageReceived(const IPC::Message& msg, OnMsgCreateResourceHostsFromHost) IPC_MESSAGE_HANDLER(PpapiHostMsg_FileRef_GetInfoForRenderer, OnMsgFileRefGetInfoForRenderer) - IPC_MESSAGE_HANDLER(PpapiHostMsg_FileRef_SyncGetInfoForRenderer, - OnMsgFileRefSyncGetInfoForRenderer) IPC_MESSAGE_HANDLER(ViewHostMsg_DidCreateInProcessInstance, OnMsgDidCreateInProcessInstance) IPC_MESSAGE_HANDLER(ViewHostMsg_DidDeleteInProcessInstance, @@ -138,20 +134,12 @@ void PepperRendererConnection::OnMsgFileRefGetInfoForRenderer( int child_process_id, int32_t sequence, const std::vector<PP_Resource>& resources) { - std::vector<ppapi::FileRefDetailedInfo> infos; - OnMsgFileRefSyncGetInfoForRenderer(child_process_id, resources, &infos); - Send(new PpapiHostMsg_FileRef_GetInfoForRendererReply( - routing_id, - sequence, - infos)); -} + 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; -void PepperRendererConnection::OnMsgFileRefSyncGetInfoForRenderer( - int child_process_id, - const std::vector<PP_Resource>& resources, - std::vector<ppapi::FileRefDetailedInfo>* out_infos) { BrowserPpapiHostImpl* host = GetHostForChildProcess(child_process_id); - if (host) { for (size_t i = 0; i < resources.size(); ++i) { ppapi::host::ResourceHost* resource_host = @@ -159,15 +147,20 @@ void PepperRendererConnection::OnMsgFileRefSyncGetInfoForRenderer( if (resource_host && resource_host->IsFileRefHost()) { PepperFileRefHost* file_ref_host = static_cast<PepperFileRefHost*>(resource_host); - ppapi::FileRefDetailedInfo info; - info.resource = resources[i]; - info.file_system_type = file_ref_host->GetFileSystemType(); - info.file_system_url_spec = file_ref_host->GetFileSystemURLSpec(); - info.external_path = file_ref_host->GetExternalPath(); - out_infos->push_back(info); + 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( diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.h b/content/browser/renderer_host/pepper/pepper_renderer_connection.h index 896d301..24cbc2c 100644 --- a/content/browser/renderer_host/pepper/pepper_renderer_connection.h +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.h @@ -13,7 +13,6 @@ #include "content/public/browser/browser_message_filter.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" -#include "ppapi/shared_impl/file_ref_detailed_info.h" class GURL; @@ -61,11 +60,6 @@ class PepperRendererConnection : public BrowserMessageFilter { int32_t sequence_num, const std::vector<PP_Resource>& resources); - void OnMsgFileRefSyncGetInfoForRenderer( - int child_process_id, - const std::vector<PP_Resource>& resources, - std::vector<ppapi::FileRefDetailedInfo>* out_infos); - void OnMsgDidCreateInProcessInstance( PP_Instance instance, const PepperRendererInstanceData& instance_data); diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 1e9e0bb..d8aabac 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -353,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 c7741a2..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; @@ -87,6 +92,7 @@ class PepperPluginInstance { virtual int32_t Navigate(const ppapi::URLRequestInfoData& request, const char* target, bool from_user_action) = 0; + }; } // namespace content diff --git a/content/public/renderer/renderer_ppapi_host.h b/content/public/renderer/renderer_ppapi_host.h index f90ee36..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 the "NaCl trusted plugin". That plugin - // and the "untrusted plugin" (the NaCl application) that will be loaded - // share a PP_Instance, and the RendererPpapiHost* for the "untrusted plugin" - // will be returned after we switch the proxy on. CONTENT_EXPORT static RendererPpapiHost* GetForPPInstance( PP_Instance instance); 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 c5f5ddd..6bbec3d 100644 --- a/content/renderer/pepper/pepper_browser_connection.cc +++ b/content/renderer/pepper/pepper_browser_connection.cc @@ -34,10 +34,9 @@ bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(PepperBrowserConnection, msg) IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostsFromHostReply, OnMsgCreateResourceHostsFromHostReply) - IPC_MESSAGE_HANDLER(PpapiHostMsg_FileRef_GetInfoForRendererReply, - OnMsgFileRefGetInfoReply) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() + return handled; } @@ -102,7 +101,10 @@ void PepperBrowserConnection::OnMsgCreateResourceHostsFromHostReply( void PepperBrowserConnection::OnMsgFileRefGetInfoReply( int32_t sequence_number, - const std::vector<ppapi::FileRefDetailedInfo>& infos) { + 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 = @@ -110,7 +112,7 @@ void PepperBrowserConnection::OnMsgFileRefGetInfoReply( if (it != get_info_map_.end()) { FileRefGetInfoCallback callback = it->second; get_info_map_.erase(it); - callback.Run(infos); + callback.Run(resources, types, file_system_url_specs, external_paths); } else { NOTREACHED(); } diff --git a/content/renderer/pepper/pepper_browser_connection.h b/content/renderer/pepper/pepper_browser_connection.h index dabfd36..ab43409 100644 --- a/content/renderer/pepper/pepper_browser_connection.h +++ b/content/renderer/pepper/pepper_browser_connection.h @@ -16,7 +16,6 @@ #include "ppapi/c/pp_file_info.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" -#include "ppapi/shared_impl/file_ref_detailed_info.h" namespace content { @@ -31,7 +30,10 @@ class PepperBrowserConnection typedef base::Callback<void(const std::vector<int>&)> PendingResourceIDCallback; typedef base::Callback<void( - const std::vector<ppapi::FileRefDetailedInfo>&)> FileRefGetInfoCallback; + 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(); @@ -72,7 +74,10 @@ class PepperBrowserConnection const std::vector<int>& pending_resource_host_ids); void OnMsgFileRefGetInfoReply( int32_t sequence_number, - const std::vector<ppapi::FileRefDetailedInfo>& infos); + 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(); diff --git a/content/renderer/pepper/pepper_file_chooser_host.cc b/content/renderer/pepper/pepper_file_chooser_host.cc index 73ebba7..1229d17 100644 --- a/content/renderer/pepper/pepper_file_chooser_host.cc +++ b/content/renderer/pepper/pepper_file_chooser_host.cc @@ -7,11 +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/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" @@ -79,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() { @@ -97,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( @@ -173,26 +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>& ids) { - DCHECK(file_paths.size() == display_names.size()); - DCHECK(file_paths.size() == ids.size()); - - std::vector<ppapi::FileRefCreateInfo> chosen_files; - for (size_t i = 0; i < ids.size(); ++i) { - ppapi::FileRefCreateInfo info = ppapi::MakeExternalFileRefCreateInfo( - file_paths[i], display_names[i], ids[i]); - 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 3f6929a..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>& 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 0698f96..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_browser_connection.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,66 +229,46 @@ int32_t PepperFileIOHost::OnHostMsgOpen( return PP_ERROR_BADARGUMENT; } - RenderView* render_view = - renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()); - PepperBrowserConnection* browser_connection = - PepperBrowserConnection::Get(render_view); - int child_process_id = plugin_instance_->module()->GetPluginChildId(); - - // Explicitly set child_process_id to 0 if we're running in process. This is - // necessary in the case where we're a host for a resource in "the trusted - // NaCl plugin". In that case, we may have already done work for the - // untrusted plugin, and the call above will give a non-zero - // child_process_id. - if (renderer_ppapi_host_->IsRunningInProcess()) - child_process_id = 0; - - std::vector<PP_Resource> resources; - resources.push_back(file_ref_resource); - browser_connection->SendBrowserFileRefGetInfo( - child_process_id, - resources, - base::Bind(&PepperFileIOHost::DidGetFileRefInfo, - weak_factory_.GetWeakPtr(), - context->MakeReplyMessageContext(), - platform_file_flags)); - state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); - return PP_OK_COMPLETIONPENDING; -} + EnterResourceNoLock<PPB_FileRef_API> enter(file_ref_resource, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; -void PepperFileIOHost::DidGetFileRefInfo( - ppapi::host::ReplyMessageContext reply_context, - int platform_file_flags, - const std::vector<ppapi::FileRefDetailedInfo>& infos) { - if (infos.size() != 1) { - reply_context.params.set_result(PP_ERROR_FAILED); - host()->SendReply(reply_context, - PpapiPluginMsg_FileIO_OpenReply()); - return; - } + 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(); - file_system_type_ = infos[0].file_system_type; - if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { - file_system_url_ = GURL(infos[0].file_system_url_spec); FileSystemDispatcher* file_system_dispatcher = ChildThread::current()->file_system_dispatcher(); - AsyncOpenFileSystemURLCallback callback = base::Bind( &PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback, weak_factory_.GetWeakPtr(), - reply_context); + context->MakeReplyMessageContext()); file_system_dispatcher->OpenFile( file_system_url_, platform_file_flags, 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(), - reply_context))); + context->MakeReplyMessageContext()))); RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( - routing_id_, infos[0].external_path, open_flags_, message_id)); + routing_id_, file_ref->GetSystemPath(), open_flags, message_id)); } + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; } int32_t PepperFileIOHost::OnHostMsgTouch( diff --git a/content/renderer/pepper/pepper_file_io_host.h b/content/renderer/pepper/pepper_file_io_host.h index a49630d..0e26174 100644 --- a/content/renderer/pepper/pepper_file_io_host.h +++ b/content/renderer/pepper/pepper_file_io_host.h @@ -19,7 +19,6 @@ #include "ppapi/host/host_message_context.h" #include "ppapi/host/resource_host.h" #include "ppapi/shared_impl/file_io_state_manager.h" -#include "ppapi/shared_impl/file_ref_detailed_info.h" #include "ppapi/thunk/ppb_file_ref_api.h" #include "url/gurl.h" #include "webkit/common/quota/quota_types.h" @@ -27,7 +26,6 @@ using ppapi::host::ReplyMessageContext; namespace content { -class PepperPluginInstanceImpl; class QuotaFileIO; class PepperFileIOHost : public ppapi::host::ResourceHost, @@ -81,11 +79,6 @@ class PepperFileIOHost : public ppapi::host::ResourceHost, int32_t OnHostMsgWillSetLength(ppapi::host::HostMessageContext* context, int64_t length); - void DidGetFileRefInfo( - ppapi::host::ReplyMessageContext reply_context, - int flags, - const std::vector<ppapi::FileRefDetailedInfo>& infos); - // Callback handlers. These mostly convert the PlatformFileError to the // PP_Error code and send back the reply. Note that the argument // ReplyMessageContext is copied so that we have a closure containing all @@ -112,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_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 bb9f2a4..49daf81 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -36,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" @@ -767,7 +768,6 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad( DCHECK(pending_host_id); DataFromWebURLResponse( - host_impl, pp_instance(), response, base::Bind(&PepperPluginInstanceImpl::DidDataFromWebURLResponse, @@ -2613,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); @@ -2749,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); diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 930c55a..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( diff --git a/content/renderer/pepper/pepper_url_loader_host.cc b/content/renderer/pepper/pepper_url_loader_host.cc index 60bb467..8343f19 100644 --- a/content/renderer/pepper/pepper_url_loader_host.cc +++ b/content/renderer/pepper/pepper_url_loader_host.cc @@ -250,12 +250,8 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( if (!frame) 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.setRequestorProcessID(renderer_ppapi_host_->GetPluginPID()); WebURLLoaderOptions options; @@ -393,7 +389,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 419b3270..2ac29a8 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" @@ -70,6 +71,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 5b3786b..e82c8a1 100644 --- a/content/renderer/pepper/url_request_info_util.cc +++ b/content/renderer/pepper/url_request_info_util.cc @@ -8,13 +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_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_module.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/file_ref_detailed_info.h" #include "ppapi/shared_impl/url_request_info_data.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" @@ -28,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; @@ -45,23 +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( - const ppapi::FileRefDetailedInfo& file_info, + Resource* file_ref_resource, int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time, WebHTTPBody *http_body) { + // Get the underlying file ref impl. + if (!file_ref_resource) + return false; + PPB_FileRef_API* file_ref_api = file_ref_resource->AsPPB_FileRef_API(); + if (!file_ref_api) + return false; + const PPB_FileRef_Impl* file_ref = + static_cast<PPB_FileRef_Impl*>(file_ref_api); + base::FilePath platform_path; - switch (file_info.file_system_type) { + 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( - GURL(file_info.file_system_url_spec), &platform_path)); + file_ref->GetFileSystemURL(), &platform_path)); break; case PP_FILESYSTEMTYPE_EXTERNAL: - platform_path = file_info.external_path; + platform_path = file_ref->GetSystemPath(); break; default: NOTREACHED(); @@ -77,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 <= @@ -87,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(); @@ -121,44 +145,19 @@ bool CreateWebURLRequest(PP_Instance instance, } } - // Get file information for FileRefs inside BodyItems. - std::vector<PP_Resource> resources; - for (size_t i = 0; i < data->body.size(); ++i) { - const URLRequestInfoData::BodyItem& item = data->body[i]; - if (item.is_file) - resources.push_back(item.file_ref_pp_resource); - } - std::vector<ppapi::FileRefDetailedInfo> infos; - - if (!resources.empty()) { - PepperPluginInstanceImpl* instance_impl = - HostGlobals::Get()->GetInstance(instance); - int child_process_id = instance_impl->module()->GetPluginChildId(); - // The routing id is automatically populated for us when set to 0. - RenderThreadImpl::current()->Send( - new PpapiHostMsg_FileRef_SyncGetInfoForRenderer( - 0, child_process_id, resources, &infos)); - if (infos.size() != resources.size()) - return false; - } - // Append the upload data. 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 (item.file_ref_pp_resource != infos[file_index].resource) - return false; - if (!AppendFileRefToBody(infos[file_index], + 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)); @@ -191,7 +190,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 38f120c..a9eccef 100644 --- a/content/renderer/pepper/url_response_info_util.cc +++ b/content/renderer/pepper/url_response_info_util.cc @@ -7,10 +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/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" @@ -46,29 +43,13 @@ bool IsRedirect(int32_t status) { return status >= 300 && status <= 399; } -void DidCreateResourceHosts(const ppapi::URLResponseInfoData& in_data, - const base::FilePath& external_path, - const DataFromWebURLResponseCallback& callback, - const std::vector<int>& pending_resource_ids) { - DCHECK(pending_resource_ids.size() == 1); - int pending_resource_id = 0; - - if (pending_resource_ids.size() == 1) - pending_resource_id = pending_resource_ids[0]; - - ppapi::URLResponseInfoData data = in_data; - data.body_as_file_ref = ppapi::MakeExternalFileRefCreateInfo( - external_path, std::string(), pending_resource_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(); @@ -83,18 +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); - 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, 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 d33be44..1d0e44f 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -23,9 +23,7 @@ 'shared_impl/file_io_state_manager.h', 'shared_impl/file_path.cc', 'shared_impl/file_path.h', - 'shared_impl/file_ref_create_info.cc', 'shared_impl/file_ref_create_info.h', - 'shared_impl/file_ref_detailed_info.h', 'shared_impl/file_ref_util.cc', 'shared_impl/file_ref_util.h', 'shared_impl/file_type_conversion.cc', @@ -55,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 e563bf4..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,13 +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.pending_host_resource_id = 12; + // 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, @@ -116,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 f63f906..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_ = file_ref; - 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_ = 0; 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 139fb83..1a888d1 100644 --- a/ppapi/proxy/file_io_resource.h +++ b/ppapi/proxy/file_io_resource.h @@ -12,7 +12,6 @@ #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/scoped_pp_resource.h" #include "ppapi/thunk/ppb_file_io_api.h" namespace ppapi { @@ -138,8 +137,6 @@ class PPAPI_PROXY_EXPORT FileIOResource PP_FileSystemType file_system_type_; FileIOStateManager state_manager_; - ScopedPPResource file_ref_; - DISALLOW_COPY_AND_ASSIGN(FileIOResource); }; diff --git a/ppapi/proxy/file_ref_resource.cc b/ppapi/proxy/file_ref_resource.cc index ae4df85..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,6 +34,7 @@ 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); } @@ -56,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) { @@ -81,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 { @@ -108,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); @@ -181,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()) { @@ -221,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 17e2f73..f108812 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -57,7 +57,6 @@ #include "ppapi/shared_impl/dir_contents.h" #include "ppapi/shared_impl/file_path.h" #include "ppapi/shared_impl/file_ref_create_info.h" -#include "ppapi/shared_impl/file_ref_detailed_info.h" #include "ppapi/shared_impl/ppapi_nacl_channel_args.h" #include "ppapi/shared_impl/ppapi_preferences.h" #include "ppapi/shared_impl/ppb_device_ref_shared.h" @@ -203,7 +202,7 @@ 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) @@ -211,13 +210,6 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::FileRefCreateInfo) IPC_STRUCT_TRAITS_MEMBER(file_system_plugin_resource) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(ppapi::FileRefDetailedInfo) - IPC_STRUCT_TRAITS_MEMBER(resource) - IPC_STRUCT_TRAITS_MEMBER(file_system_type) - IPC_STRUCT_TRAITS_MEMBER(file_system_url_spec) - IPC_STRUCT_TRAITS_MEMBER(external_path) -IPC_STRUCT_TRAITS_END() - IPC_STRUCT_TRAITS_BEGIN(ppapi::FlashSiteSetting) IPC_STRUCT_TRAITS_MEMBER(site) IPC_STRUCT_TRAITS_MEMBER(permission) @@ -306,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) @@ -493,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, @@ -755,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 */, @@ -1148,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 */, @@ -1221,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) @@ -1297,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 @@ -1341,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) @@ -1737,18 +1792,12 @@ IPC_MESSAGE_CONTROL4(PpapiHostMsg_FileRef_GetInfoForRenderer, // 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_ROUTED2( - PpapiHostMsg_FileRef_GetInfoForRendererReply, - int32_t /* sequence */, - std::vector<ppapi::FileRefDetailedInfo> /* detailed_info */) - -// A synchronous version of the two above messages. This is required to support -// some URL loading routes which must be executed synchronously. -IPC_SYNC_MESSAGE_ROUTED2_1( - PpapiHostMsg_FileRef_SyncGetInfoForRenderer, - int /* child_process_id */, - std::vector<PP_Resource> /* resources */, - std::vector<ppapi::FileRefDetailedInfo> /* detailed_info */) +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 ----------------------------------------------------------------------- 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 68c3f17..0000000 --- a/ppapi/shared_impl/file_ref_create_info.cc +++ /dev/null @@ -1,48 +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 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.pending_host_resource_id = 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 ae570e6..a3599f7 100644 --- a/ppapi/shared_impl/file_ref_create_info.h +++ b/ppapi/shared_impl/file_ref_create_info.h @@ -10,19 +10,12 @@ #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), - 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; @@ -31,18 +24,10 @@ struct FileRefCreateInfo { 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 pending_host_resource_id); - } // namespace ppapi #endif // PPAPI_SHARED_IMPL_FILE_REF_CREATE_INFO_H diff --git a/ppapi/shared_impl/file_ref_detailed_info.h b/ppapi/shared_impl/file_ref_detailed_info.h deleted file mode 100644 index 858effa..0000000 --- a/ppapi/shared_impl/file_ref_detailed_info.h +++ /dev/null @@ -1,28 +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. - -#ifndef PPAPI_SHARED_IMPL_FILE_REF_DETAILED_INFO_H -#define PPAPI_SHARED_IMPL_FILE_REF_DETAILED_INFO_H - -#include <string> - -#include "base/files/file_path.h" -#include "ppapi/c/pp_file_info.h" -#include "ppapi/c/pp_resource.h" - -namespace ppapi { - -// This structure is only used for exchanging information about FileRefs from -// the browser to the renderer. -struct FileRefDetailedInfo { - // This struct doesn't hold a ref on this resource. - PP_Resource resource; - PP_FileSystemType file_system_type; - std::string file_system_url_spec; - base::FilePath external_path; -}; - -} // namespace ppapi - -#endif // PPAPI_SHARED_IMPL_FILE_REF_DETAILED_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 8910faf..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,12 +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.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, |