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 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
13 #include "base/numerics/safe_conversions.h" | 13 #include "base/numerics/safe_conversions.h" |
14 #include "base/posix/eintr_wrapper.h" | 14 #include "base/posix/eintr_wrapper.h" |
15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
16 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h" | |
19 #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" |
20 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h" | 19 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h" |
21 #include "net/base/io_buffer.h" | 20 #include "net/base/io_buffer.h" |
22 #include "third_party/cros_system_api/dbus/service_constants.h" | 21 #include "third_party/cros_system_api/dbus/service_constants.h" |
23 | 22 |
24 namespace { | 23 namespace { |
25 | 24 |
26 // File path separator constant. | 25 // File path separator constant. |
27 const char kRootPath[] = "/"; | 26 const char kRootPath[] = "/"; |
28 | 27 |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 const ErrorCallback& error_callback) { | 545 const ErrorCallback& error_callback) { |
547 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 546 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
548 DCHECK(!file_path.empty()); | 547 DCHECK(!file_path.empty()); |
549 | 548 |
550 // If a ReadDirectory operation is in progress, the file info may already be | 549 // If a ReadDirectory operation is in progress, the file info may already be |
551 // cached. | 550 // cached. |
552 FileInfoCache::const_iterator it = file_info_cache_.find(file_path); | 551 FileInfoCache::const_iterator it = file_info_cache_.find(file_path); |
553 if (it != file_info_cache_.end()) { | 552 if (it != file_info_cache_.end()) { |
554 // TODO(thestig): This code is repeated in several places. Combine them. | 553 // TODO(thestig): This code is repeated in several places. Combine them. |
555 // e.g. c/b/media_galleries/win/mtp_device_operations_util.cc | 554 // e.g. c/b/media_galleries/win/mtp_device_operations_util.cc |
556 const storage::DirectoryEntry& cached_file_entry = it->second; | 555 const MTPDeviceTaskHelper::MTPEntry& cached_file_entry = it->second; |
557 base::File::Info info; | 556 success_callback.Run(cached_file_entry.file_info); |
558 info.size = cached_file_entry.size; | |
559 info.is_directory = cached_file_entry.is_directory; | |
560 info.is_symbolic_link = false; | |
561 info.last_modified = cached_file_entry.last_modified_time; | |
562 info.creation_time = base::Time(); | |
563 | |
564 success_callback.Run(info); | |
565 return; | 557 return; |
566 } | 558 } |
567 base::Closure closure = | 559 base::Closure closure = |
568 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, | 560 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, |
569 weak_ptr_factory_.GetWeakPtr(), | 561 weak_ptr_factory_.GetWeakPtr(), |
570 file_path, | 562 file_path, |
571 success_callback, | 563 success_callback, |
572 error_callback); | 564 error_callback); |
573 EnsureInitAndRunTask(PendingTaskInfo(file_path, | 565 EnsureInitAndRunTask(PendingTaskInfo(file_path, |
574 content::BrowserThread::IO, | 566 content::BrowserThread::IO, |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1217 EnsureInitAndRunTask(PendingTaskInfo( | 1209 EnsureInitAndRunTask(PendingTaskInfo( |
1218 base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure)); | 1210 base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure)); |
1219 PendingRequestDone(); | 1211 PendingRequestDone(); |
1220 } | 1212 } |
1221 | 1213 |
1222 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToCreateDirectory( | 1214 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToCreateDirectory( |
1223 const std::vector<base::FilePath>& components, | 1215 const std::vector<base::FilePath>& components, |
1224 const bool exclusive, | 1216 const bool exclusive, |
1225 const CreateDirectorySuccessCallback& success_callback, | 1217 const CreateDirectorySuccessCallback& success_callback, |
1226 const ErrorCallback& error_callback, | 1218 const ErrorCallback& error_callback, |
1227 const storage::AsyncFileUtil::EntryList& /* file_list */, | 1219 const storage::AsyncFileUtil::EntryList& /* entries */, |
1228 const bool has_more) { | 1220 const bool has_more) { |
1229 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1221 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1230 | 1222 |
1231 if (has_more) | 1223 if (has_more) |
1232 return; // Wait until all entries have been read. | 1224 return; // Wait until all entries have been read. |
1233 | 1225 |
1234 const base::Closure closure = | 1226 const base::Closure closure = |
1235 base::Bind(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal, | 1227 base::Bind(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal, |
1236 weak_ptr_factory_.GetWeakPtr(), components, exclusive, | 1228 weak_ptr_factory_.GetWeakPtr(), components, exclusive, |
1237 success_callback, error_callback); | 1229 success_callback, error_callback); |
1238 EnsureInitAndRunTask(PendingTaskInfo( | 1230 EnsureInitAndRunTask(PendingTaskInfo( |
1239 base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure)); | 1231 base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure)); |
1240 } | 1232 } |
1241 | 1233 |
1242 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory( | 1234 void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory( |
1243 const base::FilePath& directory_path, | 1235 const base::FilePath& directory_path, |
1244 const uint32 directory_id, | 1236 const uint32 directory_id, |
1245 const DeleteDirectorySuccessCallback& success_callback, | 1237 const DeleteDirectorySuccessCallback& success_callback, |
1246 const ErrorCallback& error_callback, | 1238 const ErrorCallback& error_callback, |
1247 const storage::AsyncFileUtil::EntryList& entries, | 1239 const MTPDeviceTaskHelper::MTPEntries& entries, |
1248 const bool has_more) { | 1240 const bool has_more) { |
1249 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1241 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1250 DCHECK(!has_more); | 1242 DCHECK(!has_more); |
1251 | 1243 |
1252 if (entries.size() > 0) { | 1244 if (entries.size() > 0) { |
1253 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY); | 1245 error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY); |
1254 } else { | 1246 } else { |
1255 RunDeleteObjectOnUIThread(directory_path, directory_id, success_callback, | 1247 RunDeleteObjectOnUIThread(directory_path, directory_id, success_callback, |
1256 error_callback); | 1248 error_callback); |
1257 } | 1249 } |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1562 const ErrorCallback& callback, | 1554 const ErrorCallback& callback, |
1563 const base::File::Error error) { | 1555 const base::File::Error error) { |
1564 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1556 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1565 | 1557 |
1566 callback.Run(base::File::FILE_ERROR_FAILED); | 1558 callback.Run(base::File::FILE_ERROR_FAILED); |
1567 } | 1559 } |
1568 | 1560 |
1569 void MTPDeviceDelegateImplLinux::OnDidReadDirectory( | 1561 void MTPDeviceDelegateImplLinux::OnDidReadDirectory( |
1570 uint32 dir_id, | 1562 uint32 dir_id, |
1571 const ReadDirectorySuccessCallback& success_callback, | 1563 const ReadDirectorySuccessCallback& success_callback, |
1572 const storage::AsyncFileUtil::EntryList& file_list, | 1564 const MTPDeviceTaskHelper::MTPEntries& mtp_entries, |
1573 bool has_more) { | 1565 bool has_more) { |
1574 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1566 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1575 | 1567 |
1576 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(dir_id); | 1568 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(dir_id); |
1577 DCHECK(it != file_id_to_node_map_.end()); | 1569 DCHECK(it != file_id_to_node_map_.end()); |
1578 MTPFileNode* dir_node = it->second; | 1570 MTPFileNode* dir_node = it->second; |
1579 | 1571 |
1580 // Traverse the MTPFileNode tree to reconstuct the full path for |dir_id|. | 1572 // Traverse the MTPFileNode tree to reconstuct the full path for |dir_id|. |
1581 std::deque<std::string> dir_path_parts; | 1573 std::deque<std::string> dir_path_parts; |
1582 MTPFileNode* parent_node = dir_node; | 1574 MTPFileNode* parent_node = dir_node; |
1583 while (parent_node->parent()) { | 1575 while (parent_node->parent()) { |
1584 dir_path_parts.push_front(parent_node->file_name()); | 1576 dir_path_parts.push_front(parent_node->file_name()); |
1585 parent_node = parent_node->parent(); | 1577 parent_node = parent_node->parent(); |
1586 } | 1578 } |
1587 base::FilePath dir_path = device_path_; | 1579 base::FilePath dir_path = device_path_; |
1588 for (size_t i = 0; i < dir_path_parts.size(); ++i) | 1580 for (size_t i = 0; i < dir_path_parts.size(); ++i) |
1589 dir_path = dir_path.Append(dir_path_parts[i]); | 1581 dir_path = dir_path.Append(dir_path_parts[i]); |
1590 | 1582 |
1591 storage::AsyncFileUtil::EntryList normalized_file_list; | 1583 storage::AsyncFileUtil::EntryList file_list; |
1592 for (size_t i = 0; i < file_list.size(); ++i) { | 1584 for (size_t i = 0; i < mtp_entries.size(); ++i) { |
Lei Zhang
2015/11/12 07:25:16
for (const auto& mtp_entry : mtp_entries) {
...
mtomasz
2015/11/12 07:48:24
Done.
| |
1593 normalized_file_list.push_back(file_list[i]); | 1585 storage::DirectoryEntry entry; |
1594 storage::DirectoryEntry& entry = normalized_file_list.back(); | 1586 entry.name = mtp_entries[i].name; |
1595 | 1587 entry.is_directory = mtp_entries[i].file_info.is_directory; |
1596 // |entry.name| has the file id encoded in it. Decode here. | 1588 file_list.push_back(entry); |
1597 size_t separator_idx = entry.name.find_last_of(','); | |
1598 DCHECK_NE(std::string::npos, separator_idx); | |
1599 std::string file_id_str = entry.name.substr(separator_idx); | |
1600 file_id_str = file_id_str.substr(1); // Get rid of the comma. | |
1601 uint32 file_id = 0; | |
1602 bool ret = base::StringToUint(file_id_str, &file_id); | |
1603 DCHECK(ret); | |
1604 entry.name = entry.name.substr(0, separator_idx); | |
1605 | 1589 |
1606 // Refresh the in memory tree. | 1590 // Refresh the in memory tree. |
1607 dir_node->EnsureChildExists(entry.name, file_id); | 1591 dir_node->EnsureChildExists(entry.name, mtp_entries[i].file_id); |
1608 child_nodes_seen_.insert(entry.name); | 1592 child_nodes_seen_.insert(entry.name); |
1609 | 1593 |
1610 // Add to |file_info_cache_|. | 1594 // Add to |file_info_cache_|. |
1611 file_info_cache_[dir_path.Append(entry.name)] = entry; | 1595 file_info_cache_[dir_path.Append(entry.name)] = mtp_entries[i]; |
1612 } | 1596 } |
1613 | 1597 |
1614 success_callback.Run(normalized_file_list, has_more); | 1598 success_callback.Run(file_list, has_more); |
1615 if (has_more) | 1599 if (has_more) |
1616 return; // Wait to be called again. | 1600 return; // Wait to be called again. |
1617 | 1601 |
1618 // Last call, finish book keeping and continue with the next request. | 1602 // Last call, finish book keeping and continue with the next request. |
1619 dir_node->ClearNonexistentChildren(child_nodes_seen_); | 1603 dir_node->ClearNonexistentChildren(child_nodes_seen_); |
1620 child_nodes_seen_.clear(); | 1604 child_nodes_seen_.clear(); |
1621 file_info_cache_.clear(); | 1605 file_info_cache_.clear(); |
1622 | 1606 |
1623 PendingRequestDone(); | 1607 PendingRequestDone(); |
1624 } | 1608 } |
(...skipping 21 matching lines...) Expand all Loading... | |
1646 void MTPDeviceDelegateImplLinux::OnDidReadBytes( | 1630 void MTPDeviceDelegateImplLinux::OnDidReadBytes( |
1647 const ReadBytesSuccessCallback& success_callback, | 1631 const ReadBytesSuccessCallback& success_callback, |
1648 const base::File::Info& file_info, int bytes_read) { | 1632 const base::File::Info& file_info, int bytes_read) { |
1649 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1633 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1650 success_callback.Run(file_info, bytes_read); | 1634 success_callback.Run(file_info, bytes_read); |
1651 PendingRequestDone(); | 1635 PendingRequestDone(); |
1652 } | 1636 } |
1653 | 1637 |
1654 void MTPDeviceDelegateImplLinux::OnDidFillFileCache( | 1638 void MTPDeviceDelegateImplLinux::OnDidFillFileCache( |
1655 const base::FilePath& path, | 1639 const base::FilePath& path, |
1656 const storage::AsyncFileUtil::EntryList& /* file_list */, | 1640 const storage::AsyncFileUtil::EntryList& /* entries */, |
1657 bool has_more) { | 1641 bool has_more) { |
1658 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1642 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1659 DCHECK(path.IsParent(pending_tasks_.front().path)); | 1643 DCHECK(path.IsParent(pending_tasks_.front().path)); |
1660 if (has_more) | 1644 if (has_more) |
1661 return; // Wait until all entries have been read. | 1645 return; // Wait until all entries have been read. |
1662 pending_tasks_.front().cached_path = path; | 1646 pending_tasks_.front().cached_path = path; |
1663 } | 1647 } |
1664 | 1648 |
1665 void MTPDeviceDelegateImplLinux::OnFillFileCacheFailed( | 1649 void MTPDeviceDelegateImplLinux::OnFillFileCacheFailed( |
1666 base::File::Error /* error */) { | 1650 base::File::Error /* error */) { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1905 } | 1889 } |
1906 } | 1890 } |
1907 | 1891 |
1908 void CreateMTPDeviceAsyncDelegate( | 1892 void CreateMTPDeviceAsyncDelegate( |
1909 const std::string& device_location, | 1893 const std::string& device_location, |
1910 const bool read_only, | 1894 const bool read_only, |
1911 const CreateMTPDeviceAsyncDelegateCallback& callback) { | 1895 const CreateMTPDeviceAsyncDelegateCallback& callback) { |
1912 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 1896 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
1913 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); | 1897 callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only)); |
1914 } | 1898 } |
OLD | NEW |