| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ppapi/proxy/ppb_file_ref_proxy.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "ppapi/c/pp_directory_entry.h" | |
| 11 #include "ppapi/c/pp_errors.h" | |
| 12 #include "ppapi/c/ppb_file_ref.h" | |
| 13 #include "ppapi/c/private/ppb_file_ref_private.h" | |
| 14 #include "ppapi/c/private/ppb_proxy_private.h" | |
| 15 #include "ppapi/proxy/enter_proxy.h" | |
| 16 #include "ppapi/proxy/host_dispatcher.h" | |
| 17 #include "ppapi/proxy/plugin_dispatcher.h" | |
| 18 #include "ppapi/proxy/ppapi_messages.h" | |
| 19 #include "ppapi/proxy/serialized_var.h" | |
| 20 #include "ppapi/shared_impl/array_writer.h" | |
| 21 #include "ppapi/shared_impl/ppb_file_ref_shared.h" | |
| 22 #include "ppapi/shared_impl/scoped_pp_resource.h" | |
| 23 #include "ppapi/shared_impl/tracked_callback.h" | |
| 24 #include "ppapi/thunk/resource_creation_api.h" | |
| 25 #include "ppapi/thunk/thunk.h" | |
| 26 | |
| 27 using ppapi::thunk::EnterResourceNoLock; | |
| 28 using ppapi::thunk::PPB_FileRef_API; | |
| 29 using ppapi::thunk::ResourceCreationAPI; | |
| 30 | |
| 31 namespace ppapi { | |
| 32 namespace proxy { | |
| 33 | |
| 34 namespace { | |
| 35 | |
| 36 void ReleaseEntries(const std::vector<PP_DirectoryEntry>& entries) { | |
| 37 ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker(); | |
| 38 for (std::vector<PP_DirectoryEntry>::const_iterator it = entries.begin(); | |
| 39 it != entries.end(); ++it) | |
| 40 tracker->ReleaseResource(it->file_ref); | |
| 41 } | |
| 42 | |
| 43 } // namespace | |
| 44 | |
| 45 class FileRef : public PPB_FileRef_Shared { | |
| 46 public: | |
| 47 explicit FileRef(const PPB_FileRef_CreateInfo& info); | |
| 48 virtual ~FileRef(); | |
| 49 | |
| 50 // Resource overrides. | |
| 51 virtual void LastPluginRefWasDeleted() OVERRIDE; | |
| 52 | |
| 53 // PPB_FileRef_API implementation (not provided by PPB_FileRef_Shared). | |
| 54 virtual PP_Resource GetParent() OVERRIDE; | |
| 55 virtual int32_t MakeDirectory( | |
| 56 PP_Bool make_ancestors, | |
| 57 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 58 virtual int32_t Touch(PP_Time last_access_time, | |
| 59 PP_Time last_modified_time, | |
| 60 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 61 virtual int32_t Delete(scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 62 virtual int32_t Rename(PP_Resource new_file_ref, | |
| 63 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 64 virtual int32_t Query(PP_FileInfo* info, | |
| 65 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 66 virtual int32_t ReadDirectoryEntries( | |
| 67 const PP_ArrayOutput& output, | |
| 68 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 69 virtual int32_t QueryInHost( | |
| 70 linked_ptr<PP_FileInfo> info, | |
| 71 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 72 virtual int32_t ReadDirectoryEntriesInHost( | |
| 73 linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, | |
| 74 linked_ptr<std::vector<PP_FileType> > file_types, | |
| 75 scoped_refptr<TrackedCallback> callback) OVERRIDE; | |
| 76 virtual PP_Var GetAbsolutePath() OVERRIDE; | |
| 77 | |
| 78 // Executes the pending callback with the given ID. See pending_callbacks_. | |
| 79 void ExecuteCallback(uint32_t callback_id, int32_t result); | |
| 80 int32_t SetFileInfo(uint32_t callback_id, const PP_FileInfo& info); | |
| 81 int32_t SetReadDirectoryEntriesOutput( | |
| 82 uint32_t callback_id, | |
| 83 const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, | |
| 84 const std::vector<PP_FileType>& file_types); | |
| 85 | |
| 86 private: | |
| 87 PluginDispatcher* GetDispatcher() const { | |
| 88 return PluginDispatcher::GetForResource(this); | |
| 89 } | |
| 90 | |
| 91 // Adds a callback to the list and returns its ID. | |
| 92 uint32_t SendCallback(scoped_refptr<TrackedCallback> callback); | |
| 93 | |
| 94 // This class can have any number of out-standing requests with completion | |
| 95 // callbacks, in contrast to most resources which have one possible pending | |
| 96 // callback pending (like a Flush callback). | |
| 97 // | |
| 98 // To keep track of them, assign integer IDs to the callbacks, which is how | |
| 99 // the callback will be identified when it's passed to the host and then | |
| 100 // back here. Use unsigned so that overflow is well-defined. | |
| 101 uint32_t next_callback_id_; | |
| 102 typedef std::map<uint32_t, | |
| 103 scoped_refptr<TrackedCallback> > PendingCallbackMap; | |
| 104 PendingCallbackMap pending_callbacks_; | |
| 105 | |
| 106 // Used to keep pointers to PP_FileInfo instances that are written before | |
| 107 // callbacks are invoked. The id of a pending file info will match that of | |
| 108 // the corresponding callback. | |
| 109 typedef std::map<uint32_t, PP_FileInfo*> PendingFileInfoMap; | |
| 110 PendingFileInfoMap pending_file_infos_; | |
| 111 | |
| 112 // Used to keep PP_ArrayOutput instances that are written before callbacks | |
| 113 // are invoked. The id of a pending array output will match that of the | |
| 114 // corresponding callback. | |
| 115 typedef std::map<uint32_t, PP_ArrayOutput> | |
| 116 PendingReadDirectoryEntriesOutputMap; | |
| 117 PendingReadDirectoryEntriesOutputMap pending_read_entries_outputs_; | |
| 118 | |
| 119 // Holds a reference on plugin side when running out of process, so that | |
| 120 // FileSystem won't die before FileRef. See PPB_FileRef_Impl for | |
| 121 // corresponding code for in-process mode. Note that this workaround will | |
| 122 // be no longer needed after FileRef refactoring. | |
| 123 ScopedPPResource file_system_; | |
| 124 | |
| 125 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef); | |
| 126 }; | |
| 127 | |
| 128 FileRef::FileRef(const PPB_FileRef_CreateInfo& info) | |
| 129 : PPB_FileRef_Shared(OBJECT_IS_PROXY, info), | |
| 130 next_callback_id_(0u), | |
| 131 file_system_(info.file_system_plugin_resource) { | |
| 132 } | |
| 133 | |
| 134 FileRef::~FileRef() { | |
| 135 // The callbacks map should have been cleared by LastPluginRefWasDeleted. | |
| 136 DCHECK(pending_callbacks_.empty()); | |
| 137 DCHECK(pending_file_infos_.empty()); | |
| 138 DCHECK(pending_read_entries_outputs_.empty()); | |
| 139 } | |
| 140 | |
| 141 void FileRef::LastPluginRefWasDeleted() { | |
| 142 // The callback tracker will abort our callbacks for us. | |
| 143 pending_callbacks_.clear(); | |
| 144 pending_file_infos_.clear(); | |
| 145 pending_read_entries_outputs_.clear(); | |
| 146 } | |
| 147 | |
| 148 PP_Resource FileRef::GetParent() { | |
| 149 PPB_FileRef_CreateInfo create_info; | |
| 150 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent( | |
| 151 API_ID_PPB_FILE_REF, host_resource(), &create_info)); | |
| 152 return PPB_FileRef_Proxy::DeserializeFileRef(create_info); | |
| 153 } | |
| 154 | |
| 155 int32_t FileRef::MakeDirectory(PP_Bool make_ancestors, | |
| 156 scoped_refptr<TrackedCallback> callback) { | |
| 157 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_MakeDirectory( | |
| 158 API_ID_PPB_FILE_REF, host_resource(), make_ancestors, | |
| 159 SendCallback(callback))); | |
| 160 return PP_OK_COMPLETIONPENDING; | |
| 161 } | |
| 162 | |
| 163 int32_t FileRef::Touch(PP_Time last_access_time, | |
| 164 PP_Time last_modified_time, | |
| 165 scoped_refptr<TrackedCallback> callback) { | |
| 166 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Touch( | |
| 167 API_ID_PPB_FILE_REF, host_resource(), last_access_time, | |
| 168 last_modified_time, SendCallback(callback))); | |
| 169 return PP_OK_COMPLETIONPENDING; | |
| 170 } | |
| 171 | |
| 172 int32_t FileRef::Delete(scoped_refptr<TrackedCallback> callback) { | |
| 173 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Delete( | |
| 174 API_ID_PPB_FILE_REF, host_resource(), SendCallback(callback))); | |
| 175 return PP_OK_COMPLETIONPENDING; | |
| 176 } | |
| 177 | |
| 178 int32_t FileRef::Rename(PP_Resource new_file_ref, | |
| 179 scoped_refptr<TrackedCallback> callback) { | |
| 180 Resource* new_file_ref_object = | |
| 181 PpapiGlobals::Get()->GetResourceTracker()->GetResource(new_file_ref); | |
| 182 if (!new_file_ref_object || | |
| 183 new_file_ref_object->host_resource().instance() != pp_instance()) | |
| 184 return PP_ERROR_BADRESOURCE; | |
| 185 | |
| 186 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename( | |
| 187 API_ID_PPB_FILE_REF, host_resource(), | |
| 188 new_file_ref_object->host_resource(), SendCallback(callback))); | |
| 189 return PP_OK_COMPLETIONPENDING; | |
| 190 } | |
| 191 | |
| 192 int32_t FileRef::Query(PP_FileInfo* info, | |
| 193 scoped_refptr<TrackedCallback> callback) { | |
| 194 // Store the pending file info id. | |
| 195 uint32_t id = SendCallback(callback); | |
| 196 pending_file_infos_[id] = info; | |
| 197 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Query( | |
| 198 API_ID_PPB_FILE_REF, host_resource(), id)); | |
| 199 return PP_OK_COMPLETIONPENDING; | |
| 200 } | |
| 201 | |
| 202 int32_t FileRef::ReadDirectoryEntries( | |
| 203 const PP_ArrayOutput& output, | |
| 204 scoped_refptr<TrackedCallback> callback) { | |
| 205 // Store the pending read entries output id. | |
| 206 uint32_t id = SendCallback(callback); | |
| 207 pending_read_entries_outputs_[id] = output; | |
| 208 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_ReadDirectoryEntries( | |
| 209 API_ID_PPB_FILE_REF, host_resource(), id)); | |
| 210 return PP_OK_COMPLETIONPENDING; | |
| 211 } | |
| 212 | |
| 213 int32_t FileRef::QueryInHost( | |
| 214 linked_ptr<PP_FileInfo> info, | |
| 215 scoped_refptr<TrackedCallback> callback) { | |
| 216 NOTREACHED(); | |
| 217 return PP_ERROR_FAILED; | |
| 218 } | |
| 219 | |
| 220 int32_t FileRef::ReadDirectoryEntriesInHost( | |
| 221 linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, | |
| 222 linked_ptr<std::vector<PP_FileType> > file_types, | |
| 223 scoped_refptr<TrackedCallback> callback) { | |
| 224 NOTREACHED(); | |
| 225 return PP_ERROR_FAILED; | |
| 226 } | |
| 227 | |
| 228 PP_Var FileRef::GetAbsolutePath() { | |
| 229 ReceiveSerializedVarReturnValue result; | |
| 230 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetAbsolutePath( | |
| 231 API_ID_PPB_FILE_REF, host_resource(), &result)); | |
| 232 return result.Return(GetDispatcher()); | |
| 233 } | |
| 234 | |
| 235 void FileRef::ExecuteCallback(uint32_t callback_id, int32_t result) { | |
| 236 PendingCallbackMap::iterator found = pending_callbacks_.find(callback_id); | |
| 237 if (found == pending_callbacks_.end()) { | |
| 238 // This will happen when the plugin deletes its resource with a pending | |
| 239 // callback. The callback will be locally issued with an ABORTED call while | |
| 240 // the operation may still be pending in the renderer. | |
| 241 return; | |
| 242 } | |
| 243 | |
| 244 // Executing the callback may mutate the callback list. | |
| 245 scoped_refptr<TrackedCallback> callback = found->second; | |
| 246 pending_callbacks_.erase(found); | |
| 247 callback->Run(result); | |
| 248 } | |
| 249 | |
| 250 int32_t FileRef::SetFileInfo(uint32_t callback_id, const PP_FileInfo& info) { | |
| 251 PendingFileInfoMap::iterator found = pending_file_infos_.find(callback_id); | |
| 252 if (found == pending_file_infos_.end()) | |
| 253 return PP_ERROR_FAILED; | |
| 254 PP_FileInfo* target_info = found->second; | |
| 255 *target_info = info; | |
| 256 pending_file_infos_.erase(found); | |
| 257 return PP_OK; | |
| 258 } | |
| 259 | |
| 260 int32_t FileRef::SetReadDirectoryEntriesOutput( | |
| 261 uint32_t callback_id, | |
| 262 const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, | |
| 263 const std::vector<PP_FileType>& file_types) { | |
| 264 PendingReadDirectoryEntriesOutputMap::iterator found = | |
| 265 pending_read_entries_outputs_.find(callback_id); | |
| 266 if (found == pending_read_entries_outputs_.end()) | |
| 267 return PP_ERROR_FAILED; | |
| 268 | |
| 269 PP_ArrayOutput output = found->second; | |
| 270 pending_read_entries_outputs_.erase(found); | |
| 271 | |
| 272 std::vector<PP_DirectoryEntry> entries; | |
| 273 for (size_t i = 0; i < infos.size(); ++i) { | |
| 274 PP_DirectoryEntry entry; | |
| 275 entry.file_ref = PPB_FileRef_Proxy::DeserializeFileRef(infos[i]); | |
| 276 entry.file_type = file_types[i]; | |
| 277 entries.push_back(entry); | |
| 278 } | |
| 279 | |
| 280 ArrayWriter writer(output); | |
| 281 if (!writer.is_valid()) { | |
| 282 ReleaseEntries(entries); | |
| 283 return PP_ERROR_BADARGUMENT; | |
| 284 } | |
| 285 | |
| 286 writer.StoreVector(entries); | |
| 287 return PP_OK; | |
| 288 } | |
| 289 | |
| 290 uint32_t FileRef::SendCallback(scoped_refptr<TrackedCallback> callback) { | |
| 291 // In extreme cases the IDs may wrap around, so avoid duplicates. | |
| 292 while (pending_callbacks_.count(next_callback_id_)) | |
| 293 ++next_callback_id_; | |
| 294 | |
| 295 pending_callbacks_[next_callback_id_] = callback; | |
| 296 return next_callback_id_++; | |
| 297 } | |
| 298 | |
| 299 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher) | |
| 300 : InterfaceProxy(dispatcher), | |
| 301 callback_factory_(this) { | |
| 302 } | |
| 303 | |
| 304 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() { | |
| 305 } | |
| 306 | |
| 307 // static | |
| 308 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Instance instance, | |
| 309 PP_Resource file_system, | |
| 310 const char* path) { | |
| 311 PPB_FileRef_CreateInfo create_info; | |
| 312 PluginDispatcher::GetForInstance(instance)->Send( | |
| 313 new PpapiHostMsg_PPBFileRef_Create( | |
| 314 API_ID_PPB_FILE_REF, instance, file_system, path, &create_info)); | |
| 315 return PPB_FileRef_Proxy::DeserializeFileRef(create_info); | |
| 316 } | |
| 317 | |
| 318 bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
| 319 bool handled = true; | |
| 320 IPC_BEGIN_MESSAGE_MAP(PPB_FileRef_Proxy, msg) | |
| 321 #if !defined(OS_NACL) | |
| 322 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Create, OnMsgCreate) | |
| 323 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetParent, OnMsgGetParent) | |
| 324 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_MakeDirectory, | |
| 325 OnMsgMakeDirectory) | |
| 326 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Touch, OnMsgTouch) | |
| 327 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Delete, OnMsgDelete) | |
| 328 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Rename, OnMsgRename) | |
| 329 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_Query, OnMsgQuery) | |
| 330 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_ReadDirectoryEntries, | |
| 331 OnMsgReadDirectoryEntries) | |
| 332 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileRef_GetAbsolutePath, | |
| 333 OnMsgGetAbsolutePath) | |
| 334 #endif // !defined(OS_NACL) | |
| 335 | |
| 336 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_CallbackComplete, | |
| 337 OnMsgCallbackComplete) | |
| 338 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileRef_QueryCallbackComplete, | |
| 339 OnMsgQueryCallbackComplete) | |
| 340 IPC_MESSAGE_HANDLER( | |
| 341 PpapiMsg_PPBFileRef_ReadDirectoryEntriesCallbackComplete, | |
| 342 OnMsgReadDirectoryEntriesCallbackComplete) | |
| 343 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 344 IPC_END_MESSAGE_MAP() | |
| 345 return handled; | |
| 346 } | |
| 347 | |
| 348 // static | |
| 349 void PPB_FileRef_Proxy::SerializeFileRef(PP_Resource file_ref, | |
| 350 PPB_FileRef_CreateInfo* result) { | |
| 351 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, false); | |
| 352 if (enter.succeeded()) | |
| 353 *result = enter.object()->GetCreateInfo(); | |
| 354 } | |
| 355 | |
| 356 // static | |
| 357 PP_Resource PPB_FileRef_Proxy::DeserializeFileRef( | |
| 358 const PPB_FileRef_CreateInfo& serialized) { | |
| 359 if (serialized.resource.is_null()) | |
| 360 return 0; // Resource invalid. | |
| 361 return (new FileRef(serialized))->GetReference(); | |
| 362 } | |
| 363 | |
| 364 #if !defined(OS_NACL) | |
| 365 void PPB_FileRef_Proxy::OnMsgCreate(PP_Instance pp_instance, | |
| 366 PP_Resource file_system, | |
| 367 const std::string& path, | |
| 368 PPB_FileRef_CreateInfo* result) { | |
| 369 thunk::EnterResourceCreation enter(pp_instance); | |
| 370 if (enter.failed()) | |
| 371 return; | |
| 372 | |
| 373 PP_Resource resource = enter.functions()->CreateFileRef( | |
| 374 pp_instance, file_system, path.c_str()); | |
| 375 if (!resource) | |
| 376 return; // CreateInfo default constructor initializes to 0. | |
| 377 SerializeFileRef(resource, result); | |
| 378 } | |
| 379 | |
| 380 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource, | |
| 381 PPB_FileRef_CreateInfo* result) { | |
| 382 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); | |
| 383 if (enter.succeeded()) | |
| 384 SerializeFileRef(enter.object()->GetParent(), result); | |
| 385 } | |
| 386 | |
| 387 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource, | |
| 388 PP_Bool make_ancestors, | |
| 389 uint32_t callback_id) { | |
| 390 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( | |
| 391 host_resource, callback_factory_, | |
| 392 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); | |
| 393 if (enter.succeeded()) { | |
| 394 enter.SetResult(enter.object()->MakeDirectory(make_ancestors, | |
| 395 enter.callback())); | |
| 396 } | |
| 397 } | |
| 398 | |
| 399 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource, | |
| 400 PP_Time last_access, | |
| 401 PP_Time last_modified, | |
| 402 uint32_t callback_id) { | |
| 403 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( | |
| 404 host_resource, callback_factory_, | |
| 405 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); | |
| 406 if (enter.succeeded()) { | |
| 407 enter.SetResult(enter.object()->Touch(last_access, last_modified, | |
| 408 enter.callback())); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource, | |
| 413 uint32_t callback_id) { | |
| 414 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( | |
| 415 host_resource, callback_factory_, | |
| 416 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); | |
| 417 if (enter.succeeded()) | |
| 418 enter.SetResult(enter.object()->Delete(enter.callback())); | |
| 419 } | |
| 420 | |
| 421 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref, | |
| 422 const HostResource& new_file_ref, | |
| 423 uint32_t callback_id) { | |
| 424 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( | |
| 425 file_ref, callback_factory_, | |
| 426 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id); | |
| 427 if (enter.succeeded()) { | |
| 428 enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(), | |
| 429 enter.callback())); | |
| 430 } | |
| 431 } | |
| 432 | |
| 433 void PPB_FileRef_Proxy::OnMsgQuery(const HostResource& file_ref, | |
| 434 uint32_t callback_id) { | |
| 435 linked_ptr<PP_FileInfo> info(new PP_FileInfo()); | |
| 436 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( | |
| 437 file_ref, callback_factory_, | |
| 438 &PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost, file_ref, | |
| 439 info, callback_id); | |
| 440 if (enter.succeeded()) | |
| 441 enter.SetResult(enter.object()->QueryInHost(info, enter.callback())); | |
| 442 } | |
| 443 | |
| 444 void PPB_FileRef_Proxy::OnMsgGetAbsolutePath(const HostResource& host_resource, | |
| 445 SerializedVarReturnValue result) { | |
| 446 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); | |
| 447 if (enter.succeeded()) | |
| 448 result.Return(dispatcher(), enter.object()->GetAbsolutePath()); | |
| 449 } | |
| 450 | |
| 451 void PPB_FileRef_Proxy::OnMsgReadDirectoryEntries(const HostResource& file_ref, | |
| 452 uint32_t callback_id) { | |
| 453 linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files( | |
| 454 new std::vector<ppapi::PPB_FileRef_CreateInfo>()); | |
| 455 linked_ptr<std::vector<PP_FileType> > file_types( | |
| 456 new std::vector<PP_FileType>()); | |
| 457 HostCallbackParams params(file_ref, callback_id); | |
| 458 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( | |
| 459 file_ref, callback_factory_, | |
| 460 &PPB_FileRef_Proxy::OnReadDirectoryEntriesCallbackCompleteInHost, | |
| 461 params, files, file_types); | |
| 462 if (enter.succeeded()) { | |
| 463 enter.SetResult(enter.object()->ReadDirectoryEntriesInHost( | |
| 464 files, file_types, enter.callback())); | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 #endif // !defined(OS_NACL) | |
| 469 | |
| 470 void PPB_FileRef_Proxy::OnMsgCallbackComplete( | |
| 471 const HostResource& host_resource, | |
| 472 uint32_t callback_id, | |
| 473 int32_t result) { | |
| 474 // Forward the callback info to the plugin resource. | |
| 475 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); | |
| 476 if (enter.succeeded()) | |
| 477 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result); | |
| 478 } | |
| 479 | |
| 480 void PPB_FileRef_Proxy::OnMsgQueryCallbackComplete( | |
| 481 const HostResource& host_resource, | |
| 482 const PP_FileInfo& info, | |
| 483 uint32_t callback_id, | |
| 484 int32_t result) { | |
| 485 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); | |
| 486 if (!enter.succeeded()) | |
| 487 return; | |
| 488 | |
| 489 if (result == PP_OK) { | |
| 490 result = static_cast<FileRef*>(enter.object())->SetFileInfo( | |
| 491 callback_id, info); | |
| 492 } | |
| 493 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result); | |
| 494 } | |
| 495 | |
| 496 void PPB_FileRef_Proxy::OnMsgReadDirectoryEntriesCallbackComplete( | |
| 497 const HostResource& host_resource, | |
| 498 const std::vector<ppapi::PPB_FileRef_CreateInfo>& infos, | |
| 499 const std::vector<PP_FileType>& file_types, | |
| 500 uint32_t callback_id, | |
| 501 int32_t result) { | |
| 502 CHECK_EQ(infos.size(), file_types.size()); | |
| 503 | |
| 504 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource); | |
| 505 if (!enter.succeeded()) | |
| 506 return; | |
| 507 | |
| 508 if (result == PP_OK) { | |
| 509 result = | |
| 510 static_cast<FileRef*>(enter.object())->SetReadDirectoryEntriesOutput( | |
| 511 callback_id, infos, file_types); | |
| 512 } | |
| 513 static_cast<FileRef*>(enter.object())->ExecuteCallback( | |
| 514 callback_id, result); | |
| 515 } | |
| 516 | |
| 517 #if !defined(OS_NACL) | |
| 518 void PPB_FileRef_Proxy::OnCallbackCompleteInHost( | |
| 519 int32_t result, | |
| 520 const HostResource& host_resource, | |
| 521 uint32_t callback_id) { | |
| 522 // Execute OnMsgCallbackComplete in the plugin process. | |
| 523 Send(new PpapiMsg_PPBFileRef_CallbackComplete( | |
| 524 API_ID_PPB_FILE_REF, host_resource, callback_id, result)); | |
| 525 } | |
| 526 | |
| 527 void PPB_FileRef_Proxy::OnQueryCallbackCompleteInHost( | |
| 528 int32_t result, | |
| 529 const HostResource& host_resource, | |
| 530 linked_ptr<PP_FileInfo> info, | |
| 531 uint32_t callback_id) { | |
| 532 Send(new PpapiMsg_PPBFileRef_QueryCallbackComplete( | |
| 533 API_ID_PPB_FILE_REF, host_resource, *info, callback_id, result)); | |
| 534 } | |
| 535 | |
| 536 void PPB_FileRef_Proxy::OnReadDirectoryEntriesCallbackCompleteInHost( | |
| 537 int32_t result, | |
| 538 HostCallbackParams params, | |
| 539 linked_ptr<std::vector<ppapi::PPB_FileRef_CreateInfo> > files, | |
| 540 linked_ptr<std::vector<PP_FileType> > file_types) { | |
| 541 Send(new PpapiMsg_PPBFileRef_ReadDirectoryEntriesCallbackComplete( | |
| 542 API_ID_PPB_FILE_REF, params.host_resource, | |
| 543 *files, *file_types, params.callback_id, result)); | |
| 544 } | |
| 545 | |
| 546 #endif // !defined(OS_NACL) | |
| 547 | |
| 548 } // namespace proxy | |
| 549 } // namespace ppapi | |
| OLD | NEW |