| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h" | 5 #include "chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 task_helper->OpenStorage(storage_name, read_only, reply_callback); | 89 task_helper->OpenStorage(storage_name, read_only, reply_callback); |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Enumerates the |dir_id| directory file entries. | 92 // Enumerates the |dir_id| directory file entries. |
| 93 // | 93 // |
| 94 // Called on the UI thread to dispatch the request to the | 94 // Called on the UI thread to dispatch the request to the |
| 95 // MediaTransferProtocolManager. | 95 // MediaTransferProtocolManager. |
| 96 // | 96 // |
| 97 // |storage_name| specifies the name of the storage device. | 97 // |storage_name| specifies the name of the storage device. |
| 98 // |read_only| specifies the mode of the storage device. | 98 // |read_only| specifies the mode of the storage device. |
| 99 // |directory_id| is an id of a directory to read. |
| 100 // |max_size| is a maximum size to read. Set 0 not to specify the maximum size. |
| 99 // |success_callback| is called when the ReadDirectory request succeeds. | 101 // |success_callback| is called when the ReadDirectory request succeeds. |
| 100 // |error_callback| is called when the ReadDirectory request fails. | 102 // |error_callback| is called when the ReadDirectory request fails. |
| 101 // |success_callback| and |error_callback| runs on the IO thread. | 103 // |success_callback| and |error_callback| runs on the IO thread. |
| 102 void ReadDirectoryOnUIThread( | 104 void ReadDirectoryOnUIThread( |
| 103 const std::string& storage_name, | 105 const std::string& storage_name, |
| 104 const bool read_only, | 106 const bool read_only, |
| 105 uint32 dir_id, | 107 const uint32 directory_id, |
| 108 const size_t max_size, |
| 106 const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, | 109 const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, |
| 107 const MTPDeviceTaskHelper::ErrorCallback& error_callback) { | 110 const MTPDeviceTaskHelper::ErrorCallback& error_callback) { |
| 108 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 111 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 109 MTPDeviceTaskHelper* task_helper = | 112 MTPDeviceTaskHelper* task_helper = |
| 110 GetDeviceTaskHelperForStorage(storage_name, read_only); | 113 GetDeviceTaskHelperForStorage(storage_name, read_only); |
| 111 if (!task_helper) | 114 if (!task_helper) |
| 112 return; | 115 return; |
| 113 task_helper->ReadDirectory(dir_id, success_callback, error_callback); | 116 task_helper->ReadDirectory(directory_id, max_size, success_callback, |
| 117 error_callback); |
| 114 } | 118 } |
| 115 | 119 |
| 116 // Gets the |file_path| details. | 120 // Gets the |file_path| details. |
| 117 // | 121 // |
| 118 // Called on the UI thread to dispatch the request to the | 122 // Called on the UI thread to dispatch the request to the |
| 119 // MediaTransferProtocolManager. | 123 // MediaTransferProtocolManager. |
| 120 // | 124 // |
| 121 // |storage_name| specifies the name of the storage device. | 125 // |storage_name| specifies the name of the storage device. |
| 122 // |read_only| specifies the mode of the storage device. | 126 // |read_only| specifies the mode of the storage device. |
| 123 // |success_callback| is called when the GetFileInfo request succeeds. | 127 // |success_callback| is called when the GetFileInfo request succeeds. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 211 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 208 MTPDeviceTaskHelper* task_helper = | 212 MTPDeviceTaskHelper* task_helper = |
| 209 GetDeviceTaskHelperForStorage(storage_name, read_only); | 213 GetDeviceTaskHelperForStorage(storage_name, read_only); |
| 210 if (!task_helper) | 214 if (!task_helper) |
| 211 return; | 215 return; |
| 212 task_helper->CopyFileFromLocal(storage_name, source_file_descriptor, | 216 task_helper->CopyFileFromLocal(storage_name, source_file_descriptor, |
| 213 parent_id, file_name, success_callback, | 217 parent_id, file_name, success_callback, |
| 214 error_callback); | 218 error_callback); |
| 215 } | 219 } |
| 216 | 220 |
| 221 // Deletes |object_id|. |
| 222 // |
| 223 // Called on the UI thread to dispatch the request to the |
| 224 // MediaTransferProtocolManager. |
| 225 // |
| 226 // |storage_name| specifies the name of the storage device. |
| 227 // |read_only| specifies the mode of the storage device. |
| 228 // |object_id| is the object to be deleted. |
| 229 // |success_callback| is called when the object is deleted successfully. |
| 230 // |error_callback| is called when it fails to delete the object. |
| 231 // |success_callback| and |error_callback| runs on the IO thread. |
| 232 void DeleteObjectOnUIThread( |
| 233 const std::string storage_name, |
| 234 const bool read_only, |
| 235 const uint32 object_id, |
| 236 const MTPDeviceTaskHelper::DeleteObjectSuccessCallback success_callback, |
| 237 const MTPDeviceTaskHelper::ErrorCallback error_callback) { |
| 238 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 239 MTPDeviceTaskHelper* task_helper = |
| 240 GetDeviceTaskHelperForStorage(storage_name, read_only); |
| 241 if (!task_helper) |
| 242 return; |
| 243 task_helper->DeleteObject(object_id, success_callback, error_callback); |
| 244 } |
| 245 |
| 217 // Closes the device storage specified by the |storage_name| and destroys the | 246 // Closes the device storage specified by the |storage_name| and destroys the |
| 218 // MTPDeviceTaskHelper object associated with the device storage. | 247 // MTPDeviceTaskHelper object associated with the device storage. |
| 219 // | 248 // |
| 220 // Called on the UI thread to dispatch the request to the | 249 // Called on the UI thread to dispatch the request to the |
| 221 // MediaTransferProtocolManager. | 250 // MediaTransferProtocolManager. |
| 222 void CloseStorageAndDestroyTaskHelperOnUIThread( | 251 void CloseStorageAndDestroyTaskHelperOnUIThread( |
| 223 const std::string& storage_name, | 252 const std::string& storage_name, |
| 224 const bool read_only) { | 253 const bool read_only) { |
| 225 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 254 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 226 MTPDeviceTaskHelper* task_helper = | 255 MTPDeviceTaskHelper* task_helper = |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 const MTPFileNode* GetChild(const std::string& name) const; | 304 const MTPFileNode* GetChild(const std::string& name) const; |
| 276 | 305 |
| 277 void EnsureChildExists(const std::string& name, uint32 id); | 306 void EnsureChildExists(const std::string& name, uint32 id); |
| 278 | 307 |
| 279 // Clears all the children, except those in |children_to_keep|. | 308 // Clears all the children, except those in |children_to_keep|. |
| 280 void ClearNonexistentChildren( | 309 void ClearNonexistentChildren( |
| 281 const std::set<std::string>& children_to_keep); | 310 const std::set<std::string>& children_to_keep); |
| 282 | 311 |
| 283 bool DeleteChild(uint32 file_id); | 312 bool DeleteChild(uint32 file_id); |
| 284 | 313 |
| 314 bool HasChildren() const; |
| 315 |
| 285 uint32 file_id() const { return file_id_; } | 316 uint32 file_id() const { return file_id_; } |
| 286 const std::string& file_name() const { return file_name_; } | 317 const std::string& file_name() const { return file_name_; } |
| 287 MTPFileNode* parent() { return parent_; } | 318 MTPFileNode* parent() { return parent_; } |
| 288 | 319 |
| 289 private: | 320 private: |
| 290 // Container for holding a node's children. | 321 // Container for holding a node's children. |
| 291 typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes; | 322 typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes; |
| 292 | 323 |
| 293 const uint32 file_id_; | 324 const uint32 file_id_; |
| 294 const std::string file_name_; | 325 const std::string file_name_; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 it != children_to_erase.end(); ++it) { | 386 it != children_to_erase.end(); ++it) { |
| 356 children_.take_and_erase(*it); | 387 children_.take_and_erase(*it); |
| 357 } | 388 } |
| 358 } | 389 } |
| 359 | 390 |
| 360 bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32 file_id) { | 391 bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32 file_id) { |
| 361 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 392 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 362 for (ChildNodes::iterator it = children_.begin(); | 393 for (ChildNodes::iterator it = children_.begin(); |
| 363 it != children_.end(); ++it) { | 394 it != children_.end(); ++it) { |
| 364 if (it->second->file_id() == file_id) { | 395 if (it->second->file_id() == file_id) { |
| 396 DCHECK(!it->second->HasChildren()); |
| 365 children_.erase(it); | 397 children_.erase(it); |
| 366 return true; | 398 return true; |
| 367 } | 399 } |
| 368 } | 400 } |
| 369 return false; | 401 return false; |
| 370 } | 402 } |
| 371 | 403 |
| 404 bool MTPDeviceDelegateImplLinux::MTPFileNode::HasChildren() const { |
| 405 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 406 return children_.size() > 0; |
| 407 } |
| 408 |
| 372 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( | 409 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( |
| 373 const std::string& device_location, | 410 const std::string& device_location, |
| 374 const bool read_only) | 411 const bool read_only) |
| 375 : init_state_(UNINITIALIZED), | 412 : init_state_(UNINITIALIZED), |
| 376 task_in_progress_(false), | 413 task_in_progress_(false), |
| 377 device_path_(device_location), | 414 device_path_(device_location), |
| 378 read_only_(read_only), | 415 read_only_(read_only), |
| 379 root_node_(new MTPFileNode(mtpd::kRootFileId, | 416 root_node_(new MTPFileNode(mtpd::kRootFileId, |
| 380 "", // Root node has no name. | 417 "", // Root node has no name. |
| 381 NULL, // And no parent node. | 418 NULL, // And no parent node. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 offset, | 524 offset, |
| 488 buf_len, | 525 buf_len, |
| 489 success_callback, | 526 success_callback, |
| 490 error_callback); | 527 error_callback); |
| 491 EnsureInitAndRunTask(PendingTaskInfo(device_file_path, | 528 EnsureInitAndRunTask(PendingTaskInfo(device_file_path, |
| 492 content::BrowserThread::IO, | 529 content::BrowserThread::IO, |
| 493 FROM_HERE, | 530 FROM_HERE, |
| 494 closure)); | 531 closure)); |
| 495 } | 532 } |
| 496 | 533 |
| 497 bool MTPDeviceDelegateImplLinux::IsReadOnly() { | 534 bool MTPDeviceDelegateImplLinux::IsReadOnly() const { |
| 498 return read_only_; | 535 return read_only_; |
| 499 } | 536 } |
| 500 | 537 |
| 501 void MTPDeviceDelegateImplLinux::CopyFileFromLocal( | 538 void MTPDeviceDelegateImplLinux::CopyFileFromLocal( |
| 502 const base::FilePath& source_file_path, | 539 const base::FilePath& source_file_path, |
| 503 const base::FilePath& device_file_path, | 540 const base::FilePath& device_file_path, |
| 504 const CopyFileFromLocalSuccessCallback& success_callback, | 541 const CopyFileFromLocalSuccessCallback& success_callback, |
| 505 const ErrorCallback& error_callback) { | 542 const ErrorCallback& error_callback) { |
| 506 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 543 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 507 DCHECK(!source_file_path.empty()); | 544 DCHECK(!source_file_path.empty()); |
| 508 DCHECK(!device_file_path.empty()); | 545 DCHECK(!device_file_path.empty()); |
| 509 | 546 |
| 510 content::BrowserThread::PostTaskAndReplyWithResult( | 547 content::BrowserThread::PostTaskAndReplyWithResult( |
| 511 content::BrowserThread::FILE, | 548 content::BrowserThread::FILE, |
| 512 FROM_HERE, | 549 FROM_HERE, |
| 513 base::Bind(&OpenFileDescriptor, | 550 base::Bind(&OpenFileDescriptor, |
| 514 source_file_path.value().c_str(), | 551 source_file_path.value().c_str(), |
| 515 O_RDONLY), | 552 O_RDONLY), |
| 516 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal, | 553 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal, |
| 517 weak_ptr_factory_.GetWeakPtr(), | 554 weak_ptr_factory_.GetWeakPtr(), |
| 518 device_file_path, | 555 device_file_path, |
| 519 success_callback, | 556 success_callback, |
| 520 error_callback)); | 557 error_callback)); |
| 521 } | 558 } |
| 522 | 559 |
| 560 void MTPDeviceDelegateImplLinux::DeleteFile( |
| 561 const base::FilePath& file_path, |
| 562 const DeleteFileSuccessCallback& success_callback, |
| 563 const ErrorCallback& error_callback) { |
| 564 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 565 DCHECK(!file_path.empty()); |
| 566 |
| 567 const GetFileInfoSuccessCallback& success_callback_wrapper = |
| 568 base::Bind(&MTPDeviceDelegateImplLinux::DeleteFileInternal, |
| 569 weak_ptr_factory_.GetWeakPtr(), file_path, success_callback, |
| 570 error_callback); |
| 571 |
| 572 const base::Closure closure = |
| 573 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, |
| 574 weak_ptr_factory_.GetWeakPtr(), file_path, |
| 575 success_callback_wrapper, error_callback); |
| 576 EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO, |
| 577 FROM_HERE, closure)); |
| 578 } |
| 579 |
| 580 void MTPDeviceDelegateImplLinux::DeleteDirectory( |
| 581 const base::FilePath& file_path, |
| 582 const DeleteDirectorySuccessCallback& success_callback, |
| 583 const ErrorCallback& error_callback) { |
| 584 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 585 DCHECK(!file_path.empty()); |
| 586 |
| 587 const GetFileInfoSuccessCallback& success_callback_wrapper = |
| 588 base::Bind(&MTPDeviceDelegateImplLinux::DeleteDirectoryInternal, |
| 589 weak_ptr_factory_.GetWeakPtr(), file_path, success_callback, |
| 590 error_callback); |
| 591 |
| 592 const base::Closure closure = |
| 593 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, |
| 594 weak_ptr_factory_.GetWeakPtr(), file_path, |
| 595 success_callback_wrapper, error_callback); |
| 596 EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO, |
| 597 FROM_HERE, closure)); |
| 598 } |
| 599 |
| 523 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { | 600 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { |
| 524 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 601 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 525 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. | 602 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. |
| 526 content::BrowserThread::PostTask( | 603 content::BrowserThread::PostTask( |
| 527 content::BrowserThread::UI, | 604 content::BrowserThread::UI, |
| 528 FROM_HERE, | 605 FROM_HERE, |
| 529 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, | 606 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, |
| 530 storage_name_, | 607 storage_name_, |
| 531 read_only_)); | 608 read_only_)); |
| 532 delete this; | 609 delete this; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 EnsureInitAndRunTask(PendingTaskInfo( | 786 EnsureInitAndRunTask(PendingTaskInfo( |
| 710 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); | 787 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); |
| 711 } else { | 788 } else { |
| 712 HandleCopyFileFromLocalError(error_callback, source_file_descriptor, | 789 HandleCopyFileFromLocalError(error_callback, source_file_descriptor, |
| 713 base::File::FILE_ERROR_INVALID_OPERATION); | 790 base::File::FILE_ERROR_INVALID_OPERATION); |
| 714 } | 791 } |
| 715 | 792 |
| 716 PendingRequestDone(); | 793 PendingRequestDone(); |
| 717 } | 794 } |
| 718 | 795 |
| 796 void MTPDeviceDelegateImplLinux::DeleteFileInternal( |
| 797 const base::FilePath& file_path, |
| 798 const DeleteFileSuccessCallback& success_callback, |
| 799 const ErrorCallback& error_callback, |
| 800 const base::File::Info& file_info) { |
| 801 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 802 |
| 803 if (file_info.is_directory) { |
| 804 error_callback.Run(base::File::FILE_ERROR_NOT_A_FILE); |
| 805 } else { |
| 806 uint32 file_id; |
| 807 if (CachedPathToId(file_path, &file_id)) |
| 808 RunDeleteObjectOnUIThread(file_id, success_callback, error_callback); |
| 809 else |
| 810 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); |
| 811 } |
| 812 |
| 813 PendingRequestDone(); |
| 814 } |
| 815 |
| 816 void MTPDeviceDelegateImplLinux::DeleteDirectoryInternal( |
| 817 const base::FilePath& file_path, |
| 818 const DeleteDirectorySuccessCallback& success_callback, |
| 819 const ErrorCallback& error_callback, |
| 820 const base::File::Info& file_info) { |
| 821 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 822 |
| 823 if (!file_info.is_directory) { |
| 824 error_callback.Run(base::File::FILE_ERROR_NOT_A_DIRECTORY); |
| 825 PendingRequestDone(); |
| 826 return; |
| 827 } |
| 828 |
| 829 uint32 directory_id; |
| 830 if (!CachedPathToId(file_path, &directory_id)) { |
| 831 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); |
| 832 PendingRequestDone(); |
| 833 return; |
| 834 } |
| 835 |
| 836 // Checks the cache first. If it has children in cache, the directory cannot |
| 837 // be empty. |
| 838 FileIdToMTPFileNodeMap::const_iterator it = |
| 839 file_id_to_node_map_.find(directory_id); |
| 840 if (it != file_id_to_node_map_.end() && it->second->HasChildren()) { |
| 841 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY); |
| 842 PendingRequestDone(); |
| 843 return; |
| 844 } |
| 845 |
| 846 // Since the directory can contain a file even if the cache returns it as |
| 847 // empty, read the directory and confirm the directory is actually empty. |
| 848 const MTPDeviceTaskHelper::ReadDirectorySuccessCallback |
| 849 success_callback_wrapper = base::Bind( |
| 850 &MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory, |
| 851 weak_ptr_factory_.GetWeakPtr(), directory_id, success_callback, |
| 852 error_callback); |
| 853 const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = |
| 854 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, |
| 855 weak_ptr_factory_.GetWeakPtr(), error_callback, directory_id); |
| 856 const base::Closure closure = base::Bind( |
| 857 &ReadDirectoryOnUIThread, storage_name_, read_only_, directory_id, |
| 858 1 /* max_size */, success_callback_wrapper, error_callback_wrapper); |
| 859 EnsureInitAndRunTask(PendingTaskInfo( |
| 860 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); |
| 861 PendingRequestDone(); |
| 862 } |
| 863 |
| 864 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory( |
| 865 const uint32 directory_id, |
| 866 const DeleteDirectorySuccessCallback& success_callback, |
| 867 const ErrorCallback& error_callback, |
| 868 const storage::AsyncFileUtil::EntryList& entries, |
| 869 const bool has_more) { |
| 870 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 871 DCHECK(!has_more); |
| 872 |
| 873 if (entries.size() > 0) |
| 874 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY); |
| 875 else |
| 876 RunDeleteObjectOnUIThread(directory_id, success_callback, error_callback); |
| 877 |
| 878 PendingRequestDone(); |
| 879 } |
| 880 |
| 881 void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread( |
| 882 const uint32 object_id, |
| 883 const DeleteObjectSuccessCallback& success_callback, |
| 884 const ErrorCallback& error_callback) { |
| 885 const MTPDeviceTaskHelper::DeleteObjectSuccessCallback |
| 886 success_callback_wrapper = base::Bind( |
| 887 &MTPDeviceDelegateImplLinux::OnDidDeleteObject, |
| 888 weak_ptr_factory_.GetWeakPtr(), object_id, success_callback); |
| 889 |
| 890 const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = |
| 891 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError, |
| 892 weak_ptr_factory_.GetWeakPtr(), error_callback); |
| 893 |
| 894 const base::Closure closure = |
| 895 base::Bind(&DeleteObjectOnUIThread, storage_name_, read_only_, object_id, |
| 896 success_callback_wrapper, error_callback_wrapper); |
| 897 EnsureInitAndRunTask(PendingTaskInfo( |
| 898 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); |
| 899 } |
| 900 |
| 719 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( | 901 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( |
| 720 const PendingTaskInfo& task_info) { | 902 const PendingTaskInfo& task_info) { |
| 721 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 903 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 722 if ((init_state_ == INITIALIZED) && !task_in_progress_) { | 904 if ((init_state_ == INITIALIZED) && !task_in_progress_) { |
| 723 RunTask(task_info); | 905 RunTask(task_info); |
| 724 return; | 906 return; |
| 725 } | 907 } |
| 726 | 908 |
| 727 // Only *Internal functions have empty paths. Since they are the continuation | 909 // Only *Internal functions have empty paths. Since they are the continuation |
| 728 // of the current running task, they get to cut in line. | 910 // of the current running task, they get to cut in line. |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 const ErrorCallback& error_callback, | 1011 const ErrorCallback& error_callback, |
| 830 const base::File::Info& file_info) { | 1012 const base::File::Info& file_info) { |
| 831 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1013 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 832 DCHECK(task_in_progress_); | 1014 DCHECK(task_in_progress_); |
| 833 if (!file_info.is_directory) { | 1015 if (!file_info.is_directory) { |
| 834 return HandleDeviceFileError(error_callback, | 1016 return HandleDeviceFileError(error_callback, |
| 835 dir_id, | 1017 dir_id, |
| 836 base::File::FILE_ERROR_NOT_A_DIRECTORY); | 1018 base::File::FILE_ERROR_NOT_A_DIRECTORY); |
| 837 } | 1019 } |
| 838 | 1020 |
| 839 base::Closure task_closure = | 1021 base::Closure task_closure = base::Bind( |
| 840 base::Bind(&ReadDirectoryOnUIThread, | 1022 &ReadDirectoryOnUIThread, storage_name_, read_only_, dir_id, |
| 841 storage_name_, | 1023 0 /* max_size */, |
| 842 read_only_, | 1024 base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadDirectory, |
| 843 dir_id, | 1025 weak_ptr_factory_.GetWeakPtr(), dir_id, success_callback), |
| 844 base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadDirectory, | 1026 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, |
| 845 weak_ptr_factory_.GetWeakPtr(), | 1027 weak_ptr_factory_.GetWeakPtr(), error_callback, dir_id)); |
| 846 dir_id, | |
| 847 success_callback), | |
| 848 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, | |
| 849 weak_ptr_factory_.GetWeakPtr(), | |
| 850 error_callback, | |
| 851 dir_id)); | |
| 852 content::BrowserThread::PostTask(content::BrowserThread::UI, | 1028 content::BrowserThread::PostTask(content::BrowserThread::UI, |
| 853 FROM_HERE, | 1029 FROM_HERE, |
| 854 task_closure); | 1030 task_closure); |
| 855 } | 1031 } |
| 856 | 1032 |
| 857 void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile( | 1033 void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile( |
| 858 scoped_ptr<SnapshotRequestInfo> snapshot_request_info, | 1034 scoped_ptr<SnapshotRequestInfo> snapshot_request_info, |
| 859 const base::File::Info& file_info) { | 1035 const base::File::Info& file_info) { |
| 860 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1036 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 861 DCHECK(!current_snapshot_request_info_.get()); | 1037 DCHECK(!current_snapshot_request_info_.get()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 const base::Closure closure = base::Bind(&CloseFileDescriptor, | 1191 const base::Closure closure = base::Bind(&CloseFileDescriptor, |
| 1016 source_file_descriptor); | 1192 source_file_descriptor); |
| 1017 | 1193 |
| 1018 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, | 1194 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, |
| 1019 closure); | 1195 closure); |
| 1020 | 1196 |
| 1021 error_callback.Run(error); | 1197 error_callback.Run(error); |
| 1022 PendingRequestDone(); | 1198 PendingRequestDone(); |
| 1023 } | 1199 } |
| 1024 | 1200 |
| 1201 void MTPDeviceDelegateImplLinux::OnDidDeleteObject( |
| 1202 const uint32 object_id, |
| 1203 const DeleteObjectSuccessCallback success_callback) { |
| 1204 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1205 |
| 1206 EvictCachedPathToId(object_id); |
| 1207 success_callback.Run(); |
| 1208 PendingRequestDone(); |
| 1209 } |
| 1210 |
| 1211 void MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError( |
| 1212 const ErrorCallback& error_callback, |
| 1213 base::File::Error error) { |
| 1214 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1215 |
| 1216 error_callback.Run(error); |
| 1217 PendingRequestDone(); |
| 1218 } |
| 1219 |
| 1025 void MTPDeviceDelegateImplLinux::HandleDeviceFileError( | 1220 void MTPDeviceDelegateImplLinux::HandleDeviceFileError( |
| 1026 const ErrorCallback& error_callback, | 1221 const ErrorCallback& error_callback, |
| 1027 uint32 file_id, | 1222 uint32 file_id, |
| 1028 base::File::Error error) { | 1223 base::File::Error error) { |
| 1029 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1224 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1030 | 1225 |
| 1031 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(file_id); | 1226 EvictCachedPathToId(file_id); |
| 1032 if (it != file_id_to_node_map_.end()) { | |
| 1033 MTPFileNode* parent = it->second->parent(); | |
| 1034 if (parent) { | |
| 1035 bool ret = parent->DeleteChild(file_id); | |
| 1036 DCHECK(ret); | |
| 1037 } | |
| 1038 } | |
| 1039 error_callback.Run(error); | 1227 error_callback.Run(error); |
| 1040 PendingRequestDone(); | 1228 PendingRequestDone(); |
| 1041 } | 1229 } |
| 1042 | 1230 |
| 1043 base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent( | 1231 base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent( |
| 1044 const base::FilePath& path, | 1232 const base::FilePath& path, |
| 1045 const base::FilePath& cached_path) const { | 1233 const base::FilePath& cached_path) const { |
| 1046 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1234 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1047 DCHECK(cached_path.empty() || cached_path.IsParent(path)); | 1235 DCHECK(cached_path.empty() || cached_path.IsParent(path)); |
| 1048 | 1236 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 const MTPFileNode* current_node = root_node_.get(); | 1290 const MTPFileNode* current_node = root_node_.get(); |
| 1103 for (size_t i = 0; i < device_relpath_components.size(); ++i) { | 1291 for (size_t i = 0; i < device_relpath_components.size(); ++i) { |
| 1104 current_node = current_node->GetChild(device_relpath_components[i]); | 1292 current_node = current_node->GetChild(device_relpath_components[i]); |
| 1105 if (!current_node) | 1293 if (!current_node) |
| 1106 return false; | 1294 return false; |
| 1107 } | 1295 } |
| 1108 *id = current_node->file_id(); | 1296 *id = current_node->file_id(); |
| 1109 return true; | 1297 return true; |
| 1110 } | 1298 } |
| 1111 | 1299 |
| 1300 void MTPDeviceDelegateImplLinux::EvictCachedPathToId(const uint32 id) { |
| 1301 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(id); |
| 1302 if (it != file_id_to_node_map_.end()) { |
| 1303 DCHECK(!it->second->HasChildren()); |
| 1304 MTPFileNode* parent = it->second->parent(); |
| 1305 if (parent) { |
| 1306 const bool ret = parent->DeleteChild(id); |
| 1307 DCHECK(ret); |
| 1308 } |
| 1309 } |
| 1310 } |
| 1311 |
| 1112 void CreateMTPDeviceAsyncDelegate( | 1312 void CreateMTPDeviceAsyncDelegate( |
| 1113 const std::string& device_location, | 1313 const std::string& device_location, |
| 1114 const bool read_only, | 1314 const bool read_only, |
| 1115 const CreateMTPDeviceAsyncDelegateCallback& callback) { | 1315 const CreateMTPDeviceAsyncDelegateCallback& callback) { |
| 1116 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1316 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1117 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); | 1317 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); |
| 1118 } | 1318 } |
| OLD | NEW |