Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 // 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 | 214 // 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 | 215 // may be to contain media directories. This function tries to find those |
| 216 // immediate container directories. | 216 // container directories. |
| 217 MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults( | 217 MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults( |
| 218 const MediaFolderFinder::MediaFolderFinderResults& found_folders, | 218 const MediaFolderFinder::MediaFolderFinderResults& found_folders, |
| 219 const std::vector<base::FilePath>& sensitive_locations) { | 219 const std::vector<base::FilePath>& sensitive_locations) { |
| 220 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); | 220 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
| 221 std::vector<base::FilePath> abs_sensitive_locations; | 221 std::vector<base::FilePath> abs_sensitive_locations; |
| 222 for (size_t i = 0; i < sensitive_locations.size(); ++i) { | 222 for (size_t i = 0; i < sensitive_locations.size(); ++i) { |
| 223 base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]); | 223 base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]); |
| 224 if (!path.empty()) | 224 if (!path.empty()) |
| 225 abs_sensitive_locations.push_back(path); | 225 abs_sensitive_locations.push_back(path); |
| 226 } | 226 } |
| 227 // Count the number of scan results with the same parent directory. | 227 // Find parent directories with majority of media directories, |
|
vandebo (ex-Chrome)
2014/05/20 20:51:45
I think this change needs some unit testing. One
Kevin Bailey
2014/05/21 14:41:45
Will do. Here's another one:
A/
B/
D/
| |
| 228 // or container directories. Return |result|. | |
| 229 MediaFolderFinder::MediaFolderFinderResults result; | |
| 230 // |candidates| keeps track of directories which might have enough | |
| 231 // media entries to have us return them. | |
| 228 typedef std::map<base::FilePath, int /*count*/> ContainerCandidates; | 232 typedef std::map<base::FilePath, int /*count*/> ContainerCandidates; |
| 229 ContainerCandidates candidates; | 233 ContainerCandidates candidates; |
| 230 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it = | 234 // |candidates_to_check| are members of |candidates| that have crossed |
| 231 found_folders.begin(); it != found_folders.end(); ++it) { | 235 // threshold to be returned, and whose parents should likewise be checked. |
| 232 base::FilePath parent_directory = it->first.DirName(); | 236 std::set<base::FilePath> candidates_to_check; |
| 237 MediaFolderFinder::MediaFolderFinderResults::const_iterator folder_it = | |
| 238 found_folders.begin(); | |
| 239 while (folder_it != found_folders.end() && !candidates_to_check.empty()) { | |
| 240 base::FilePath candidate; | |
| 241 // Go through incoming |found_folders| first, then discovered candidates. | |
| 242 if (folder_it != found_folders.end()) { | |
| 243 candidate = folder_it->first; | |
| 244 ++folder_it; | |
| 245 } else { | |
| 246 candidate = *candidates_to_check.begin(); | |
| 247 // Remove in case it gets added back. | |
| 248 candidates_to_check.erase(candidates_to_check.begin()); | |
| 249 } | |
| 250 // It *could* have been nuked. | |
| 251 ContainerCandidates::iterator it = candidates.find(candidate); | |
| 252 if (it == candidates.end()) | |
|
vandebo (ex-Chrome)
2014/05/20 20:51:45
Confused... candidates starts emtpy, so we won't f
Kevin Bailey
2014/05/21 14:41:45
arg, leftover cruft. Missed it in the diffs.
| |
| 253 continue; | |
| 254 base::FilePath parent_directory = candidate.DirName(); | |
| 233 | 255 |
| 234 // Skip sensitive folders and their ancestors. | 256 // Skip sensitive folders and their ancestors. |
| 235 bool is_sensitive = false; | 257 bool is_sensitive = false; |
| 236 base::FilePath abs_parent_directory = | 258 base::FilePath abs_parent_directory = |
| 237 base::MakeAbsoluteFilePath(parent_directory); | 259 base::MakeAbsoluteFilePath(parent_directory); |
| 238 if (abs_parent_directory.empty()) | 260 if (abs_parent_directory.empty()) { |
| 261 result.erase(result.find(candidate)); | |
|
vandebo (ex-Chrome)
2014/05/20 20:51:45
Why erase it from result? Just don't add it to be
Kevin Bailey
2014/05/21 14:41:45
In fact, these lines could have simply been remove
| |
| 262 candidates.erase(it); | |
| 239 continue; | 263 continue; |
| 264 } | |
| 240 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) { | 265 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) { |
| 241 if (abs_parent_directory == abs_sensitive_locations[i] || | 266 if (abs_parent_directory == abs_sensitive_locations[i] || |
| 242 abs_parent_directory.IsParent(abs_sensitive_locations[i])) { | 267 abs_parent_directory.IsParent(abs_sensitive_locations[i])) { |
| 243 is_sensitive = true; | 268 is_sensitive = true; |
| 244 continue; | 269 break; |
| 245 } | 270 } |
| 246 } | 271 } |
| 247 if (is_sensitive) | 272 if (is_sensitive) { |
| 273 result.erase(result.find(candidate)); | |
|
vandebo (ex-Chrome)
2014/05/20 20:51:45
ditto
Kevin Bailey
2014/05/21 14:41:45
ack
| |
| 274 candidates.erase(it); | |
| 248 continue; | 275 continue; |
| 249 | 276 } |
| 250 ContainerCandidates::iterator existing = candidates.find(parent_directory); | 277 // Don't bother with ones we already have. |
| 251 if (existing == candidates.end()) { | 278 if (found_folders.find(parent_directory) != found_folders.end()) |
| 279 continue; | |
| 280 ContainerCandidates::iterator parent_it = candidates.find(parent_directory); | |
| 281 if (parent_it == candidates.end()) { | |
| 252 candidates[parent_directory] = 1; | 282 candidates[parent_directory] = 1; |
| 253 } else { | 283 continue; |
| 254 existing->second++; | |
| 255 } | 284 } |
| 256 } | 285 parent_it->second++; |
| 257 | 286 // If a parent directory has more than one scan result, consider it. |
| 258 // If a parent directory has more than one scan result, consider it. | 287 base::FileEnumerator dir_counter(parent_it->first, false /*recursive*/, |
| 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); | 288 base::FileEnumerator::DIRECTORIES); |
| 268 base::FileEnumerator::FileInfo info; | 289 base::FileEnumerator::FileInfo info; |
| 269 int count = 0; | 290 int count = 0; |
| 270 for (base::FilePath name = dir_counter.Next(); | 291 for (base::FilePath name = dir_counter.Next(); |
|
vandebo (ex-Chrome)
2014/05/20 20:51:45
This does a directory traversal on every increment
Kevin Bailey
2014/05/21 14:41:45
Done.
| |
| 271 !name.empty(); | 292 !name.empty(); |
| 272 name = dir_counter.Next()) { | 293 name = dir_counter.Next()) { |
| 273 if (!base::IsLink(name)) | 294 if (!base::IsLink(name)) |
| 274 count++; | 295 count++; |
| 275 } | 296 } |
| 276 if (it->second * 100 / count >= kContainerDirectoryMinimumPercent) | 297 if (parent_it->second * 100 / count >= kContainerDirectoryMinimumPercent) { |
| 277 result[it->first] = MediaGalleryScanResult(); | 298 // We're keeping this parent. Remove any children. |
|
vandebo (ex-Chrome)
2014/05/20 20:51:45
Why remove the children? They'll get taken care o
Kevin Bailey
2014/05/21 14:41:45
Not positive which phase that you're referring to
vandebo (ex-Chrome)
2014/05/21 15:55:09
See PartitionChildScanResults()
| |
| 299 for (ContainerCandidates::iterator child_it = candidates.begin(); | |
| 300 child_it != candidates.end(); ) { | |
| 301 if (child_it != parent_it && | |
| 302 child_it->first.DirName() == parent_it->first) { | |
| 303 ContainerCandidates::iterator next(child_it); | |
| 304 ++next; | |
| 305 result.erase(result.find(child_it->first)); | |
| 306 candidates.erase(child_it); | |
| 307 child_it = next; | |
| 308 } else { | |
| 309 ++child_it; | |
| 310 } | |
| 311 } | |
| 312 // It's a qualified candidate now. | |
| 313 result[parent_it->first] = MediaGalleryScanResult(); | |
| 314 candidates_to_check.insert(parent_it->first); | |
| 315 } | |
| 278 } | 316 } |
| 279 return result; | 317 return result; |
| 280 } | 318 } |
| 281 | 319 |
| 282 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences, | 320 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences, |
| 283 const extensions::Extension* extension, | 321 const extensions::Extension* extension, |
| 284 MediaGalleryScanResult* file_counts) { | 322 MediaGalleryScanResult* file_counts) { |
| 285 int gallery_count = 0; | 323 int gallery_count = 0; |
| 286 | 324 |
| 287 MediaGalleryPrefIdSet permitted_galleries = | 325 MediaGalleryPrefIdSet permitted_galleries = |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 gallery_count, | 546 gallery_count, |
| 509 file_counts); | 547 file_counts); |
| 510 } | 548 } |
| 511 } | 549 } |
| 512 scanning_extensions->clear(); | 550 scanning_extensions->clear(); |
| 513 preferences->SetLastScanCompletionTime(base::Time::Now()); | 551 preferences->SetLastScanCompletionTime(base::Time::Now()); |
| 514 } | 552 } |
| 515 scoped_extension_registry_observer_.RemoveAll(); | 553 scoped_extension_registry_observer_.RemoveAll(); |
| 516 folder_finder_.reset(); | 554 folder_finder_.reset(); |
| 517 } | 555 } |
| OLD | NEW |