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

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

Issue 495433002: Media Galleries: Cache file info during a directory read to service incoming requests to get file i… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix device path Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 } 200 }
201 201
202 MTPDeviceDelegateImplLinux::PendingTaskInfo::~PendingTaskInfo() { 202 MTPDeviceDelegateImplLinux::PendingTaskInfo::~PendingTaskInfo() {
203 } 203 }
204 204
205 // Represents a file on the MTP device. 205 // Represents a file on the MTP device.
206 // Lives on the IO thread. 206 // Lives on the IO thread.
207 class MTPDeviceDelegateImplLinux::MTPFileNode { 207 class MTPDeviceDelegateImplLinux::MTPFileNode {
208 public: 208 public:
209 MTPFileNode(uint32 file_id, 209 MTPFileNode(uint32 file_id,
210 const std::string& file_name,
210 MTPFileNode* parent, 211 MTPFileNode* parent,
211 FileIdToMTPFileNodeMap* file_id_to_node_map); 212 FileIdToMTPFileNodeMap* file_id_to_node_map);
212 ~MTPFileNode(); 213 ~MTPFileNode();
213 214
214 const MTPFileNode* GetChild(const std::string& name) const; 215 const MTPFileNode* GetChild(const std::string& name) const;
215 216
216 void EnsureChildExists(const std::string& name, uint32 id); 217 void EnsureChildExists(const std::string& name, uint32 id);
217 218
218 // Clears all the children, except those in |children_to_keep|. 219 // Clears all the children, except those in |children_to_keep|.
219 void ClearNonexistentChildren( 220 void ClearNonexistentChildren(
220 const std::set<std::string>& children_to_keep); 221 const std::set<std::string>& children_to_keep);
221 222
222 bool DeleteChild(uint32 file_id); 223 bool DeleteChild(uint32 file_id);
223 224
224 uint32 file_id() const { return file_id_; } 225 uint32 file_id() const { return file_id_; }
226 const std::string& file_name() const { return file_name_; }
225 MTPFileNode* parent() { return parent_; } 227 MTPFileNode* parent() { return parent_; }
226 228
227 private: 229 private:
228 // Container for holding a node's children. 230 // Container for holding a node's children.
229 typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes; 231 typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes;
230 232
231 const uint32 file_id_; 233 const uint32 file_id_;
234 const std::string file_name_;
235
232 ChildNodes children_; 236 ChildNodes children_;
233 MTPFileNode* const parent_; 237 MTPFileNode* const parent_;
234 FileIdToMTPFileNodeMap* file_id_to_node_map_; 238 FileIdToMTPFileNodeMap* file_id_to_node_map_;
235 239
236 DISALLOW_COPY_AND_ASSIGN(MTPFileNode); 240 DISALLOW_COPY_AND_ASSIGN(MTPFileNode);
237 }; 241 };
238 242
239 MTPDeviceDelegateImplLinux::MTPFileNode::MTPFileNode( 243 MTPDeviceDelegateImplLinux::MTPFileNode::MTPFileNode(
240 uint32 file_id, 244 uint32 file_id,
245 const std::string& file_name,
241 MTPFileNode* parent, 246 MTPFileNode* parent,
242 FileIdToMTPFileNodeMap* file_id_to_node_map) 247 FileIdToMTPFileNodeMap* file_id_to_node_map)
243 : file_id_(file_id), 248 : file_id_(file_id),
249 file_name_(file_name),
244 parent_(parent), 250 parent_(parent),
245 file_id_to_node_map_(file_id_to_node_map) { 251 file_id_to_node_map_(file_id_to_node_map) {
246 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 252 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
247 DCHECK(file_id_to_node_map_); 253 DCHECK(file_id_to_node_map_);
248 DCHECK(!ContainsKey(*file_id_to_node_map_, file_id_)); 254 DCHECK(!ContainsKey(*file_id_to_node_map_, file_id_));
249 (*file_id_to_node_map_)[file_id_] = this; 255 (*file_id_to_node_map_)[file_id_] = this;
250 } 256 }
251 257
252 MTPDeviceDelegateImplLinux::MTPFileNode::~MTPFileNode() { 258 MTPDeviceDelegateImplLinux::MTPFileNode::~MTPFileNode() {
253 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 259 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
(...skipping 11 matching lines...) Expand all
265 void MTPDeviceDelegateImplLinux::MTPFileNode::EnsureChildExists( 271 void MTPDeviceDelegateImplLinux::MTPFileNode::EnsureChildExists(
266 const std::string& name, 272 const std::string& name,
267 uint32 id) { 273 uint32 id) {
268 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 274 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
269 const MTPFileNode* child = GetChild(name); 275 const MTPFileNode* child = GetChild(name);
270 if (child && child->file_id() == id) 276 if (child && child->file_id() == id)
271 return; 277 return;
272 278
273 children_.set( 279 children_.set(
274 name, 280 name,
275 make_scoped_ptr(new MTPFileNode(id, this, file_id_to_node_map_))); 281 make_scoped_ptr(new MTPFileNode(id, name, this, file_id_to_node_map_)));
276 } 282 }
277 283
278 void MTPDeviceDelegateImplLinux::MTPFileNode::ClearNonexistentChildren( 284 void MTPDeviceDelegateImplLinux::MTPFileNode::ClearNonexistentChildren(
279 const std::set<std::string>& children_to_keep) { 285 const std::set<std::string>& children_to_keep) {
280 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 286 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
281 std::set<std::string> children_to_erase; 287 std::set<std::string> children_to_erase;
282 for (ChildNodes::const_iterator it = children_.begin(); 288 for (ChildNodes::const_iterator it = children_.begin();
283 it != children_.end(); ++it) { 289 it != children_.end(); ++it) {
284 if (ContainsKey(children_to_keep, it->first)) 290 if (ContainsKey(children_to_keep, it->first))
285 continue; 291 continue;
(...skipping 16 matching lines...) Expand all
302 } 308 }
303 return false; 309 return false;
304 } 310 }
305 311
306 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( 312 MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux(
307 const std::string& device_location) 313 const std::string& device_location)
308 : init_state_(UNINITIALIZED), 314 : init_state_(UNINITIALIZED),
309 task_in_progress_(false), 315 task_in_progress_(false),
310 device_path_(device_location), 316 device_path_(device_location),
311 root_node_(new MTPFileNode(mtpd::kRootFileId, 317 root_node_(new MTPFileNode(mtpd::kRootFileId,
312 NULL, 318 "", // Root node has no name.
319 NULL, // And no parent node.
313 &file_id_to_node_map_)), 320 &file_id_to_node_map_)),
314 weak_ptr_factory_(this) { 321 weak_ptr_factory_(this) {
315 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 322 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
316 DCHECK(!device_path_.empty()); 323 DCHECK(!device_path_.empty());
317 base::RemoveChars(device_location, kRootPath, &storage_name_); 324 base::RemoveChars(device_location, kRootPath, &storage_name_);
318 DCHECK(!storage_name_.empty()); 325 DCHECK(!storage_name_.empty());
319 } 326 }
320 327
321 MTPDeviceDelegateImplLinux::~MTPDeviceDelegateImplLinux() { 328 MTPDeviceDelegateImplLinux::~MTPDeviceDelegateImplLinux() {
322 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 329 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
323 } 330 }
324 331
325 void MTPDeviceDelegateImplLinux::GetFileInfo( 332 void MTPDeviceDelegateImplLinux::GetFileInfo(
326 const base::FilePath& file_path, 333 const base::FilePath& file_path,
327 const GetFileInfoSuccessCallback& success_callback, 334 const GetFileInfoSuccessCallback& success_callback,
328 const ErrorCallback& error_callback) { 335 const ErrorCallback& error_callback) {
329 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 336 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
330 DCHECK(!file_path.empty()); 337 DCHECK(!file_path.empty());
338
339 // If a ReadDirectory operation is in progress, the file info may already be
340 // cached.
341 FileInfoCache::const_iterator it = file_info_cache_.find(file_path);
342 if (it != file_info_cache_.end()) {
343 // TODO(thestig): This code is repeated in several places. Combine them.
344 // e.g. c/b/media_galleries/win/mtp_device_operations_util.cc
345 const fileapi::DirectoryEntry& cached_file_entry = it->second;
346 base::File::Info info;
347 info.size = cached_file_entry.size;
348 info.is_directory = cached_file_entry.is_directory;
349 info.is_symbolic_link = false;
350 info.last_modified = cached_file_entry.last_modified_time;
351 info.creation_time = base::Time();
352
353 success_callback.Run(info);
kinaba 2014/08/20 23:10:05 Just a comment. Ah, I didn't fully understand the
354 return;
355 }
331 base::Closure closure = 356 base::Closure closure =
332 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, 357 base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
333 weak_ptr_factory_.GetWeakPtr(), 358 weak_ptr_factory_.GetWeakPtr(),
334 file_path, 359 file_path,
335 success_callback, 360 success_callback,
336 error_callback); 361 error_callback);
337 EnsureInitAndRunTask(PendingTaskInfo(file_path, 362 EnsureInitAndRunTask(PendingTaskInfo(file_path,
338 content::BrowserThread::IO, 363 content::BrowserThread::IO,
339 FROM_HERE, 364 FROM_HERE,
340 closure)); 365 closure));
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 uint32 dir_id, 751 uint32 dir_id,
727 const ReadDirectorySuccessCallback& success_callback, 752 const ReadDirectorySuccessCallback& success_callback,
728 const fileapi::AsyncFileUtil::EntryList& file_list, 753 const fileapi::AsyncFileUtil::EntryList& file_list,
729 bool has_more) { 754 bool has_more) {
730 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 755 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
731 756
732 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(dir_id); 757 FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(dir_id);
733 DCHECK(it != file_id_to_node_map_.end()); 758 DCHECK(it != file_id_to_node_map_.end());
734 MTPFileNode* dir_node = it->second; 759 MTPFileNode* dir_node = it->second;
735 760
761 // Traverse the MTPFileNode tree to reconstuct the full path for |dir_id|.
762 std::deque<std::string> dir_path_parts;
763 MTPFileNode* parent_node = dir_node;
764 while (parent_node->parent()) {
765 dir_path_parts.push_front(parent_node->file_name());
766 parent_node = parent_node->parent();
767 }
768 base::FilePath dir_path = device_path_;
769 for (size_t i = 0; i < dir_path_parts.size(); ++i)
770 dir_path = dir_path.Append(dir_path_parts[i]);
771
736 fileapi::AsyncFileUtil::EntryList normalized_file_list; 772 fileapi::AsyncFileUtil::EntryList normalized_file_list;
737 for (size_t i = 0; i < file_list.size(); ++i) { 773 for (size_t i = 0; i < file_list.size(); ++i) {
738 normalized_file_list.push_back(file_list[i]); 774 normalized_file_list.push_back(file_list[i]);
739 fileapi::DirectoryEntry& entry = normalized_file_list.back(); 775 fileapi::DirectoryEntry& entry = normalized_file_list.back();
740 776
741 // |entry.name| has the file id encoded in it. Decode here. 777 // |entry.name| has the file id encoded in it. Decode here.
742 size_t separator_idx = entry.name.find_last_of(','); 778 size_t separator_idx = entry.name.find_last_of(',');
743 DCHECK_NE(std::string::npos, separator_idx); 779 DCHECK_NE(std::string::npos, separator_idx);
744 std::string file_id_str = entry.name.substr(separator_idx); 780 std::string file_id_str = entry.name.substr(separator_idx);
745 file_id_str = file_id_str.substr(1); // Get rid of the comma. 781 file_id_str = file_id_str.substr(1); // Get rid of the comma.
746 uint32 file_id = 0; 782 uint32 file_id = 0;
747 bool ret = base::StringToUint(file_id_str, &file_id); 783 bool ret = base::StringToUint(file_id_str, &file_id);
748 DCHECK(ret); 784 DCHECK(ret);
749 entry.name = entry.name.substr(0, separator_idx); 785 entry.name = entry.name.substr(0, separator_idx);
750 786
751 // Refresh the in memory tree. 787 // Refresh the in memory tree.
752 dir_node->EnsureChildExists(entry.name, file_id); 788 dir_node->EnsureChildExists(entry.name, file_id);
753 child_nodes_seen_.insert(entry.name); 789 child_nodes_seen_.insert(entry.name);
790
791 // Add to |file_info_cache_|.
792 file_info_cache_[dir_path.Append(entry.name)] = entry;
754 } 793 }
755 794
756 success_callback.Run(normalized_file_list, has_more); 795 success_callback.Run(normalized_file_list, has_more);
757 if (has_more) 796 if (has_more)
758 return; // Wait to be called again. 797 return; // Wait to be called again.
759 798
760 // Last call, finish book keeping and continue with the next request. 799 // Last call, finish book keeping and continue with the next request.
761 dir_node->ClearNonexistentChildren(child_nodes_seen_); 800 dir_node->ClearNonexistentChildren(child_nodes_seen_);
762 child_nodes_seen_.clear(); 801 child_nodes_seen_.clear();
802 file_info_cache_.clear();
763 803
764 PendingRequestDone(); 804 PendingRequestDone();
765 } 805 }
766 806
767 void MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile( 807 void MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile(
768 const base::File::Info& file_info, 808 const base::File::Info& file_info,
769 const base::FilePath& snapshot_file_path) { 809 const base::FilePath& snapshot_file_path) {
770 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 810 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
771 DCHECK(current_snapshot_request_info_.get()); 811 DCHECK(current_snapshot_request_info_.get());
772 current_snapshot_request_info_->success_callback.Run( 812 current_snapshot_request_info_->success_callback.Run(
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 *id = current_node->file_id(); 938 *id = current_node->file_id();
899 return true; 939 return true;
900 } 940 }
901 941
902 void CreateMTPDeviceAsyncDelegate( 942 void CreateMTPDeviceAsyncDelegate(
903 const std::string& device_location, 943 const std::string& device_location,
904 const CreateMTPDeviceAsyncDelegateCallback& callback) { 944 const CreateMTPDeviceAsyncDelegateCallback& callback) {
905 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 945 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
906 callback.Run(new MTPDeviceDelegateImplLinux(device_location)); 946 callback.Run(new MTPDeviceDelegateImplLinux(device_location));
907 } 947 }
OLDNEW
« no previous file with comments | « chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698