| Index: ppapi/proxy/ppb_file_ref_proxy.cc
|
| diff --git a/ppapi/proxy/ppb_file_ref_proxy.cc b/ppapi/proxy/ppb_file_ref_proxy.cc
|
| index da621598e24dd6ed24ef138b0790f8aa006214c8..62c55da9d8b85fa4f1ddbc0810981302d3c3ec2d 100644
|
| --- a/ppapi/proxy/ppb_file_ref_proxy.cc
|
| +++ b/ppapi/proxy/ppb_file_ref_proxy.cc
|
| @@ -7,6 +7,7 @@
|
| #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"
|
| @@ -16,6 +17,7 @@
|
| #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"
|
| @@ -29,6 +31,17 @@ 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);
|
| @@ -50,11 +63,25 @@ class FileRef : public PPB_FileRef_Shared {
|
| 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);
|
| - void SetFileInfo(uint32_t callback_id, const PP_FileInfo& info);
|
| + 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 {
|
| @@ -82,6 +109,13 @@ class FileRef : public PPB_FileRef_Shared {
|
| 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
|
| @@ -101,12 +135,14 @@ 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() {
|
| @@ -156,13 +192,39 @@ int32_t FileRef::Rename(PP_Resource new_file_ref,
|
| int32_t FileRef::Query(PP_FileInfo* info,
|
| scoped_refptr<TrackedCallback> callback) {
|
| // Store the pending file info id.
|
| - int id = SendCallback(callback);
|
| + 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(
|
| @@ -185,13 +247,44 @@ void FileRef::ExecuteCallback(uint32_t callback_id, int32_t result) {
|
| callback->Run(result);
|
| }
|
|
|
| -void FileRef::SetFileInfo(uint32_t callback_id, const PP_FileInfo& info) {
|
| +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;
|
| + 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) {
|
| @@ -234,6 +327,8 @@ bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) {
|
| 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)
|
| @@ -242,6 +337,9 @@ bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) {
|
| 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;
|
| @@ -334,13 +432,13 @@ void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref,
|
|
|
| void PPB_FileRef_Proxy::OnMsgQuery(const HostResource& file_ref,
|
| uint32_t callback_id) {
|
| - PP_FileInfo* info = new PP_FileInfo();
|
| + linked_ptr<PP_FileInfo> info(new PP_FileInfo());
|
| EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
|
| file_ref, callback_factory_,
|
| &PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost, file_ref,
|
| - base::Owned(info), callback_id);
|
| + info, callback_id);
|
| if (enter.succeeded())
|
| - enter.SetResult(enter.object()->Query(info, enter.callback()));
|
| + enter.SetResult(enter.object()->QueryInHost(info, enter.callback()));
|
| }
|
|
|
| void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource,
|
| @@ -349,6 +447,24 @@ void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& 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(
|
| @@ -367,11 +483,35 @@ void PPB_FileRef_Proxy::OnMsgQueryCallbackComplete(
|
| uint32_t callback_id,
|
| int32_t result) {
|
| EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource);
|
| - if (enter.succeeded()) {
|
| - // Set the FileInfo output parameter.
|
| - static_cast<FileRef*>(enter.object())->SetFileInfo(callback_id, info);
|
| - static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result);
|
| + 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)
|
| @@ -387,11 +527,22 @@ void PPB_FileRef_Proxy::OnCallbackCompleteInHost(
|
| void PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost(
|
| int32_t result,
|
| const HostResource& host_resource,
|
| - base::internal::OwnedWrapper<PP_FileInfo> info,
|
| + linked_ptr<PP_FileInfo> info,
|
| uint32_t callback_id) {
|
| Send(new PpapiMsg_PPBFileRef_QueryCallbackComplete(
|
| - API_ID_PPB_FILE_REF, host_resource, *info.get(), callback_id, result));
|
| + 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
|
|
|