Chromium Code Reviews| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, | 106 const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, |
| 107 const MTPDeviceTaskHelper::ErrorCallback& error_callback) { | 107 const MTPDeviceTaskHelper::ErrorCallback& error_callback) { |
| 108 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 108 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 109 MTPDeviceTaskHelper* task_helper = | 109 MTPDeviceTaskHelper* task_helper = |
| 110 GetDeviceTaskHelperForStorage(storage_name, read_only); | 110 GetDeviceTaskHelperForStorage(storage_name, read_only); |
| 111 if (!task_helper) | 111 if (!task_helper) |
| 112 return; | 112 return; |
| 113 task_helper->ReadDirectory(dir_id, success_callback, error_callback); | 113 task_helper->ReadDirectory(dir_id, success_callback, error_callback); |
| 114 } | 114 } |
| 115 | 115 |
| 116 // Gets entry ids on |directory_id|. | |
| 117 // | |
| 118 // Called on the UI thread to dispatch the request to the | |
| 119 // MediaTransferProtocolManager. | |
| 120 // | |
| 121 // |storage_name| specifies the name of the storage device. | |
| 122 // |read_only| specifies the mode of the storage device. | |
| 123 // |directory_id| is the directory to be read. | |
| 124 // |success_callback| is called when the ReadDirectoryEntryIds request succeeds. | |
| 125 // |error_callback| is called when the ReadDirectoryEntryIds request fails. | |
| 126 // |success_callback| and |error_callback| runs on the IO thread. | |
| 127 void ReadDirectoryEntryIdsOnUIThread( | |
| 128 const std::string& storage_name, | |
| 129 const bool read_only, | |
| 130 const uint32 directory_id, | |
| 131 const MTPDeviceTaskHelper::ReadDirectoryEntryIdsSuccessCallback& | |
| 132 success_callback, | |
| 133 const MTPDeviceTaskHelper::ErrorCallback& error_callback) { | |
| 134 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 135 MTPDeviceTaskHelper* task_helper = | |
| 136 GetDeviceTaskHelperForStorage(storage_name, read_only); | |
| 137 if (!task_helper) | |
| 138 return; | |
| 139 task_helper->ReadDirectoryEntryIds(directory_id, success_callback, | |
| 140 error_callback); | |
| 141 } | |
| 142 | |
| 116 // Gets the |file_path| details. | 143 // Gets the |file_path| details. |
| 117 // | 144 // |
| 118 // Called on the UI thread to dispatch the request to the | 145 // Called on the UI thread to dispatch the request to the |
| 119 // MediaTransferProtocolManager. | 146 // MediaTransferProtocolManager. |
| 120 // | 147 // |
| 121 // |storage_name| specifies the name of the storage device. | 148 // |storage_name| specifies the name of the storage device. |
| 122 // |read_only| specifies the mode of the storage device. | 149 // |read_only| specifies the mode of the storage device. |
| 123 // |success_callback| is called when the GetFileInfo request succeeds. | 150 // |success_callback| is called when the GetFileInfo request succeeds. |
| 124 // |error_callback| is called when the GetFileInfo request fails. | 151 // |error_callback| is called when the GetFileInfo request fails. |
| 125 // |success_callback| and |error_callback| runs on the IO thread. | 152 // |success_callback| and |error_callback| runs on the IO thread. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 234 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 208 MTPDeviceTaskHelper* task_helper = | 235 MTPDeviceTaskHelper* task_helper = |
| 209 GetDeviceTaskHelperForStorage(storage_name, read_only); | 236 GetDeviceTaskHelperForStorage(storage_name, read_only); |
| 210 if (!task_helper) | 237 if (!task_helper) |
| 211 return; | 238 return; |
| 212 task_helper->CopyFileFromLocal(storage_name, source_file_descriptor, | 239 task_helper->CopyFileFromLocal(storage_name, source_file_descriptor, |
| 213 parent_id, file_name, success_callback, | 240 parent_id, file_name, success_callback, |
| 214 error_callback); | 241 error_callback); |
| 215 } | 242 } |
| 216 | 243 |
| 244 // Deletes |object_id|. | |
| 245 // | |
| 246 // Called on the UI thread to dispatch the request to the | |
| 247 // MediaTransferProtocolManager. | |
| 248 // | |
| 249 // |storage_name| specifies the name of the storage device. | |
| 250 // |read_only| specifies the mode of the storage device. | |
| 251 // |object_id| is the object to be deleted. | |
| 252 // |success_callback| is called when the object is deleted successfully. | |
| 253 // |error_callback| is called when it fails to delete the object. | |
| 254 // |success_callback| and |error_callback| runs on the IO thread. | |
| 255 void DeleteObjectOnUIThread( | |
| 256 const std::string storage_name, | |
| 257 const bool read_only, | |
| 258 const uint32 object_id, | |
| 259 const MTPDeviceTaskHelper::DeleteObjectSuccessCallback success_callback, | |
| 260 const MTPDeviceTaskHelper::ErrorCallback error_callback) { | |
| 261 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 262 MTPDeviceTaskHelper* task_helper = | |
| 263 GetDeviceTaskHelperForStorage(storage_name, read_only); | |
| 264 if (!task_helper) | |
| 265 return; | |
| 266 task_helper->DeleteObject(object_id, success_callback, error_callback); | |
| 267 } | |
| 268 | |
| 217 // Closes the device storage specified by the |storage_name| and destroys the | 269 // Closes the device storage specified by the |storage_name| and destroys the |
| 218 // MTPDeviceTaskHelper object associated with the device storage. | 270 // MTPDeviceTaskHelper object associated with the device storage. |
| 219 // | 271 // |
| 220 // Called on the UI thread to dispatch the request to the | 272 // Called on the UI thread to dispatch the request to the |
| 221 // MediaTransferProtocolManager. | 273 // MediaTransferProtocolManager. |
| 222 void CloseStorageAndDestroyTaskHelperOnUIThread( | 274 void CloseStorageAndDestroyTaskHelperOnUIThread( |
| 223 const std::string& storage_name, | 275 const std::string& storage_name, |
| 224 const bool read_only) { | 276 const bool read_only) { |
| 225 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 277 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 226 MTPDeviceTaskHelper* task_helper = | 278 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; | 327 const MTPFileNode* GetChild(const std::string& name) const; |
| 276 | 328 |
| 277 void EnsureChildExists(const std::string& name, uint32 id); | 329 void EnsureChildExists(const std::string& name, uint32 id); |
| 278 | 330 |
| 279 // Clears all the children, except those in |children_to_keep|. | 331 // Clears all the children, except those in |children_to_keep|. |
| 280 void ClearNonexistentChildren( | 332 void ClearNonexistentChildren( |
| 281 const std::set<std::string>& children_to_keep); | 333 const std::set<std::string>& children_to_keep); |
| 282 | 334 |
| 283 bool DeleteChild(uint32 file_id); | 335 bool DeleteChild(uint32 file_id); |
| 284 | 336 |
| 337 bool HasChildren() const; | |
| 338 | |
| 285 uint32 file_id() const { return file_id_; } | 339 uint32 file_id() const { return file_id_; } |
| 286 const std::string& file_name() const { return file_name_; } | 340 const std::string& file_name() const { return file_name_; } |
| 287 MTPFileNode* parent() { return parent_; } | 341 MTPFileNode* parent() { return parent_; } |
| 288 | 342 |
| 289 private: | 343 private: |
| 290 // Container for holding a node's children. | 344 // Container for holding a node's children. |
| 291 typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes; | 345 typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes; |
| 292 | 346 |
| 293 const uint32 file_id_; | 347 const uint32 file_id_; |
| 294 const std::string file_name_; | 348 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) { | 409 it != children_to_erase.end(); ++it) { |
| 356 children_.take_and_erase(*it); | 410 children_.take_and_erase(*it); |
| 357 } | 411 } |
| 358 } | 412 } |
| 359 | 413 |
| 360 bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32 file_id) { | 414 bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32 file_id) { |
| 361 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 415 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 362 for (ChildNodes::iterator it = children_.begin(); | 416 for (ChildNodes::iterator it = children_.begin(); |
| 363 it != children_.end(); ++it) { | 417 it != children_.end(); ++it) { |
| 364 if (it->second->file_id() == file_id) { | 418 if (it->second->file_id() == file_id) { |
| 419 DCHECK(!it->second->HasChildren()); | |
| 365 children_.erase(it); | 420 children_.erase(it); |
| 366 return true; | 421 return true; |
| 367 } | 422 } |
| 368 } | 423 } |
| 369 return false; | 424 return false; |
| 370 } | 425 } |
| 371 | 426 |
| 427 bool MTPDeviceDelegateImplLinux::MTPFileNode::HasChildren() const { | |
| 428 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 429 return children_.size() > 0; | |
| 430 } | |
| 431 | |
| 372 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( | 432 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( |
| 373 const std::string& device_location, | 433 const std::string& device_location, |
| 374 const bool read_only) | 434 const bool read_only) |
| 375 : init_state_(UNINITIALIZED), | 435 : init_state_(UNINITIALIZED), |
| 376 task_in_progress_(false), | 436 task_in_progress_(false), |
| 377 device_path_(device_location), | 437 device_path_(device_location), |
| 378 read_only_(read_only), | 438 read_only_(read_only), |
| 379 root_node_(new MTPFileNode(mtpd::kRootFileId, | 439 root_node_(new MTPFileNode(mtpd::kRootFileId, |
| 380 "", // Root node has no name. | 440 "", // Root node has no name. |
| 381 NULL, // And no parent node. | 441 NULL, // And no parent node. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 offset, | 547 offset, |
| 488 buf_len, | 548 buf_len, |
| 489 success_callback, | 549 success_callback, |
| 490 error_callback); | 550 error_callback); |
| 491 EnsureInitAndRunTask(PendingTaskInfo(device_file_path, | 551 EnsureInitAndRunTask(PendingTaskInfo(device_file_path, |
| 492 content::BrowserThread::IO, | 552 content::BrowserThread::IO, |
| 493 FROM_HERE, | 553 FROM_HERE, |
| 494 closure)); | 554 closure)); |
| 495 } | 555 } |
| 496 | 556 |
| 497 bool MTPDeviceDelegateImplLinux::IsReadOnly() { | 557 bool MTPDeviceDelegateImplLinux::IsReadOnly() const { |
| 498 return read_only_; | 558 return read_only_; |
| 499 } | 559 } |
| 500 | 560 |
| 501 void MTPDeviceDelegateImplLinux::CopyFileFromLocal( | 561 void MTPDeviceDelegateImplLinux::CopyFileFromLocal( |
| 502 const base::FilePath& source_file_path, | 562 const base::FilePath& source_file_path, |
| 503 const base::FilePath& device_file_path, | 563 const base::FilePath& device_file_path, |
| 504 const CopyFileFromLocalSuccessCallback& success_callback, | 564 const CopyFileFromLocalSuccessCallback& success_callback, |
| 505 const ErrorCallback& error_callback) { | 565 const ErrorCallback& error_callback) { |
| 506 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 566 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 507 DCHECK(!source_file_path.empty()); | 567 DCHECK(!source_file_path.empty()); |
| 508 DCHECK(!device_file_path.empty()); | 568 DCHECK(!device_file_path.empty()); |
| 509 | 569 |
| 510 content::BrowserThread::PostTaskAndReplyWithResult( | 570 content::BrowserThread::PostTaskAndReplyWithResult( |
| 511 content::BrowserThread::FILE, | 571 content::BrowserThread::FILE, |
| 512 FROM_HERE, | 572 FROM_HERE, |
| 513 base::Bind(&OpenFileDescriptor, | 573 base::Bind(&OpenFileDescriptor, |
| 514 source_file_path.value().c_str(), | 574 source_file_path.value().c_str(), |
| 515 O_RDONLY), | 575 O_RDONLY), |
| 516 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal, | 576 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal, |
| 517 weak_ptr_factory_.GetWeakPtr(), | 577 weak_ptr_factory_.GetWeakPtr(), |
| 518 device_file_path, | 578 device_file_path, |
| 519 success_callback, | 579 success_callback, |
| 520 error_callback)); | 580 error_callback)); |
| 521 } | 581 } |
| 522 | 582 |
| 583 void MTPDeviceDelegateImplLinux::DeleteFile( | |
| 584 const base::FilePath& file_path, | |
| 585 const DeleteFileSuccessCallback& success_callback, | |
| 586 const ErrorCallback& error_callback) { | |
| 587 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 588 DCHECK(!file_path.empty()); | |
| 589 | |
| 590 const GetFileInfoSuccessCallback& success_callback_wrapper = | |
| 591 base::Bind(&MTPDeviceDelegateImplLinux::DeleteFileInternal, | |
| 592 weak_ptr_factory_.GetWeakPtr(), file_path, success_callback, | |
| 593 error_callback); | |
| 594 | |
| 595 const base::Closure closure = | |
| 596 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, | |
| 597 weak_ptr_factory_.GetWeakPtr(), file_path, | |
| 598 success_callback_wrapper, error_callback); | |
| 599 EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO, | |
| 600 FROM_HERE, closure)); | |
| 601 } | |
| 602 | |
| 603 void MTPDeviceDelegateImplLinux::DeleteDirectory( | |
| 604 const base::FilePath& file_path, | |
| 605 const DeleteDirectorySuccessCallback& success_callback, | |
| 606 const ErrorCallback& error_callback) { | |
| 607 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 608 DCHECK(!file_path.empty()); | |
| 609 | |
| 610 const GetFileInfoSuccessCallback& success_callback_wrapper = | |
| 611 base::Bind(&MTPDeviceDelegateImplLinux::DeleteDirectoryInternal, | |
| 612 weak_ptr_factory_.GetWeakPtr(), file_path, success_callback, | |
| 613 error_callback); | |
| 614 | |
| 615 const base::Closure closure = | |
| 616 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, | |
| 617 weak_ptr_factory_.GetWeakPtr(), file_path, | |
| 618 success_callback_wrapper, error_callback); | |
| 619 EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO, | |
| 620 FROM_HERE, closure)); | |
| 621 } | |
| 622 | |
| 523 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { | 623 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { |
| 524 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 624 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 525 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. | 625 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. |
| 526 content::BrowserThread::PostTask( | 626 content::BrowserThread::PostTask( |
| 527 content::BrowserThread::UI, | 627 content::BrowserThread::UI, |
| 528 FROM_HERE, | 628 FROM_HERE, |
| 529 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, | 629 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, |
| 530 storage_name_, | 630 storage_name_, |
| 531 read_only_)); | 631 read_only_)); |
| 532 delete this; | 632 delete this; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 EnsureInitAndRunTask(PendingTaskInfo( | 809 EnsureInitAndRunTask(PendingTaskInfo( |
| 710 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); | 810 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); |
| 711 } else { | 811 } else { |
| 712 HandleCopyFileFromLocalError(error_callback, source_file_descriptor, | 812 HandleCopyFileFromLocalError(error_callback, source_file_descriptor, |
| 713 base::File::FILE_ERROR_INVALID_OPERATION); | 813 base::File::FILE_ERROR_INVALID_OPERATION); |
| 714 } | 814 } |
| 715 | 815 |
| 716 PendingRequestDone(); | 816 PendingRequestDone(); |
| 717 } | 817 } |
| 718 | 818 |
| 819 void MTPDeviceDelegateImplLinux::DeleteFileInternal( | |
| 820 const base::FilePath& file_path, | |
| 821 const DeleteFileSuccessCallback& success_callback, | |
| 822 const ErrorCallback& error_callback, | |
| 823 const base::File::Info& file_info) { | |
| 824 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 825 | |
| 826 if (file_info.is_directory) { | |
| 827 error_callback.Run(base::File::FILE_ERROR_NOT_A_FILE); | |
| 828 } else { | |
| 829 uint32 file_id; | |
| 830 if (CachedPathToId(file_path, &file_id)) | |
| 831 RunDeleteObjectOnUIThread(file_id, success_callback, error_callback); | |
| 832 else | |
| 833 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); | |
| 834 } | |
| 835 | |
| 836 PendingRequestDone(); | |
| 837 } | |
| 838 | |
| 839 void MTPDeviceDelegateImplLinux::DeleteDirectoryInternal( | |
| 840 const base::FilePath& file_path, | |
| 841 const DeleteDirectorySuccessCallback& success_callback, | |
| 842 const ErrorCallback& error_callback, | |
| 843 const base::File::Info& file_info) { | |
| 844 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 845 | |
| 846 if (!file_info.is_directory) { | |
| 847 error_callback.Run(base::File::FILE_ERROR_NOT_A_DIRECTORY); | |
| 848 PendingRequestDone(); | |
| 849 return; | |
| 850 } | |
| 851 | |
| 852 uint32 directory_id; | |
| 853 if (!CachedPathToId(file_path, &directory_id)) { | |
| 854 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); | |
| 855 PendingRequestDone(); | |
| 856 return; | |
| 857 } | |
| 858 | |
| 859 // Checks the cache first. If it has children in cache, the directory cannot | |
| 860 // be empty. | |
| 861 FileIdToMTPFileNodeMap::const_iterator it = | |
| 862 file_id_to_node_map_.find(directory_id); | |
| 863 if (it != file_id_to_node_map_.end() && it->second->HasChildren()) { | |
| 864 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY); | |
| 865 PendingRequestDone(); | |
| 866 return; | |
| 867 } | |
| 868 | |
| 869 // Since the directory can contain a file even if the cache returns it as | |
| 870 // empty, read the directory and confirm the directory is actually empty. | |
| 871 const MTPDeviceTaskHelper::ReadDirectoryEntryIdsSuccessCallback | |
| 872 success_callback_wrapper = | |
| 873 base::Bind(&MTPDeviceDelegateImplLinux:: | |
| 874 OnDidReadDirectoryEntryIdsToDeleteDirectory, | |
| 875 weak_ptr_factory_.GetWeakPtr(), directory_id, | |
| 876 success_callback, error_callback); | |
| 877 const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = | |
| 878 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, | |
| 879 weak_ptr_factory_.GetWeakPtr(), error_callback, directory_id); | |
| 880 const base::Closure closure = base::Bind( | |
| 881 &ReadDirectoryEntryIdsOnUIThread, storage_name_, read_only_, directory_id, | |
| 882 success_callback_wrapper, error_callback_wrapper); | |
| 883 EnsureInitAndRunTask(PendingTaskInfo( | |
|
Lei Zhang
2015/03/10 00:48:06
This can also just be PostTask().
yawano
2015/03/10 05:01:28
If we use PostTask instead of PendingTaskInfo with
Lei Zhang
2015/03/10 08:12:04
If you were to use PostTask(), then you would not
yawano
2015/03/10 08:20:36
Acknowledged.
| |
| 884 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); | |
| 885 PendingRequestDone(); | |
| 886 } | |
| 887 | |
| 888 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryEntryIdsToDeleteDirectory( | |
| 889 const uint32 directory_id, | |
| 890 const DeleteDirectorySuccessCallback& success_callback, | |
| 891 const ErrorCallback& error_callback, | |
| 892 const std::vector<uint32>& file_ids) { | |
| 893 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 894 | |
| 895 if (file_ids.size() > 0) | |
| 896 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY); | |
| 897 else | |
| 898 RunDeleteObjectOnUIThread(directory_id, success_callback, error_callback); | |
| 899 | |
| 900 PendingRequestDone(); | |
| 901 } | |
| 902 | |
| 903 void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread( | |
| 904 const uint32 object_id, | |
| 905 const DeleteObjectSuccessCallback& success_callback, | |
| 906 const ErrorCallback& error_callback) { | |
| 907 const MTPDeviceTaskHelper::DeleteObjectSuccessCallback | |
| 908 success_callback_wrapper = base::Bind( | |
| 909 &MTPDeviceDelegateImplLinux::OnDidDeleteObject, | |
| 910 weak_ptr_factory_.GetWeakPtr(), object_id, success_callback); | |
| 911 | |
| 912 const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper = | |
| 913 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError, | |
| 914 weak_ptr_factory_.GetWeakPtr(), error_callback); | |
| 915 | |
| 916 const base::Closure closure = | |
| 917 base::Bind(&DeleteObjectOnUIThread, storage_name_, read_only_, object_id, | |
| 918 success_callback_wrapper, error_callback_wrapper); | |
| 919 | |
| 920 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | |
| 921 closure); | |
| 922 } | |
| 923 | |
| 719 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( | 924 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( |
| 720 const PendingTaskInfo& task_info) { | 925 const PendingTaskInfo& task_info) { |
| 721 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 926 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 722 if ((init_state_ == INITIALIZED) && !task_in_progress_) { | 927 if ((init_state_ == INITIALIZED) && !task_in_progress_) { |
| 723 RunTask(task_info); | 928 RunTask(task_info); |
| 724 return; | 929 return; |
| 725 } | 930 } |
| 726 | 931 |
| 727 // Only *Internal functions have empty paths. Since they are the continuation | 932 // Only *Internal functions have empty paths. Since they are the continuation |
| 728 // of the current running task, they get to cut in line. | 933 // of the current running task, they get to cut in line. |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 const base::Closure closure = base::Bind(&CloseFileDescriptor, | 1220 const base::Closure closure = base::Bind(&CloseFileDescriptor, |
| 1016 source_file_descriptor); | 1221 source_file_descriptor); |
| 1017 | 1222 |
| 1018 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, | 1223 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, |
| 1019 closure); | 1224 closure); |
| 1020 | 1225 |
| 1021 error_callback.Run(error); | 1226 error_callback.Run(error); |
| 1022 PendingRequestDone(); | 1227 PendingRequestDone(); |
| 1023 } | 1228 } |
| 1024 | 1229 |
| 1230 void MTPDeviceDelegateImplLinux::OnDidDeleteObject( | |
| 1231 const uint32 object_id, | |
| 1232 const DeleteObjectSuccessCallback success_callback) { | |
| 1233 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 1234 | |
| 1235 EvictCachedPathToId(object_id); | |
| 1236 success_callback.Run(); | |
| 1237 PendingRequestDone(); | |
| 1238 } | |
| 1239 | |
| 1240 void MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError( | |
| 1241 const ErrorCallback& error_callback, | |
| 1242 base::File::Error error) { | |
| 1243 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 1244 | |
| 1245 error_callback.Run(error); | |
| 1246 PendingRequestDone(); | |
| 1247 } | |
| 1248 | |
| 1025 void MTPDeviceDelegateImplLinux::HandleDeviceFileError( | 1249 void MTPDeviceDelegateImplLinux::HandleDeviceFileError( |
| 1026 const ErrorCallback& error_callback, | 1250 const ErrorCallback& error_callback, |
| 1027 uint32 file_id, | 1251 uint32 file_id, |
| 1028 base::File::Error error) { | 1252 base::File::Error error) { |
| 1029 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1253 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1030 | 1254 |
| 1031 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(file_id); | 1255 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); | 1256 error_callback.Run(error); |
| 1040 PendingRequestDone(); | 1257 PendingRequestDone(); |
| 1041 } | 1258 } |
| 1042 | 1259 |
| 1043 base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent( | 1260 base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent( |
| 1044 const base::FilePath& path, | 1261 const base::FilePath& path, |
| 1045 const base::FilePath& cached_path) const { | 1262 const base::FilePath& cached_path) const { |
| 1046 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1263 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1047 DCHECK(cached_path.empty() || cached_path.IsParent(path)); | 1264 DCHECK(cached_path.empty() || cached_path.IsParent(path)); |
| 1048 | 1265 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1102 const MTPFileNode* current_node = root_node_.get(); | 1319 const MTPFileNode* current_node = root_node_.get(); |
| 1103 for (size_t i = 0; i < device_relpath_components.size(); ++i) { | 1320 for (size_t i = 0; i < device_relpath_components.size(); ++i) { |
| 1104 current_node = current_node->GetChild(device_relpath_components[i]); | 1321 current_node = current_node->GetChild(device_relpath_components[i]); |
| 1105 if (!current_node) | 1322 if (!current_node) |
| 1106 return false; | 1323 return false; |
| 1107 } | 1324 } |
| 1108 *id = current_node->file_id(); | 1325 *id = current_node->file_id(); |
| 1109 return true; | 1326 return true; |
| 1110 } | 1327 } |
| 1111 | 1328 |
| 1329 void MTPDeviceDelegateImplLinux::EvictCachedPathToId(const uint32 id) { | |
| 1330 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(id); | |
| 1331 if (it != file_id_to_node_map_.end()) { | |
| 1332 DCHECK(!it->second->HasChildren()); | |
| 1333 MTPFileNode* parent = it->second->parent(); | |
| 1334 if (parent) { | |
| 1335 const bool ret = parent->DeleteChild(id); | |
| 1336 DCHECK(ret); | |
| 1337 } | |
| 1338 } | |
| 1339 } | |
| 1340 | |
| 1112 void CreateMTPDeviceAsyncDelegate( | 1341 void CreateMTPDeviceAsyncDelegate( |
| 1113 const std::string& device_location, | 1342 const std::string& device_location, |
| 1114 const bool read_only, | 1343 const bool read_only, |
| 1115 const CreateMTPDeviceAsyncDelegateCallback& callback) { | 1344 const CreateMTPDeviceAsyncDelegateCallback& callback) { |
| 1116 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1345 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 1117 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); | 1346 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); |
| 1118 } | 1347 } |
| OLD | NEW |