| 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 49dac58d60ada7d43589bd10a201186336c6adf8..c63cccd1d083ba89fa9084ce221eb4065baa0b7f 100644
|
| --- a/ppapi/proxy/ppb_file_ref_proxy.cc
|
| +++ b/ppapi/proxy/ppb_file_ref_proxy.cc
|
| @@ -47,10 +47,13 @@ class FileRef : public PPB_FileRef_Shared {
|
| 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 PP_Var GetAbsolutePath() OVERRIDE;
|
|
|
| // Executes the pending callback with the given ID. See pending_callbacks_.
|
| - void ExecuteCallback(int callback_id, int32_t result);
|
| + void ExecuteCallback(uint32_t callback_id, int32_t result);
|
| + void SetFileInfo(uint32_t callback_id, const PP_FileInfo& info);
|
|
|
| private:
|
| PluginDispatcher* GetDispatcher() const {
|
| @@ -58,7 +61,7 @@ class FileRef : public PPB_FileRef_Shared {
|
| }
|
|
|
| // Adds a callback to the list and returns its ID.
|
| - int SendCallback(scoped_refptr<TrackedCallback> callback);
|
| + 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
|
| @@ -67,11 +70,17 @@ class FileRef : public PPB_FileRef_Shared {
|
| // 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.
|
| - unsigned int next_callback_id_;
|
| - typedef std::map<unsigned int,
|
| + 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_;
|
| +
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef);
|
| };
|
|
|
| @@ -83,11 +92,13 @@ FileRef::FileRef(const PPB_FileRef_CreateInfo& info)
|
| FileRef::~FileRef() {
|
| // The callbacks map should have been cleared by LastPluginRefWasDeleted.
|
| DCHECK(pending_callbacks_.empty());
|
| + DCHECK(pending_file_infos_.empty());
|
| }
|
|
|
| void FileRef::LastPluginRefWasDeleted() {
|
| // The callback tracker will abort our callbacks for us.
|
| pending_callbacks_.clear();
|
| + pending_file_infos_.clear();
|
| }
|
|
|
| PP_Resource FileRef::GetParent() {
|
| @@ -134,6 +145,16 @@ int32_t FileRef::Rename(PP_Resource new_file_ref,
|
| return PP_OK_COMPLETIONPENDING;
|
| }
|
|
|
| +int32_t FileRef::Query(PP_FileInfo* info,
|
| + scoped_refptr<TrackedCallback> callback) {
|
| + // Store the pending file info id.
|
| + int 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;
|
| +}
|
| +
|
| PP_Var FileRef::GetAbsolutePath() {
|
| ReceiveSerializedVarReturnValue result;
|
| GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetAbsolutePath(
|
| @@ -141,7 +162,7 @@ PP_Var FileRef::GetAbsolutePath() {
|
| return result.Return(GetDispatcher());
|
| }
|
|
|
| -void FileRef::ExecuteCallback(int callback_id, int32_t result) {
|
| +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
|
| @@ -156,7 +177,16 @@ void FileRef::ExecuteCallback(int callback_id, int32_t result) {
|
| callback->Run(result);
|
| }
|
|
|
| -int FileRef::SendCallback(scoped_refptr<TrackedCallback> callback) {
|
| +void 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_FileInfo* target_info = found->second;
|
| + *target_info = info;
|
| + pending_file_infos_.erase(found);
|
| +}
|
| +
|
| +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_;
|
| @@ -200,12 +230,15 @@ bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) {
|
| 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_GetAbsolutePath,
|
| OnMsgGetAbsolutePath)
|
| #endif // !defined(OS_NACL)
|
|
|
| IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_CallbackComplete,
|
| OnMsgCallbackComplete)
|
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_QueryCallbackComplete,
|
| + OnMsgQueryCallbackComplete)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
| return handled;
|
| @@ -250,7 +283,7 @@ void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource,
|
|
|
| void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource,
|
| PP_Bool make_ancestors,
|
| - int callback_id) {
|
| + uint32_t callback_id) {
|
| EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
|
| host_resource, callback_factory_,
|
| &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
|
| @@ -263,7 +296,7 @@ void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource,
|
| void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource,
|
| PP_Time last_access,
|
| PP_Time last_modified,
|
| - int callback_id) {
|
| + uint32_t callback_id) {
|
| EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
|
| host_resource, callback_factory_,
|
| &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
|
| @@ -274,7 +307,7 @@ void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource,
|
| }
|
|
|
| void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource,
|
| - int callback_id) {
|
| + uint32_t callback_id) {
|
| EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
|
| host_resource, callback_factory_,
|
| &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
|
| @@ -284,7 +317,7 @@ void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource,
|
|
|
| void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref,
|
| const HostResource& new_file_ref,
|
| - int callback_id) {
|
| + uint32_t callback_id) {
|
| EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
|
| file_ref, callback_factory_,
|
| &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id);
|
| @@ -294,6 +327,17 @@ 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();
|
| + EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
|
| + file_ref, callback_factory_,
|
| + &PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost, file_ref,
|
| + base::Owned(info), callback_id);
|
| + if (enter.succeeded())
|
| + enter.SetResult(enter.object()->Query(info, enter.callback()));
|
| +}
|
| +
|
| void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource,
|
| SerializedVarReturnValue result) {
|
| EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
|
| @@ -304,7 +348,7 @@ void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource,
|
|
|
| void PPB_FileRef_Proxy::OnMsgCallbackComplete(
|
| const HostResource& host_resource,
|
| - int callback_id,
|
| + uint32_t callback_id,
|
| int32_t result) {
|
| // Forward the callback info to the plugin resource.
|
| EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource);
|
| @@ -312,15 +356,37 @@ void PPB_FileRef_Proxy::OnMsgCallbackComplete(
|
| 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()) {
|
| + // Set the FileInfo output parameter.
|
| + static_cast<FileRef*>(enter.object())->SetFileInfo(callback_id, info);
|
| + 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,
|
| - int callback_id) {
|
| + 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,
|
| + base::internal::OwnedWrapper<PP_FileInfo> info,
|
| + uint32_t callback_id) {
|
| + Send(new PpapiMsg_PPBFileRef_QueryCallbackComplete(
|
| + API_ID_PPB_FILE_REF, host_resource, *info.get(), callback_id, result));
|
| +}
|
| #endif // !defined(OS_NACL)
|
|
|
| } // namespace proxy
|
|
|