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 // immediate container directories. |
vandebo (ex-Chrome)
2014/05/14 22:33:08
nit: remove "immediate"
Kevin Bailey
2014/05/20 16:21:39
Done.
| |
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 // Count the number of scan results with the same parent directory. |
vandebo (ex-Chrome)
2014/05/14 22:33:08
This comment seems wrong now
Kevin Bailey
2014/05/20 16:21:39
Better?
| |
228 MediaFolderFinder::MediaFolderFinderResults result; | |
228 typedef std::map<base::FilePath, int /*count*/> ContainerCandidates; | 229 typedef std::map<base::FilePath, int /*count*/> ContainerCandidates; |
229 ContainerCandidates candidates; | 230 ContainerCandidates candidates; |
vandebo (ex-Chrome)
2014/05/14 22:33:08
Having result, candidates, and interesting_candida
Kevin Bailey
2014/05/20 16:21:39
I renamed to |candidates_to_check|, and commented
| |
231 std::set<base::FilePath> interesting_candidates; | |
232 // Add incoming folders to all the lists. | |
230 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it = | 233 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it = |
231 found_folders.begin(); it != found_folders.end(); ++it) { | 234 found_folders.begin(); it != found_folders.end(); ++it) { |
232 base::FilePath parent_directory = it->first.DirName(); | 235 // All original folders are "permanent" candidates. |
236 // If not subsumed by parent, they get reported. | |
237 // TODO: We could even keep the original audio_count, ... | |
vandebo (ex-Chrome)
2014/05/14 22:33:08
Container results should be reported with zero cou
Kevin Bailey
2014/05/20 16:21:39
Done.
| |
238 result[it->first] = MediaGalleryScanResult(); | |
239 // We have to use this count in case this candidate is treated like a | |
240 // parent. Media files have to outnumber non-media entries. | |
241 candidates[it->first] = it->second.audio_count + it->second.image_count + | |
vandebo (ex-Chrome)
2014/05/14 22:33:08
Why do we need the counts of media files?
Kevin Bailey
2014/05/20 16:21:39
Gone.
| |
242 it->second.video_count; | |
243 // Add it to the list to be considered. | |
244 interesting_candidates.insert(it->first); | |
245 } | |
246 base::FilePath candidate; | |
247 while (!interesting_candidates.empty()) { | |
248 candidate = *interesting_candidates.begin(); | |
249 // Remove in case it gets added back. | |
250 interesting_candidates.erase(interesting_candidates.begin()); | |
251 // It *could* have been nuked. | |
252 ContainerCandidates::iterator it = candidates.find(candidate); | |
253 if (it == candidates.end()) | |
254 continue; | |
255 base::FilePath parent_directory = candidate.DirName(); | |
233 | 256 |
234 // Skip sensitive folders and their ancestors. | 257 // Skip sensitive folders and their ancestors. |
235 bool is_sensitive = false; | 258 bool is_sensitive = false; |
236 base::FilePath abs_parent_directory = | 259 base::FilePath abs_parent_directory = |
237 base::MakeAbsoluteFilePath(parent_directory); | 260 base::MakeAbsoluteFilePath(parent_directory); |
238 if (abs_parent_directory.empty()) | 261 if (abs_parent_directory.empty()) { |
262 result.erase(result.find(candidate)); | |
263 candidates.erase(it); | |
239 continue; | 264 continue; |
265 } | |
240 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) { | 266 for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) { |
241 if (abs_parent_directory == abs_sensitive_locations[i] || | 267 if (abs_parent_directory == abs_sensitive_locations[i] || |
242 abs_parent_directory.IsParent(abs_sensitive_locations[i])) { | 268 abs_parent_directory.IsParent(abs_sensitive_locations[i])) { |
243 is_sensitive = true; | 269 is_sensitive = true; |
244 continue; | 270 break; |
245 } | 271 } |
246 } | 272 } |
247 if (is_sensitive) | 273 if (is_sensitive) { |
274 result.erase(result.find(candidate)); | |
275 candidates.erase(it); | |
248 continue; | 276 continue; |
249 | 277 } |
250 ContainerCandidates::iterator existing = candidates.find(parent_directory); | 278 ContainerCandidates::iterator it_parent = candidates.find(parent_directory); |
251 if (existing == candidates.end()) { | 279 if (it_parent == candidates.end()) { |
252 candidates[parent_directory] = 1; | 280 candidates[parent_directory] = 1; |
253 } else { | 281 continue; |
254 existing->second++; | |
255 } | 282 } |
256 } | 283 it_parent->second++; |
257 | 284 // 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. | 285 base::FileEnumerator dir_counter(it_parent->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); | 286 base::FileEnumerator::DIRECTORIES); |
268 base::FileEnumerator::FileInfo info; | 287 base::FileEnumerator::FileInfo info; |
269 int count = 0; | 288 int count = 0; |
270 for (base::FilePath name = dir_counter.Next(); | 289 for (base::FilePath name = dir_counter.Next(); |
271 !name.empty(); | 290 !name.empty(); |
272 name = dir_counter.Next()) { | 291 name = dir_counter.Next()) { |
273 if (!base::IsLink(name)) | 292 if (!base::IsLink(name)) |
274 count++; | 293 count++; |
275 } | 294 } |
276 if (it->second * 100 / count >= kContainerDirectoryMinimumPercent) | 295 if (it_parent->second * 100 / count >= kContainerDirectoryMinimumPercent) { |
277 result[it->first] = MediaGalleryScanResult(); | 296 // We're keeping this parent. Remove all children. |
vandebo (ex-Chrome)
2014/05/14 22:33:08
Which children to remove is Profile specific, so y
Kevin Bailey
2014/05/20 16:21:39
Gone, but we do remove children that we've added.
| |
297 for (ContainerCandidates::iterator it_child = candidates.begin(); | |
298 it_child != candidates.end(); ) { | |
299 if (it_child != it_parent && | |
300 it_child->first.DirName() == it_parent->first) { | |
301 ContainerCandidates::iterator next(it_child); | |
302 ++next; | |
303 result.erase(result.find(it_child->first)); | |
304 candidates.erase(it_child); | |
305 it_child = next; | |
306 } else { | |
307 ++it_child; | |
308 } | |
309 } | |
310 // It's a qualified candidate now. | |
311 result[it_parent->first] = MediaGalleryScanResult(); | |
312 interesting_candidates.insert(it_parent->first); | |
313 } | |
278 } | 314 } |
279 return result; | 315 return result; |
280 } | 316 } |
281 | 317 |
282 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences, | 318 int CountScanResultsForExtension(MediaGalleriesPreferences* preferences, |
283 const extensions::Extension* extension, | 319 const extensions::Extension* extension, |
284 MediaGalleryScanResult* file_counts) { | 320 MediaGalleryScanResult* file_counts) { |
285 int gallery_count = 0; | 321 int gallery_count = 0; |
286 | 322 |
287 MediaGalleryPrefIdSet permitted_galleries = | 323 MediaGalleryPrefIdSet permitted_galleries = |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 UMA_HISTOGRAM_LONG_TIMES("MediaGalleries.ScanFinishedTime", | 495 UMA_HISTOGRAM_LONG_TIMES("MediaGalleries.ScanFinishedTime", |
460 base::Time::Now() - scan_start_time_); | 496 base::Time::Now() - scan_start_time_); |
461 scan_start_time_ = base::Time(); | 497 scan_start_time_ = base::Time(); |
462 | 498 |
463 content::BrowserThread::PostTaskAndReplyWithResult( | 499 content::BrowserThread::PostTaskAndReplyWithResult( |
464 content::BrowserThread::FILE, FROM_HERE, | 500 content::BrowserThread::FILE, FROM_HERE, |
465 base::Bind(FindContainerScanResults, | 501 base::Bind(FindContainerScanResults, |
466 found_folders, | 502 found_folders, |
467 folder_finder_->graylisted_folders()), | 503 folder_finder_->graylisted_folders()), |
468 base::Bind(&MediaScanManager::OnFoundContainerDirectories, | 504 base::Bind(&MediaScanManager::OnFoundContainerDirectories, |
469 weak_factory_.GetWeakPtr(), | 505 weak_factory_.GetWeakPtr())); |
470 found_folders)); | |
471 } | 506 } |
472 | 507 |
473 void MediaScanManager::OnFoundContainerDirectories( | 508 void MediaScanManager::OnFoundContainerDirectories( |
474 const MediaFolderFinder::MediaFolderFinderResults& found_folders, | |
475 const MediaFolderFinder::MediaFolderFinderResults& container_folders) { | 509 const MediaFolderFinder::MediaFolderFinderResults& container_folders) { |
476 MediaFolderFinder::MediaFolderFinderResults folders; | |
477 folders.insert(found_folders.begin(), found_folders.end()); | |
478 folders.insert(container_folders.begin(), container_folders.end()); | |
479 | 510 |
480 for (ScanObserverMap::iterator scans_for_profile = observers_.begin(); | 511 for (ScanObserverMap::iterator scans_for_profile = observers_.begin(); |
481 scans_for_profile != observers_.end(); | 512 scans_for_profile != observers_.end(); |
482 ++scans_for_profile) { | 513 ++scans_for_profile) { |
483 if (scans_for_profile->second.scanning_extensions.empty()) | 514 if (scans_for_profile->second.scanning_extensions.empty()) |
484 continue; | 515 continue; |
485 Profile* profile = scans_for_profile->first; | 516 Profile* profile = scans_for_profile->first; |
486 MediaGalleriesPreferences* preferences = | 517 MediaGalleriesPreferences* preferences = |
487 MediaGalleriesPreferencesFactory::GetForProfile(profile); | 518 MediaGalleriesPreferencesFactory::GetForProfile(profile); |
488 ExtensionService* extension_service = | 519 ExtensionService* extension_service = |
489 extensions::ExtensionSystem::Get(profile)->extension_service(); | 520 extensions::ExtensionSystem::Get(profile)->extension_service(); |
490 if (!extension_service) | 521 if (!extension_service) |
491 continue; | 522 continue; |
492 | 523 |
493 AddScanResultsForProfile(preferences, folders); | 524 AddScanResultsForProfile(preferences, container_folders); |
vandebo (ex-Chrome)
2014/05/14 22:33:08
We need to add all the scan results - this is the
Kevin Bailey
2014/05/20 16:21:39
Restored original code.
| |
494 | 525 |
495 ScanningExtensionIdSet* scanning_extensions = | 526 ScanningExtensionIdSet* scanning_extensions = |
496 &scans_for_profile->second.scanning_extensions; | 527 &scans_for_profile->second.scanning_extensions; |
497 for (ScanningExtensionIdSet::const_iterator extension_id_it = | 528 for (ScanningExtensionIdSet::const_iterator extension_id_it = |
498 scanning_extensions->begin(); | 529 scanning_extensions->begin(); |
499 extension_id_it != scanning_extensions->end(); | 530 extension_id_it != scanning_extensions->end(); |
500 ++extension_id_it) { | 531 ++extension_id_it) { |
501 const extensions::Extension* extension = | 532 const extensions::Extension* extension = |
502 extension_service->GetExtensionById(*extension_id_it, false); | 533 extension_service->GetExtensionById(*extension_id_it, false); |
503 if (extension) { | 534 if (extension) { |
504 MediaGalleryScanResult file_counts; | 535 MediaGalleryScanResult file_counts; |
505 int gallery_count = CountScanResultsForExtension(preferences, extension, | 536 int gallery_count = CountScanResultsForExtension(preferences, extension, |
506 &file_counts); | 537 &file_counts); |
507 scans_for_profile->second.observer->OnScanFinished(*extension_id_it, | 538 scans_for_profile->second.observer->OnScanFinished(*extension_id_it, |
508 gallery_count, | 539 gallery_count, |
509 file_counts); | 540 file_counts); |
510 } | 541 } |
511 } | 542 } |
512 scanning_extensions->clear(); | 543 scanning_extensions->clear(); |
513 preferences->SetLastScanCompletionTime(base::Time::Now()); | 544 preferences->SetLastScanCompletionTime(base::Time::Now()); |
514 } | 545 } |
515 scoped_extension_registry_observer_.RemoveAll(); | 546 scoped_extension_registry_observer_.RemoveAll(); |
516 folder_finder_.reset(); | 547 folder_finder_.reset(); |
517 } | 548 } |
OLD | NEW |