| Index: chrome/browser/media_galleries/media_scan_manager.cc
|
| diff --git a/chrome/browser/media_galleries/media_scan_manager.cc b/chrome/browser/media_galleries/media_scan_manager.cc
|
| index b631a682e3656e8b639d105151d1246641d74da5..64a6d7a2079cc54107157f0e361e3fe8791d5996 100644
|
| --- a/chrome/browser/media_galleries/media_scan_manager.cc
|
| +++ b/chrome/browser/media_galleries/media_scan_manager.cc
|
| @@ -210,74 +210,12 @@ void AddScanResultsForProfile(
|
| unique_found_folders.size() + to_update.size());
|
| }
|
|
|
| -// A single directory may contain many folders with media in them, without
|
| -// containing any media itself. In fact, the primary purpose of that directory
|
| -// may be to contain media directories. This function tries to find those
|
| -// immediate container directories.
|
| -MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults(
|
| - const MediaFolderFinder::MediaFolderFinderResults& found_folders,
|
| - const std::vector<base::FilePath>& sensitive_locations) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
| - std::vector<base::FilePath> abs_sensitive_locations;
|
| - for (size_t i = 0; i < sensitive_locations.size(); ++i) {
|
| - base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]);
|
| - if (!path.empty())
|
| - abs_sensitive_locations.push_back(path);
|
| - }
|
| - // Count the number of scan results with the same parent directory.
|
| - typedef std::map<base::FilePath, int /*count*/> ContainerCandidates;
|
| - ContainerCandidates candidates;
|
| - for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it =
|
| - found_folders.begin(); it != found_folders.end(); ++it) {
|
| - base::FilePath parent_directory = it->first.DirName();
|
| -
|
| - // Skip sensitive folders and their ancestors.
|
| - bool is_sensitive = false;
|
| - base::FilePath abs_parent_directory =
|
| - base::MakeAbsoluteFilePath(parent_directory);
|
| - if (abs_parent_directory.empty())
|
| - continue;
|
| - for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) {
|
| - if (abs_parent_directory == abs_sensitive_locations[i] ||
|
| - abs_parent_directory.IsParent(abs_sensitive_locations[i])) {
|
| - is_sensitive = true;
|
| - continue;
|
| - }
|
| - }
|
| - if (is_sensitive)
|
| - continue;
|
| +struct ContainerCount {
|
| + int seen_count, entries_count;
|
| + bool is_qualified;
|
|
|
| - ContainerCandidates::iterator existing = candidates.find(parent_directory);
|
| - if (existing == candidates.end()) {
|
| - candidates[parent_directory] = 1;
|
| - } else {
|
| - existing->second++;
|
| - }
|
| - }
|
| -
|
| - // If a parent directory has more than one scan result, consider it.
|
| - MediaFolderFinder::MediaFolderFinderResults result;
|
| - for (ContainerCandidates::const_iterator it = candidates.begin();
|
| - it != candidates.end();
|
| - ++it) {
|
| - if (it->second <= 1)
|
| - continue;
|
| -
|
| - base::FileEnumerator dir_counter(it->first, false /*recursive*/,
|
| - base::FileEnumerator::DIRECTORIES);
|
| - base::FileEnumerator::FileInfo info;
|
| - int count = 0;
|
| - for (base::FilePath name = dir_counter.Next();
|
| - !name.empty();
|
| - name = dir_counter.Next()) {
|
| - if (!base::IsLink(name))
|
| - count++;
|
| - }
|
| - if (it->second * 100 / count >= kContainerDirectoryMinimumPercent)
|
| - result[it->first] = MediaGalleryScanResult();
|
| - }
|
| - return result;
|
| -}
|
| + ContainerCount() : seen_count(0), entries_count(-1), is_qualified(false) {}
|
| +};
|
|
|
| int CountScanResultsForExtension(MediaGalleriesPreferences* preferences,
|
| const extensions::Extension* extension,
|
| @@ -302,6 +240,20 @@ int CountScanResultsForExtension(MediaGalleriesPreferences* preferences,
|
| return gallery_count;
|
| }
|
|
|
| +int CountDirectoryEntries(const base::FilePath& path) {
|
| + base::FileEnumerator dir_counter(path, false /*recursive*/,
|
| + base::FileEnumerator::DIRECTORIES);
|
| + int count = 0;
|
| + base::FileEnumerator::FileInfo info;
|
| + for (base::FilePath name = dir_counter.Next();
|
| + !name.empty();
|
| + name = dir_counter.Next()) {
|
| + if (!base::IsLink(name))
|
| + ++count;
|
| + }
|
| + return count;
|
| +}
|
| +
|
| } // namespace
|
|
|
| MediaScanManager::MediaScanManager()
|
| @@ -423,6 +375,92 @@ void MediaScanManager::SetMediaFolderFinderFactory(
|
| testing_folder_finder_factory_ = factory;
|
| }
|
|
|
| +// A single directory may contain many folders with media in them, without
|
| +// containing any media itself. In fact, the primary purpose of that directory
|
| +// may be to contain media directories. This function tries to find those
|
| +// container directories.
|
| +MediaFolderFinder::MediaFolderFinderResults
|
| +MediaScanManager::FindContainerScanResults(
|
| + const MediaFolderFinder::MediaFolderFinderResults& found_folders,
|
| + const std::vector<base::FilePath>& sensitive_locations) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
| + std::vector<base::FilePath> abs_sensitive_locations;
|
| + for (size_t i = 0; i < sensitive_locations.size(); ++i) {
|
| + base::FilePath path = base::MakeAbsoluteFilePath(sensitive_locations[i]);
|
| + if (!path.empty())
|
| + abs_sensitive_locations.push_back(path);
|
| + }
|
| + // Find parent directories with majority of media directories,
|
| + // or container directories.
|
| + // |candidates| keeps track of directories which might have enough
|
| + // media directories to have us return them.
|
| + typedef std::map<base::FilePath, ContainerCount> ContainerCandidates;
|
| + ContainerCandidates candidates;
|
| + // |candidates_to_check| are members of |candidates| that have crossed
|
| + // threshold to be returned, and whose parents still need to be checked.
|
| + std::set<base::FilePath> candidates_to_check;
|
| + MediaFolderFinder::MediaFolderFinderResults::const_iterator folder_it =
|
| + found_folders.begin();
|
| + while (folder_it != found_folders.end() || !candidates_to_check.empty()) {
|
| + base::FilePath candidate;
|
| + // Go through incoming |found_folders| first, then discovered candidates.
|
| + if (folder_it != found_folders.end()) {
|
| + candidate = folder_it->first;
|
| + ++folder_it;
|
| + } else {
|
| + candidate = *candidates_to_check.begin();
|
| + // Remove in case it gets added back.
|
| + candidates_to_check.erase(candidates_to_check.begin());
|
| + }
|
| + base::FilePath parent_directory = candidate.DirName();
|
| +
|
| + // Skip sensitive folders and their ancestors.
|
| + base::FilePath abs_parent_directory =
|
| + base::MakeAbsoluteFilePath(parent_directory);
|
| + if (abs_parent_directory.empty())
|
| + continue;
|
| + bool is_sensitive = false;
|
| + for (size_t i = 0; i < abs_sensitive_locations.size(); ++i) {
|
| + if (abs_parent_directory == abs_sensitive_locations[i] ||
|
| + abs_parent_directory.IsParent(abs_sensitive_locations[i])) {
|
| + is_sensitive = true;
|
| + break;
|
| + }
|
| + }
|
| + if (is_sensitive)
|
| + continue;
|
| +
|
| + // Don't bother with ones we already have.
|
| + if (found_folders.find(parent_directory) != found_folders.end())
|
| + continue;
|
| +
|
| + ContainerCandidates::iterator parent_it = candidates.find(parent_directory);
|
| + if (parent_it == candidates.end()) {
|
| + ContainerCount count;
|
| + count.seen_count = 1;
|
| + count.entries_count = CountDirectoryEntries(parent_directory);
|
| + parent_it = candidates.insert(std::make_pair(parent_directory,
|
| + count)).first;
|
| + } else {
|
| + ++candidates[parent_directory].seen_count;
|
| + }
|
| + if (parent_it->second.seen_count * 100 / parent_it->second.entries_count
|
| + >= kContainerDirectoryMinimumPercent) {
|
| + // It's a qualified candidate now.
|
| + parent_it->second.is_qualified = true;
|
| + candidates_to_check.insert(parent_directory);
|
| + }
|
| + }
|
| + MediaFolderFinder::MediaFolderFinderResults result;
|
| + // Copy and return worthy results.
|
| + for (ContainerCandidates::const_iterator it = candidates.begin();
|
| + it != candidates.end(); ++it) {
|
| + if (it->second.is_qualified)
|
| + result[it->first] = MediaGalleryScanResult();
|
| + }
|
| + return result;
|
| +}
|
| +
|
| MediaScanManager::ScanObservers::ScanObservers() : observer(NULL) {}
|
| MediaScanManager::ScanObservers::~ScanObservers() {}
|
|
|
|
|