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/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: Keep better state of candidates Created 6 years, 7 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
« no previous file with comments | « no previous file | 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 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 struct ContainerCount {
214 int seen_count, entries_count;
215 bool has_parent;
216
217 ContainerCount()
218 :seen_count(0), entries_count(-1), has_parent(false) {}
vandebo (ex-Chrome) 2014/05/21 15:55:09 nit: previous line, and ": "
Kevin Bailey 2014/05/21 17:29:36 Done.
219 };
220
213 // A single directory may contain many folders with media in them, without 221 // A single directory may contain many folders with media in them, without
214 // containing any media itself. In fact, the primary purpose of that directory 222 // containing any media itself. In fact, the primary purpose of that directory
215 // may be to contain media directories. This function tries to find those 223 // may be to contain media directories. This function tries to find those
216 // immediate container directories. 224 // container directories.
217 MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults( 225 MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults(
218 const MediaFolderFinder::MediaFolderFinderResults& found_folders, 226 const MediaFolderFinder::MediaFolderFinderResults& found_folders,
219 const std::vector<base::FilePath>& sensitive_locations) { 227 const std::vector<base::FilePath>& sensitive_locations) {
220 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); 228 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
221 std::vector<base::FilePath> abs_sensitive_locations; 229 std::vector<base::FilePath> abs_sensitive_locations;
222 for (size_t i = 0; i < sensitive_locations.size(); ++i) { 230 for (size_t i = 0; i < sensitive_locations.size(); ++i) {
223 base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]); 231 base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]);
224 if (!path.empty()) 232 if (!path.empty())
225 abs_sensitive_locations.push_back(path); 233 abs_sensitive_locations.push_back(path);
226 } 234 }
227 // Count the number of scan results with the same parent directory. 235 // Find parent directories with majority of media directories,
228 typedef std::map<base::FilePath, int /*count*/> ContainerCandidates; 236 // or container directories.
237 // |candidates| keeps track of directories which might have enough
238 // media directories to have us return them.
239 typedef std::map<base::FilePath, ContainerCount> ContainerCandidates;
229 ContainerCandidates candidates; 240 ContainerCandidates candidates;
230 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it = 241 // |candidates_to_check| are members of |candidates| that have crossed
231 found_folders.begin(); it != found_folders.end(); ++it) { 242 // threshold to be returned, and whose parents should likewise be checked.
vandebo (ex-Chrome) 2014/05/21 15:55:09 nit: "...and whose parents still need to be checke
Kevin Bailey 2014/05/21 17:29:36 I was really trying to say that we would recur on
232 base::FilePath parent_directory = it->first.DirName(); 243 std::set<base::FilePath> candidates_to_check;
244 MediaFolderFinder::MediaFolderFinderResults::const_iterator folder_it =
245 found_folders.begin();
246 while (folder_it != found_folders.end() && !candidates_to_check.empty()) {
247 base::FilePath candidate;
248 // Go through incoming |found_folders| first, then discovered candidates.
249 if (folder_it != found_folders.end()) {
250 candidate = folder_it->first;
251 ++folder_it;
252 } else {
253 candidate = *candidates_to_check.begin();
254 // Remove in case it gets added back.
255 candidates_to_check.erase(candidates_to_check.begin());
256 }
257 base::FilePath parent_directory = candidate.DirName();
233 258
234 // Skip sensitive folders and their ancestors. 259 // Skip sensitive folders and their ancestors.
235 bool is_sensitive = false; 260 bool is_sensitive = false;
236 base::FilePath abs_parent_directory = 261 base::FilePath abs_parent_directory =
237 base::MakeAbsoluteFilePath(parent_directory); 262 base::MakeAbsoluteFilePath(parent_directory);
238 if (abs_parent_directory.empty()) 263 if (abs_parent_directory.empty()) {
264 candidates.erase(candidates.find(candidate));
vandebo (ex-Chrome) 2014/05/21 15:55:09 Not needed - you only add to candidates after this
Kevin Bailey 2014/05/21 17:29:36 I think this one was left-over but the next one is
239 continue; 265 continue;
266 }
240 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) { 267 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) {
241 if (abs_parent_directory == abs_sensitive_locations[i] || 268 if (abs_parent_directory == abs_sensitive_locations[i] ||
242 abs_parent_directory.IsParent(abs_sensitive_locations[i])) { 269 abs_parent_directory.IsParent(abs_sensitive_locations[i])) {
243 is_sensitive = true; 270 is_sensitive = true;
244 continue; 271 break;
245 } 272 }
246 } 273 }
247 if (is_sensitive) 274 if (is_sensitive) {
275 candidates.erase(candidates.find(candidate));
vandebo (ex-Chrome) 2014/05/21 15:55:09 ditto
Kevin Bailey 2014/05/21 17:29:36 I don't think so. Consider: A/ sensitive/ B/
vandebo (ex-Chrome) 2014/05/21 19:21:00 Please walk be through it if I'm missing something
Kevin Bailey 2014/05/21 20:17:38 Recall that a directory itself need not be sensiti
vandebo (ex-Chrome) 2014/05/22 17:35:51 Won't that check on 269 prevent A from ever being
Kevin Bailey 2014/05/27 14:50:13 Done.
248 continue; 276 continue;
249 277 }
250 ContainerCandidates::iterator existing = candidates.find(parent_directory); 278 // Don't bother with ones we already have.
251 if (existing == candidates.end()) { 279 if (found_folders.find(parent_directory) != found_folders.end())
252 candidates[parent_directory] = 1; 280 continue;
253 } else { 281 ContainerCandidates::iterator parent_it = candidates.find(parent_directory);
254 existing->second++; 282 if (parent_it == candidates.end()) {
283 candidates[parent_directory].seen_count = 1;
284 continue;
285 }
286 parent_it->second.seen_count++;
vandebo (ex-Chrome) 2014/05/21 15:55:09 If you like, use ContainerCount* parent_counts = &
Kevin Bailey 2014/05/21 17:29:36 Done.
287 // If a parent directory has more than one scan result, consider it.
288 // If we haven't scanned it yet, do so.
289 if (parent_it->second.entries_count == -1) {
290 base::FileEnumerator dir_counter(parent_it->first, false /*recursive*/,
vandebo (ex-Chrome) 2014/05/21 15:55:09 parent_it->first => parent_directory
Kevin Bailey 2014/05/21 17:29:36 Done.
291 base::FileEnumerator::DIRECTORIES);
292 base::FileEnumerator::FileInfo info;
293 int count = 0;
vandebo (ex-Chrome) 2014/05/21 15:55:09 nit: you could use parent_it->second.entries_count
Kevin Bailey 2014/05/21 17:29:36 I generally prefer to write in an exception safe s
294 for (base::FilePath name = dir_counter.Next();
295 !name.empty();
296 name = dir_counter.Next()) {
297 if (!base::IsLink(name))
298 count++;
299 }
300 parent_it->second.entries_count = count;
301 }
302 if (parent_it->second.seen_count * 100 / parent_it->second.entries_count
303 >= kContainerDirectoryMinimumPercent) {
304 // We're keeping this parent. Mark immediate children for exclusion.
305 for (ContainerCandidates::iterator child_it = candidates.begin();
306 child_it != candidates.end(); ++child_it) {
307 if (child_it != parent_it &&
308 child_it->first.DirName() == parent_it->first) {
vandebo (ex-Chrome) 2014/05/21 15:55:09 parent_it->first => parent_directory
Kevin Bailey 2014/05/21 17:29:36 Done.
309 child_it->second.has_parent = true;
310 }
311 }
312 // It's a qualified candidate now.
313 candidates_to_check.insert(parent_it->first);
vandebo (ex-Chrome) 2014/05/21 15:55:09 parent_it->first => parent_directory
Kevin Bailey 2014/05/21 17:29:36 Done.
255 } 314 }
256 } 315 }
257
258 // If a parent directory has more than one scan result, consider it.
259 MediaFolderFinder::MediaFolderFinderResults result; 316 MediaFolderFinder::MediaFolderFinderResults result;
317 // Copy and return worthy results.
260 for (ContainerCandidates::const_iterator it = candidates.begin(); 318 for (ContainerCandidates::const_iterator it = candidates.begin();
261 it != candidates.end(); 319 it != candidates.end(); ++it) {
262 ++it) { 320 if (it->second.seen_count > 1 && it->second.seen_count * 100 /
vandebo (ex-Chrome) 2014/05/21 15:55:09 Instead of duplicating the criteria here would it
Kevin Bailey 2014/05/21 17:29:36 Sure, swapping it for |has_parent| is free.
263 if (it->second <= 1) 321 it->second.entries_count >= kContainerDirectoryMinimumPercent &&
264 continue; 322 !it->second.has_parent) {
265 323 result[it->first] = MediaGalleryScanResult();
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 } 324 }
276 if (it->second * 100 / count >= kContainerDirectoryMinimumPercent)
277 result[it->first] = MediaGalleryScanResult();
278 } 325 }
279 return result; 326 return result;
280 } 327 }
281 328
282 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences, 329 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences,
283 const extensions::Extension* extension, 330 const extensions::Extension* extension,
284 MediaGalleryScanResult* file_counts) { 331 MediaGalleryScanResult* file_counts) {
285 int gallery_count = 0; 332 int gallery_count = 0;
286 333
287 MediaGalleryPrefIdSet permitted_galleries = 334 MediaGalleryPrefIdSet permitted_galleries =
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 gallery_count, 555 gallery_count,
509 file_counts); 556 file_counts);
510 } 557 }
511 } 558 }
512 scanning_extensions->clear(); 559 scanning_extensions->clear();
513 preferences->SetLastScanCompletionTime(base::Time::Now()); 560 preferences->SetLastScanCompletionTime(base::Time::Now());
514 } 561 }
515 scoped_extension_registry_observer_.RemoveAll(); 562 scoped_extension_registry_observer_.RemoveAll();
516 folder_finder_.reset(); 563 folder_finder_.reset();
517 } 564 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698