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 |
| 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 |