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

Side by Side Diff: chrome/browser/media_galleries/media_scan_manager.cc

Issue 285433004: Have FindContainerScanResults() find broader media container directories (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Unit tests (and fixes they found) Created 6 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/media_scan_manager.h" 5 #include "chrome/browser/media_galleries/media_scan_manager.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/files/file_enumerator.h" 8 #include "base/files/file_enumerator.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 MediaGalleryPrefInfo::kScanResult, 203 MediaGalleryPrefInfo::kScanResult,
204 gallery.volume_label, gallery.vendor_name, 204 gallery.volume_label, gallery.vendor_name,
205 gallery.model_name, gallery.total_size_in_bytes, 205 gallery.model_name, gallery.total_size_in_bytes,
206 gallery.last_attach_time, file_counts.audio_count, 206 gallery.last_attach_time, file_counts.audio_count,
207 file_counts.image_count, file_counts.video_count); 207 file_counts.image_count, file_counts.video_count);
208 } 208 }
209 UMA_HISTOGRAM_COUNTS_10000("MediaGalleries.ScanGalleriesPopulated", 209 UMA_HISTOGRAM_COUNTS_10000("MediaGalleries.ScanGalleriesPopulated",
210 unique_found_folders.size() + to_update.size()); 210 unique_found_folders.size() + to_update.size());
211 } 211 }
212 212
213 // A single directory may contain many folders with media in them, without 213 struct ContainerCount {
214 // containing any media itself. In fact, the primary purpose of that directory 214 int seen_count, entries_count;
215 // may be to contain media directories. This function tries to find those 215 bool is_qualified;
216 // immediate container directories.
217 MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults(
218 const MediaFolderFinder::MediaFolderFinderResults& found_folders,
219 const std::vector<base::FilePath>& sensitive_locations) {
220 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
221 std::vector<base::FilePath> abs_sensitive_locations;
222 for (size_t i = 0; i < sensitive_locations.size(); ++i) {
223 base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]);
224 if (!path.empty())
225 abs_sensitive_locations.push_back(path);
226 }
227 // Count the number of scan results with the same parent directory.
228 typedef std::map<base::FilePath, int /*count*/> ContainerCandidates;
229 ContainerCandidates candidates;
230 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it =
231 found_folders.begin(); it != found_folders.end(); ++it) {
232 base::FilePath parent_directory = it->first.DirName();
233 216
234 // Skip sensitive folders and their ancestors. 217 ContainerCount() : seen_count(0), entries_count(-1), is_qualified(false) {}
235 bool is_sensitive = false; 218 };
236 base::FilePath abs_parent_directory =
237 base::MakeAbsoluteFilePath(parent_directory);
238 if (abs_parent_directory.empty())
239 continue;
240 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) {
241 if (abs_parent_directory == abs_sensitive_locations[i] ||
242 abs_parent_directory.IsParent(abs_sensitive_locations[i])) {
243 is_sensitive = true;
244 continue;
245 }
246 }
247 if (is_sensitive)
248 continue;
249
250 ContainerCandidates::iterator existing = candidates.find(parent_directory);
251 if (existing == candidates.end()) {
252 candidates[parent_directory] = 1;
253 } else {
254 existing->second++;
255 }
256 }
257
258 // If a parent directory has more than one scan result, consider it.
259 MediaFolderFinder::MediaFolderFinderResults result;
260 for (ContainerCandidates::const_iterator it = candidates.begin();
261 it != candidates.end();
262 ++it) {
263 if (it->second <= 1)
264 continue;
265
266 base::FileEnumerator dir_counter(it->first, false /*recursive*/,
267 base::FileEnumerator::DIRECTORIES);
268 base::FileEnumerator::FileInfo info;
269 int count = 0;
270 for (base::FilePath name = dir_counter.Next();
271 !name.empty();
272 name = dir_counter.Next()) {
273 if (!base::IsLink(name))
274 count++;
275 }
276 if (it->second * 100 / count >= kContainerDirectoryMinimumPercent)
277 result[it->first] = MediaGalleryScanResult();
278 }
279 return result;
280 }
281 219
282 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences, 220 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences,
283 const extensions::Extension* extension, 221 const extensions::Extension* extension,
284 MediaGalleryScanResult* file_counts) { 222 MediaGalleryScanResult* file_counts) {
285 int gallery_count = 0; 223 int gallery_count = 0;
286 224
287 MediaGalleryPrefIdSet permitted_galleries = 225 MediaGalleryPrefIdSet permitted_galleries =
288 preferences->GalleriesForExtension(*extension); 226 preferences->GalleriesForExtension(*extension);
289 const MediaGalleriesPrefInfoMap& known_galleries = 227 const MediaGalleriesPrefInfoMap& known_galleries =
290 preferences->known_galleries(); 228 preferences->known_galleries();
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 base::Time::Now() - scan_start_time_); 354 base::Time::Now() - scan_start_time_);
417 scan_start_time_ = base::Time(); 355 scan_start_time_ = base::Time();
418 } 356 }
419 } 357 }
420 358
421 void MediaScanManager::SetMediaFolderFinderFactory( 359 void MediaScanManager::SetMediaFolderFinderFactory(
422 const MediaFolderFinderFactory& factory) { 360 const MediaFolderFinderFactory& factory) {
423 testing_folder_finder_factory_ = factory; 361 testing_folder_finder_factory_ = factory;
424 } 362 }
425 363
364 // A single directory may contain many folders with media in them, without
365 // containing any media itself. In fact, the primary purpose of that directory
366 // may be to contain media directories. This function tries to find those
367 // container directories.
368 MediaFolderFinder::MediaFolderFinderResults
369 MediaScanManager::FindContainerScanResults(
370 const MediaFolderFinder::MediaFolderFinderResults& found_folders,
371 const std::vector<base::FilePath>& sensitive_locations) {
372 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
373 std::vector<base::FilePath> abs_sensitive_locations;
374 for (size_t i = 0; i < sensitive_locations.size(); ++i) {
375 base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]);
376 if (!path.empty())
377 abs_sensitive_locations.push_back(path);
378 }
379 // Find parent directories with majority of media directories,
380 // or container directories.
381 // |candidates| keeps track of directories which might have enough
382 // media directories to have us return them.
383 typedef std::map<base::FilePath, ContainerCount> ContainerCandidates;
384 ContainerCandidates candidates;
385 // |candidates_to_check| are members of |candidates| that have crossed
386 // threshold to be returned, and whose parents still need to be checked.
387 std::set<base::FilePath> candidates_to_check;
388 MediaFolderFinder::MediaFolderFinderResults::const_iterator folder_it =
389 found_folders.begin();
390 while (folder_it != found_folders.end() || !candidates_to_check.empty()) {
391 base::FilePath candidate;
392 // Go through incoming |found_folders| first, then discovered candidates.
393 if (folder_it != found_folders.end()) {
394 candidate = folder_it->first;
395 ++folder_it;
396 } else {
397 candidate = *candidates_to_check.begin();
398 // Remove in case it gets added back.
399 candidates_to_check.erase(candidates_to_check.begin());
400 }
401 base::FilePath parent_directory = candidate.DirName();
402
403 // Skip sensitive folders and their ancestors.
404 bool is_sensitive = false;
vandebo (ex-Chrome) 2014/05/27 19:07:16 nit: move this to line 409
Kevin Bailey 2014/05/27 21:04:36 Done.
405 base::FilePath abs_parent_directory =
406 base::MakeAbsoluteFilePath(parent_directory);
407 if (abs_parent_directory.empty())
408 continue;
409 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) {
410 if (abs_parent_directory == abs_sensitive_locations[i] ||
411 abs_parent_directory.IsParent(abs_sensitive_locations[i])) {
412 is_sensitive = true;
413 break;
414 }
415 }
416 if (is_sensitive)
417 continue;
418 // Don't bother with ones we already have.
vandebo (ex-Chrome) 2014/05/27 19:07:16 nit: add a blank line above comment.
Kevin Bailey 2014/05/27 21:04:36 Done.
419 if (found_folders.find(parent_directory) != found_folders.end())
420 continue;
421 ContainerCandidates::iterator parent_it = candidates.find(parent_directory);
vandebo (ex-Chrome) 2014/05/27 19:07:16 nit: add a blank line, otherwise at first glance t
Kevin Bailey 2014/05/27 21:04:36 Done.
422 if (parent_it == candidates.end()) {
423 candidates[parent_directory].seen_count = 1;
424 continue;
425 }
426 ContainerCount* parent_counts = &parent_it->second;
427 ++parent_counts->seen_count;
428 // If a parent directory has more than one scan result, consider it.
vandebo (ex-Chrome) 2014/05/27 19:07:16 nit: this comment should probably go up on line 42
Kevin Bailey 2014/05/27 21:04:36 I was attempting to say, "Since at this point it h
429 // If we haven't scanned it yet, do so.
vandebo (ex-Chrome) 2014/05/27 19:07:16 nit: scanned is a fairly generic term.. => If need
Kevin Bailey 2014/05/27 21:04:36 Done with respect to the previous comment.
430 if (parent_counts->entries_count == -1) {
431 parent_counts->entries_count = 0;
vandebo (ex-Chrome) 2014/05/27 19:07:16 nit: Consider putting this into a helper function
Kevin Bailey 2014/05/27 21:04:36 Done. Didn't spot anything in base/files already d
432 base::FileEnumerator dir_counter(parent_directory, false /*recursive*/,
433 base::FileEnumerator::DIRECTORIES);
434 base::FileEnumerator::FileInfo info;
435 for (base::FilePath name = dir_counter.Next();
436 !name.empty();
437 name = dir_counter.Next()) {
438 if (!base::IsLink(name))
439 ++parent_counts->entries_count;
440 }
441 }
442 if (parent_it->second.seen_count * 100 / parent_it->second.entries_count
443 >= kContainerDirectoryMinimumPercent) {
444 // It's a qualified candidate now.
445 parent_it->second.is_qualified = true;
446 candidates_to_check.insert(parent_directory);
447 }
448 }
449 MediaFolderFinder::MediaFolderFinderResults result;
450 // Copy and return worthy results.
451 for (ContainerCandidates::const_iterator it = candidates.begin();
452 it != candidates.end(); ++it) {
453 if (it->second.is_qualified)
454 result[it->first] = MediaGalleryScanResult();
455 }
456 return result;
457 }
458
426 MediaScanManager::ScanObservers::ScanObservers() : observer(NULL) {} 459 MediaScanManager::ScanObservers::ScanObservers() : observer(NULL) {}
427 MediaScanManager::ScanObservers::~ScanObservers() {} 460 MediaScanManager::ScanObservers::~ScanObservers() {}
428 461
429 void MediaScanManager::OnExtensionUnloaded( 462 void MediaScanManager::OnExtensionUnloaded(
430 content::BrowserContext* browser_context, 463 content::BrowserContext* browser_context,
431 const extensions::Extension* extension, 464 const extensions::Extension* extension,
432 extensions::UnloadedExtensionInfo::Reason reason) { 465 extensions::UnloadedExtensionInfo::Reason reason) {
433 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 466 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
434 CancelScan(Profile::FromBrowserContext(browser_context), extension); 467 CancelScan(Profile::FromBrowserContext(browser_context), extension);
435 } 468 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 gallery_count, 541 gallery_count,
509 file_counts); 542 file_counts);
510 } 543 }
511 } 544 }
512 scanning_extensions->clear(); 545 scanning_extensions->clear();
513 preferences->SetLastScanCompletionTime(base::Time::Now()); 546 preferences->SetLastScanCompletionTime(base::Time::Now());
514 } 547 }
515 scoped_extension_registry_observer_.RemoveAll(); 548 scoped_extension_registry_observer_.RemoveAll();
516 folder_finder_.reset(); 549 folder_finder_.reset();
517 } 550 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698