Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc

Issue 982283002: Implement DeleteFile and DeleteDirectory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix unit_tests. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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(
Lei Zhang 2015/03/07 01:17:24 What if we: - got rid of this - make ReadDirectory
yawano 2015/03/09 03:46:48 Can I confirm that chunk_size is maximum_length? I
Lei Zhang 2015/03/10 00:48:06 Actually, my idea only works if we modify MediaTra
yawano 2015/03/10 01:17:04 Yes, I agree with implementing max_size. Adding a
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
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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 offset, 539 offset,
488 buf_len, 540 buf_len,
489 success_callback, 541 success_callback,
490 error_callback); 542 error_callback);
491 EnsureInitAndRunTask(PendingTaskInfo(device_file_path, 543 EnsureInitAndRunTask(PendingTaskInfo(device_file_path,
492 content::BrowserThread::IO, 544 content::BrowserThread::IO,
493 FROM_HERE, 545 FROM_HERE,
494 closure)); 546 closure));
495 } 547 }
496 548
497 bool MTPDeviceDelegateImplLinux::IsReadOnly() { 549 bool MTPDeviceDelegateImplLinux::IsReadOnly() const {
498 return read_only_; 550 return read_only_;
499 } 551 }
500 552
501 void MTPDeviceDelegateImplLinux::CopyFileFromLocal( 553 void MTPDeviceDelegateImplLinux::CopyFileFromLocal(
502 const base::FilePath& source_file_path, 554 const base::FilePath& source_file_path,
503 const base::FilePath& device_file_path, 555 const base::FilePath& device_file_path,
504 const CopyFileFromLocalSuccessCallback& success_callback, 556 const CopyFileFromLocalSuccessCallback& success_callback,
505 const ErrorCallback& error_callback) { 557 const ErrorCallback& error_callback) {
506 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 558 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
507 DCHECK(!source_file_path.empty()); 559 DCHECK(!source_file_path.empty());
508 DCHECK(!device_file_path.empty()); 560 DCHECK(!device_file_path.empty());
509 561
510 content::BrowserThread::PostTaskAndReplyWithResult( 562 content::BrowserThread::PostTaskAndReplyWithResult(
511 content::BrowserThread::FILE, 563 content::BrowserThread::FILE,
512 FROM_HERE, 564 FROM_HERE,
513 base::Bind(&OpenFileDescriptor, 565 base::Bind(&OpenFileDescriptor,
514 source_file_path.value().c_str(), 566 source_file_path.value().c_str(),
515 O_RDONLY), 567 O_RDONLY),
516 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal, 568 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal,
517 weak_ptr_factory_.GetWeakPtr(), 569 weak_ptr_factory_.GetWeakPtr(),
518 device_file_path, 570 device_file_path,
519 success_callback, 571 success_callback,
520 error_callback)); 572 error_callback));
521 } 573 }
522 574
575 void MTPDeviceDelegateImplLinux::DeleteFile(
576 const base::FilePath& file_path,
577 const DeleteFileSuccessCallback& success_callback,
578 const ErrorCallback& error_callback) {
579 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
580 DCHECK(!file_path.empty());
581
582 const GetFileInfoSuccessCallback& success_callback_wrapper =
583 base::Bind(&MTPDeviceDelegateImplLinux::DeleteFileInternal,
584 weak_ptr_factory_.GetWeakPtr(), file_path, success_callback,
585 error_callback);
586
587 const base::Closure closure =
588 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
589 weak_ptr_factory_.GetWeakPtr(), file_path,
590 success_callback_wrapper, error_callback);
591 EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO,
592 FROM_HERE, closure));
593 }
594
595 void MTPDeviceDelegateImplLinux::DeleteDirectory(
596 const base::FilePath& file_path,
597 const DeleteDirectorySuccessCallback& success_callback,
598 const ErrorCallback& error_callback) {
599 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
600 DCHECK(!file_path.empty());
601
602 const GetFileInfoSuccessCallback& success_callback_wrapper =
603 base::Bind(&MTPDeviceDelegateImplLinux::DeleteDirectoryInternal,
604 weak_ptr_factory_.GetWeakPtr(), file_path, success_callback,
605 error_callback);
606
607 const base::Closure closure =
608 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
609 weak_ptr_factory_.GetWeakPtr(), file_path,
610 success_callback_wrapper, error_callback);
611 EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO,
612 FROM_HERE, closure));
613 }
614
523 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { 615 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() {
524 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 616 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
525 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. 617 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object.
526 content::BrowserThread::PostTask( 618 content::BrowserThread::PostTask(
527 content::BrowserThread::UI, 619 content::BrowserThread::UI,
528 FROM_HERE, 620 FROM_HERE,
529 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, 621 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread,
530 storage_name_, 622 storage_name_,
531 read_only_)); 623 read_only_));
532 delete this; 624 delete this;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 EnsureInitAndRunTask(PendingTaskInfo( 801 EnsureInitAndRunTask(PendingTaskInfo(
710 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure)); 802 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
711 } else { 803 } else {
712 HandleCopyFileFromLocalError(error_callback, source_file_descriptor, 804 HandleCopyFileFromLocalError(error_callback, source_file_descriptor,
713 base::File::FILE_ERROR_INVALID_OPERATION); 805 base::File::FILE_ERROR_INVALID_OPERATION);
714 } 806 }
715 807
716 PendingRequestDone(); 808 PendingRequestDone();
717 } 809 }
718 810
811 void MTPDeviceDelegateImplLinux::DeleteFileInternal(
812 const base::FilePath& file_path,
813 const DeleteFileSuccessCallback& success_callback,
814 const ErrorCallback& error_callback,
815 const base::File::Info& file_info) {
816 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
817
818 if (file_info.is_directory)
819 error_callback.Run(base::File::FILE_ERROR_NOT_A_FILE);
820 else
821 RunDeleteObjectOnUIThread(file_path, success_callback, error_callback);
822
823 PendingRequestDone();
824 }
825
826 void MTPDeviceDelegateImplLinux::DeleteDirectoryInternal(
827 const base::FilePath& file_path,
828 const DeleteDirectorySuccessCallback& success_callback,
829 const ErrorCallback& error_callback,
830 const base::File::Info& file_info) {
831 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
832
833 if (!file_info.is_directory) {
834 error_callback.Run(base::File::FILE_ERROR_NOT_A_DIRECTORY);
835 } else {
836 // Read directory entry ids to check the directory is empty.
837 uint32 directory_id;
838 if (CachedPathToId(file_path, &directory_id)) {
839 const MTPDeviceTaskHelper::ReadDirectoryEntryIdsSuccessCallback
Lei Zhang 2015/03/07 01:17:24 Before we issue the ReadDirectory call, can we che
yawano 2015/03/09 04:37:49 Done.
840 success_callback_wrapper =
841 base::Bind(&MTPDeviceDelegateImplLinux::
842 OnDidReadDirectoryEntryIdsToDeleteDirectory,
843 weak_ptr_factory_.GetWeakPtr(), directory_id,
844 success_callback, error_callback);
845 const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper =
846 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
847 weak_ptr_factory_.GetWeakPtr(), error_callback,
848 directory_id);
849 const base::Closure closure = base::Bind(
850 &ReadDirectoryEntryIdsOnUIThread, storage_name_, read_only_,
851 directory_id, success_callback_wrapper, error_callback_wrapper);
852 EnsureInitAndRunTask(PendingTaskInfo(
853 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
854 } else {
855 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
856 }
857 }
858
859 PendingRequestDone();
860 }
861
862 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryEntryIdsToDeleteDirectory(
863 const uint32 directory_id,
864 const DeleteDirectorySuccessCallback& success_callback,
865 const ErrorCallback& error_callback,
866 const std::vector<uint32>& file_ids) {
867 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
868
869 if (file_ids.size() > 0)
870 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY);
871 else
872 RunDeleteObjectOnUIThread(directory_id, success_callback, error_callback);
873
874 PendingRequestDone();
875 }
876
877 void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread(
Lei Zhang 2015/03/07 01:17:24 There's only one caller for this. I would just put
yawano 2015/03/09 04:37:49 Done.
878 const base::FilePath& file_path,
879 const DeleteObjectSuccessCallback& success_callback,
880 const ErrorCallback& error_callback) {
881 uint32 object_id;
882 if (CachedPathToId(file_path, &object_id))
883 RunDeleteObjectOnUIThread(object_id, success_callback, error_callback);
884 else
885 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
886 }
887
888 void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread(
889 const uint32 object_id,
890 const DeleteObjectSuccessCallback& success_callback,
891 const ErrorCallback& error_callback) {
892 const MTPDeviceTaskHelper::DeleteObjectSuccessCallback
893 success_callback_wrapper = base::Bind(
894 &MTPDeviceDelegateImplLinux::OnDidDeleteObject,
895 weak_ptr_factory_.GetWeakPtr(), object_id, success_callback);
896
897 const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper =
898 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError,
899 weak_ptr_factory_.GetWeakPtr(), error_callback);
900
901 const base::Closure closure =
902 base::Bind(&DeleteObjectOnUIThread, storage_name_, read_only_, object_id,
903 success_callback_wrapper, error_callback_wrapper);
904
905 EnsureInitAndRunTask(PendingTaskInfo(
Lei Zhang 2015/03/07 01:17:24 You can just call content::BrowserThread::PostTask
yawano 2015/03/09 04:37:48 Done.
906 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
907 }
908
719 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( 909 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask(
720 const PendingTaskInfo& task_info) { 910 const PendingTaskInfo& task_info) {
721 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 911 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
722 if ((init_state_ == INITIALIZED) && !task_in_progress_) { 912 if ((init_state_ == INITIALIZED) && !task_in_progress_) {
723 RunTask(task_info); 913 RunTask(task_info);
724 return; 914 return;
725 } 915 }
726 916
727 // Only *Internal functions have empty paths. Since they are the continuation 917 // Only *Internal functions have empty paths. Since they are the continuation
728 // of the current running task, they get to cut in line. 918 // of the current running task, they get to cut in line.
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 const base::Closure closure = base::Bind(&CloseFileDescriptor, 1205 const base::Closure closure = base::Bind(&CloseFileDescriptor,
1016 source_file_descriptor); 1206 source_file_descriptor);
1017 1207
1018 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 1208 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
1019 closure); 1209 closure);
1020 1210
1021 error_callback.Run(error); 1211 error_callback.Run(error);
1022 PendingRequestDone(); 1212 PendingRequestDone();
1023 } 1213 }
1024 1214
1215 void MTPDeviceDelegateImplLinux::OnDidDeleteObject(
1216 const uint32 object_id,
1217 const DeleteObjectSuccessCallback success_callback) {
1218 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
1219
1220 EvictCachedPathToId(object_id);
1221 success_callback.Run();
1222 PendingRequestDone();
1223 }
1224
1225 void MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError(
1226 const ErrorCallback& error_callback,
1227 base::File::Error error) {
1228 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
1229
1230 error_callback.Run(error);
1231 PendingRequestDone();
1232 }
1233
1025 void MTPDeviceDelegateImplLinux::HandleDeviceFileError( 1234 void MTPDeviceDelegateImplLinux::HandleDeviceFileError(
1026 const ErrorCallback& error_callback, 1235 const ErrorCallback& error_callback,
1027 uint32 file_id, 1236 uint32 file_id,
1028 base::File::Error error) { 1237 base::File::Error error) {
1029 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 1238 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
1030 1239
1031 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(file_id); 1240 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); 1241 error_callback.Run(error);
1040 PendingRequestDone(); 1242 PendingRequestDone();
1041 } 1243 }
1042 1244
1043 base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent( 1245 base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent(
1044 const base::FilePath& path, 1246 const base::FilePath& path,
1045 const base::FilePath& cached_path) const { 1247 const base::FilePath& cached_path) const {
1046 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 1248 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
1047 DCHECK(cached_path.empty() || cached_path.IsParent(path)); 1249 DCHECK(cached_path.empty() || cached_path.IsParent(path));
1048 1250
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 const MTPFileNode* current_node = root_node_.get(); 1304 const MTPFileNode* current_node = root_node_.get();
1103 for (size_t i = 0; i < device_relpath_components.size(); ++i) { 1305 for (size_t i = 0; i < device_relpath_components.size(); ++i) {
1104 current_node = current_node->GetChild(device_relpath_components[i]); 1306 current_node = current_node->GetChild(device_relpath_components[i]);
1105 if (!current_node) 1307 if (!current_node)
1106 return false; 1308 return false;
1107 } 1309 }
1108 *id = current_node->file_id(); 1310 *id = current_node->file_id();
1109 return true; 1311 return true;
1110 } 1312 }
1111 1313
1314 void MTPDeviceDelegateImplLinux::EvictCachedPathToId(const uint32 id) {
1315 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(id);
1316 if (it != file_id_to_node_map_.end()) {
1317 MTPFileNode* parent = it->second->parent();
Lei Zhang 2015/03/07 01:17:24 Assuming we add MTPNode::HasChildren(), I would DC
yawano 2015/03/09 04:37:48 Done. Added also for DeleteChild.
1318 if (parent) {
1319 const bool ret = parent->DeleteChild(id);
1320 DCHECK(ret);
1321 }
1322 }
1323 }
1324
1112 void CreateMTPDeviceAsyncDelegate( 1325 void CreateMTPDeviceAsyncDelegate(
1113 const std::string& device_location, 1326 const std::string& device_location,
1114 const bool read_only, 1327 const bool read_only,
1115 const CreateMTPDeviceAsyncDelegateCallback& callback) { 1328 const CreateMTPDeviceAsyncDelegateCallback& callback) {
1116 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 1329 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
1117 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); 1330 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only));
1118 } 1331 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698