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

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

Issue 947943002: Implement CopyFileFromLocal of MTPDeviceAsyncDelegate. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix wrong function definition. 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 <algorithm> 8 #include <algorithm>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/numerics/safe_conversions.h" 12 #include "base/numerics/safe_conversions.h"
13 #include "base/posix/eintr_wrapper.h"
12 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
15 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h" 17 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h"
16 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper_map_servic e.h" 18 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper_map_servic e.h"
17 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h" 19 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h"
18 #include "net/base/io_buffer.h" 20 #include "net/base/io_buffer.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h" 21 #include "third_party/cros_system_api/dbus/service_constants.h"
20 22
21 namespace { 23 namespace {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // Opens the storage device for communication. 65 // Opens the storage device for communication.
64 // 66 //
65 // Called on the UI thread to dispatch the request to the 67 // Called on the UI thread to dispatch the request to the
66 // MediaTransferProtocolManager. 68 // MediaTransferProtocolManager.
67 // 69 //
68 // |storage_name| specifies the name of the storage device. 70 // |storage_name| specifies the name of the storage device.
69 // |reply_callback| is called when the OpenStorage request completes. 71 // |reply_callback| is called when the OpenStorage request completes.
70 // |reply_callback| runs on the IO thread. 72 // |reply_callback| runs on the IO thread.
71 void OpenStorageOnUIThread( 73 void OpenStorageOnUIThread(
72 const std::string& storage_name, 74 const std::string& storage_name,
75 const bool read_only,
73 const MTPDeviceTaskHelper::OpenStorageCallback& reply_callback) { 76 const MTPDeviceTaskHelper::OpenStorageCallback& reply_callback) {
74 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 77 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
75 MTPDeviceTaskHelper* task_helper = 78 MTPDeviceTaskHelper* task_helper =
76 GetDeviceTaskHelperForStorage(storage_name); 79 GetDeviceTaskHelperForStorage(storage_name);
77 if (!task_helper) { 80 if (!task_helper) {
78 task_helper = 81 task_helper =
79 MTPDeviceTaskHelperMapService::GetInstance()->CreateDeviceTaskHelper( 82 MTPDeviceTaskHelperMapService::GetInstance()->CreateDeviceTaskHelper(
80 storage_name); 83 storage_name);
81 } 84 }
82 task_helper->OpenStorage(storage_name, reply_callback); 85 task_helper->OpenStorage(storage_name, read_only, reply_callback);
83 } 86 }
84 87
85 // Enumerates the |dir_id| directory file entries. 88 // Enumerates the |dir_id| directory file entries.
86 // 89 //
87 // Called on the UI thread to dispatch the request to the 90 // Called on the UI thread to dispatch the request to the
88 // MediaTransferProtocolManager. 91 // MediaTransferProtocolManager.
89 // 92 //
90 // |storage_name| specifies the name of the storage device. 93 // |storage_name| specifies the name of the storage device.
91 // |success_callback| is called when the ReadDirectory request succeeds. 94 // |success_callback| is called when the ReadDirectory request succeeds.
92 // |error_callback| is called when the ReadDirectory request fails. 95 // |error_callback| is called when the ReadDirectory request fails.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 const std::string& storage_name, 165 const std::string& storage_name,
163 const MTPDeviceAsyncDelegate::ReadBytesRequest& request) { 166 const MTPDeviceAsyncDelegate::ReadBytesRequest& request) {
164 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 167 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
165 MTPDeviceTaskHelper* task_helper = 168 MTPDeviceTaskHelper* task_helper =
166 GetDeviceTaskHelperForStorage(storage_name); 169 GetDeviceTaskHelperForStorage(storage_name);
167 if (!task_helper) 170 if (!task_helper)
168 return; 171 return;
169 task_helper->ReadBytes(request); 172 task_helper->ReadBytes(request);
170 } 173 }
171 174
175 void CopyFileFromLocalOnUIThread(
176 const std::string& storage_name,
177 const int source_file_descriptor,
178 const uint32 parent_id,
179 const std::string& file_name,
180 const MTPDeviceTaskHelper::CopyFileFromLocalSuccessCallback&
181 success_callback,
182 const MTPDeviceTaskHelper::ErrorCallback& error_callback) {
183 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
184 MTPDeviceTaskHelper* task_helper =
185 GetDeviceTaskHelperForStorage(storage_name);
186 if (!task_helper)
187 return;
188 task_helper->CopyFileFromLocal(storage_name, source_file_descriptor,
189 parent_id, file_name, success_callback,
190 error_callback);
191 }
192
172 // Closes the device storage specified by the |storage_name| and destroys the 193 // Closes the device storage specified by the |storage_name| and destroys the
173 // MTPDeviceTaskHelper object associated with the device storage. 194 // MTPDeviceTaskHelper object associated with the device storage.
174 // 195 //
175 // Called on the UI thread to dispatch the request to the 196 // Called on the UI thread to dispatch the request to the
176 // MediaTransferProtocolManager. 197 // MediaTransferProtocolManager.
177 void CloseStorageAndDestroyTaskHelperOnUIThread( 198 void CloseStorageAndDestroyTaskHelperOnUIThread(
178 const std::string& storage_name) { 199 const std::string& storage_name) {
179 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 200 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
180 MTPDeviceTaskHelper* task_helper = 201 MTPDeviceTaskHelper* task_helper =
181 GetDeviceTaskHelperForStorage(storage_name); 202 GetDeviceTaskHelperForStorage(storage_name);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 it != children_.end(); ++it) { 324 it != children_.end(); ++it) {
304 if (it->second->file_id() == file_id) { 325 if (it->second->file_id() == file_id) {
305 children_.erase(it); 326 children_.erase(it);
306 return true; 327 return true;
307 } 328 }
308 } 329 }
309 return false; 330 return false;
310 } 331 }
311 332
312 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( 333 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux(
313 const std::string& device_location) 334 const std::string& device_location,
335 const bool read_only)
314 : init_state_(UNINITIALIZED), 336 : init_state_(UNINITIALIZED),
315 task_in_progress_(false), 337 task_in_progress_(false),
316 device_path_(device_location), 338 device_path_(device_location),
339 read_only_(read_only),
317 root_node_(new MTPFileNode(mtpd::kRootFileId, 340 root_node_(new MTPFileNode(mtpd::kRootFileId,
318 "", // Root node has no name. 341 "", // Root node has no name.
319 NULL, // And no parent node. 342 NULL, // And no parent node.
320 &file_id_to_node_map_)), 343 &file_id_to_node_map_)),
321 weak_ptr_factory_(this) { 344 weak_ptr_factory_(this) {
322 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 345 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
323 DCHECK(!device_path_.empty()); 346 DCHECK(!device_path_.empty());
324 base::RemoveChars(device_location, kRootPath, &storage_name_); 347 base::RemoveChars(device_location, kRootPath, &storage_name_);
325 DCHECK(!storage_name_.empty()); 348 DCHECK(!storage_name_.empty());
326 } 349 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 offset, 448 offset,
426 buf_len, 449 buf_len,
427 success_callback, 450 success_callback,
428 error_callback); 451 error_callback);
429 EnsureInitAndRunTask(PendingTaskInfo(device_file_path, 452 EnsureInitAndRunTask(PendingTaskInfo(device_file_path,
430 content::BrowserThread::IO, 453 content::BrowserThread::IO,
431 FROM_HERE, 454 FROM_HERE,
432 closure)); 455 closure));
433 } 456 }
434 457
458 bool MTPDeviceDelegateImplLinux::IsReadOnly() {
459 return read_only_;
460 }
461
462 void MTPDeviceDelegateImplLinux::CopyFileFromLocal(
463 const base::FilePath& source_file_path,
464 const base::FilePath& device_file_path,
465 const CopyFileFromLocalSuccessCallback& success_callback,
466 const ErrorCallback& error_callback) {
467 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
468 DCHECK(!source_file_path.empty());
469 DCHECK(!device_file_path.empty());
470 base::Closure closure =
471 base::Bind(&MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal,
472 weak_ptr_factory_.GetWeakPtr(), source_file_path,
473 device_file_path, success_callback, error_callback);
474 EnsureInitAndRunTask(PendingTaskInfo(device_file_path.DirName(),
475 content::BrowserThread::IO, FROM_HERE,
476 closure));
477 }
478
435 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { 479 void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() {
436 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 480 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
437 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. 481 // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object.
438 content::BrowserThread::PostTask( 482 content::BrowserThread::PostTask(
439 content::BrowserThread::UI, 483 content::BrowserThread::UI,
440 FROM_HERE, 484 FROM_HERE,
441 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, storage_name_)); 485 base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, storage_name_));
442 delete this; 486 delete this;
443 } 487 }
444 488
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 file_id, buf, offset, buf_len, 606 file_id, buf, offset, buf_len,
563 base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadBytes, 607 base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadBytes,
564 weak_ptr_factory_.GetWeakPtr(), 608 weak_ptr_factory_.GetWeakPtr(),
565 success_callback), 609 success_callback),
566 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, 610 base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
567 weak_ptr_factory_.GetWeakPtr(), 611 weak_ptr_factory_.GetWeakPtr(),
568 error_callback, 612 error_callback,
569 file_id)); 613 file_id));
570 614
571 base::Closure closure = 615 base::Closure closure =
572 base::Bind(base::Bind(&ReadBytesOnUIThread, storage_name_, request)); 616 base::Bind(&ReadBytesOnUIThread, storage_name_, request);
573 EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), 617 EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(),
574 content::BrowserThread::UI, 618 content::BrowserThread::UI,
575 FROM_HERE, 619 FROM_HERE,
576 closure)); 620 closure));
577 } else { 621 } else {
578 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); 622 error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
579 } 623 }
580 PendingRequestDone(); 624 PendingRequestDone();
581 } 625 }
582 626
627 void MTPDeviceDelegateImplLinux::CopyFileFromLocalInternal(
628 const base::FilePath& source_file_path,
629 const base::FilePath& device_file_path,
630 const CopyFileFromLocalSuccessCallback& success_callback,
631 const ErrorCallback& error_callback) {
632 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
633
634 const int source_file_descriptor =
635 open(source_file_path.value().c_str(), O_RDONLY);
Lei Zhang 2015/03/02 23:41:39 Actually, we should open() and close() this on a F
yawano 2015/03/03 09:16:54 Done.
636
637 uint32 parent_id;
638 if (source_file_descriptor != -1 &&
639 CachedPathToId(device_file_path.DirName(), &parent_id)) {
640 CopyFileFromLocalSuccessCallback success_callback_wrapper =
641 base::Bind(&MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal,
642 weak_ptr_factory_.GetWeakPtr(), success_callback,
643 source_file_descriptor);
644
645 ErrorCallback error_callback_wrapper = base::Bind(
646 &MTPDeviceDelegateImplLinux::HandleCopyFileFromLocalError,
647 weak_ptr_factory_.GetWeakPtr(), error_callback, source_file_descriptor);
648
649 base::Closure closure = base::Bind(
650 &CopyFileFromLocalOnUIThread, storage_name_, source_file_descriptor,
651 parent_id, device_file_path.BaseName().value(),
652 success_callback_wrapper, error_callback_wrapper);
653 EnsureInitAndRunTask(PendingTaskInfo(
654 base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
655 } else {
656 error_callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
657 }
658
659 PendingRequestDone();
660 }
661
583 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( 662 void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask(
584 const PendingTaskInfo& task_info) { 663 const PendingTaskInfo& task_info) {
585 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 664 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
586 if ((init_state_ == INITIALIZED) && !task_in_progress_) { 665 if ((init_state_ == INITIALIZED) && !task_in_progress_) {
587 RunTask(task_info); 666 RunTask(task_info);
588 return; 667 return;
589 } 668 }
590 669
591 // Only *Internal functions have empty paths. Since they are the continuation 670 // Only *Internal functions have empty paths. Since they are the continuation
592 // of the current running task, they get to cut in line. 671 // of the current running task, they get to cut in line.
593 if (task_info.path.empty()) 672 if (task_info.path.empty())
594 pending_tasks_.push_front(task_info); 673 pending_tasks_.push_front(task_info);
595 else 674 else
596 pending_tasks_.push_back(task_info); 675 pending_tasks_.push_back(task_info);
597 676
598 if (init_state_ == UNINITIALIZED) { 677 if (init_state_ == UNINITIALIZED) {
599 init_state_ = PENDING_INIT; 678 init_state_ = PENDING_INIT;
600 task_in_progress_ = true; 679 task_in_progress_ = true;
601 content::BrowserThread::PostTask( 680 content::BrowserThread::PostTask(
602 content::BrowserThread::UI, 681 content::BrowserThread::UI, FROM_HERE,
603 FROM_HERE, 682 base::Bind(&OpenStorageOnUIThread, storage_name_, read_only_,
604 base::Bind(&OpenStorageOnUIThread,
605 storage_name_,
606 base::Bind(&MTPDeviceDelegateImplLinux::OnInitCompleted, 683 base::Bind(&MTPDeviceDelegateImplLinux::OnInitCompleted,
607 weak_ptr_factory_.GetWeakPtr()))); 684 weak_ptr_factory_.GetWeakPtr())));
608 } 685 }
609 } 686 }
610 687
611 void MTPDeviceDelegateImplLinux::RunTask(const PendingTaskInfo& task_info) { 688 void MTPDeviceDelegateImplLinux::RunTask(const PendingTaskInfo& task_info) {
612 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 689 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
613 DCHECK_EQ(INITIALIZED, init_state_); 690 DCHECK_EQ(INITIALIZED, init_state_);
614 DCHECK(!task_in_progress_); 691 DCHECK(!task_in_progress_);
615 task_in_progress_ = true; 692 task_in_progress_ = true;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 924
848 void MTPDeviceDelegateImplLinux::OnFillFileCacheFailed( 925 void MTPDeviceDelegateImplLinux::OnFillFileCacheFailed(
849 base::File::Error /* error */) { 926 base::File::Error /* error */) {
850 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 927 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
851 // When filling the cache fails for the task at the front of the queue, clear 928 // When filling the cache fails for the task at the front of the queue, clear
852 // the path of the task so it will not try to do any more caching. Instead, 929 // the path of the task so it will not try to do any more caching. Instead,
853 // the task will just run and fail the CachedPathToId() lookup. 930 // the task will just run and fail the CachedPathToId() lookup.
854 pending_tasks_.front().path.clear(); 931 pending_tasks_.front().path.clear();
855 } 932 }
856 933
934 void MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal(
935 const CopyFileFromLocalSuccessCallback& success_callback,
936 const uint32 source_file_descriptor) {
937 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
938
939 IGNORE_EINTR(close(source_file_descriptor));
940 success_callback.Run();
941 PendingRequestDone();
942 }
943
944 void MTPDeviceDelegateImplLinux::HandleCopyFileFromLocalError(
945 const ErrorCallback& error_callback,
946 const uint32 source_file_descriptor,
947 base::File::Error error) {
948 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
949
950 close(source_file_descriptor);
951 error_callback.Run(error);
952 PendingRequestDone();
953 }
954
857 void MTPDeviceDelegateImplLinux::HandleDeviceFileError( 955 void MTPDeviceDelegateImplLinux::HandleDeviceFileError(
858 const ErrorCallback& error_callback, 956 const ErrorCallback& error_callback,
859 uint32 file_id, 957 uint32 file_id,
860 base::File::Error error) { 958 base::File::Error error) {
861 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 959 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
862 960
863 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(file_id); 961 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(file_id);
864 if (it != file_id_to_node_map_.end()) { 962 if (it != file_id_to_node_map_.end()) {
865 MTPFileNode* parent = it->second->parent(); 963 MTPFileNode* parent = it->second->parent();
866 if (parent) { 964 if (parent) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 current_node = current_node->GetChild(device_relpath_components[i]); 1034 current_node = current_node->GetChild(device_relpath_components[i]);
937 if (!current_node) 1035 if (!current_node)
938 return false; 1036 return false;
939 } 1037 }
940 *id = current_node->file_id(); 1038 *id = current_node->file_id();
941 return true; 1039 return true;
942 } 1040 }
943 1041
944 void CreateMTPDeviceAsyncDelegate( 1042 void CreateMTPDeviceAsyncDelegate(
945 const std::string& device_location, 1043 const std::string& device_location,
1044 const bool read_only,
946 const CreateMTPDeviceAsyncDelegateCallback& callback) { 1045 const CreateMTPDeviceAsyncDelegateCallback& callback) {
947 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 1046 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
948 callback.Run(new MTPDeviceDelegateImplLinux(device_location)); 1047 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only));
949 } 1048 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698