| 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..93ad45f7ddda48f5d717fd0ae55ec92caedce5ac 100644
|
| --- a/chrome/browser/media_galleries/media_scan_manager.cc
|
| +++ b/chrome/browser/media_galleries/media_scan_manager.cc
|
| @@ -210,75 +210,6 @@ 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;
|
| -
|
| - 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;
|
| -}
|
| -
|
| int CountScanResultsForExtension(MediaGalleriesPreferences* preferences,
|
| const extensions::Extension* extension,
|
| MediaGalleryScanResult* file_counts) {
|
| @@ -302,6 +233,28 @@ 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;
|
| +}
|
| +
|
| +struct ContainerCount {
|
| + int seen_count, entries_count;
|
| + bool is_qualified;
|
| +
|
| + ContainerCount() : seen_count(0), entries_count(-1), is_qualified(false) {}
|
| +};
|
| +
|
| +typedef std::map<base::FilePath, ContainerCount> ContainerCandidates;
|
| +
|
| } // namespace
|
|
|
| MediaScanManager::MediaScanManager()
|
| @@ -423,6 +376,90 @@ 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);
|
| + }
|
| + // Recursively find parent directories with majority of media directories,
|
| + // or container directories.
|
| + // |candidates| keeps track of directories which might have enough
|
| + // such directories to have us return them.
|
| + typedef std::map<base::FilePath, ContainerCount> ContainerCandidates;
|
| + ContainerCandidates candidates;
|
| + for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it =
|
| + found_folders.begin();
|
| + it != found_folders.end();
|
| + ++it) {
|
| + base::FilePath child_directory = it->first;
|
| + base::FilePath parent_directory = child_directory.DirName();
|
| +
|
| + // Parent of root is root.
|
| + while (!parent_directory.empty() && child_directory != parent_directory) {
|
| + // Skip sensitive folders and their ancestors.
|
| + base::FilePath abs_parent_directory =
|
| + base::MakeAbsoluteFilePath(parent_directory);
|
| + if (abs_parent_directory.empty())
|
| + break;
|
| + 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)
|
| + break;
|
| +
|
| + // 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 previously sufficient, or not sufficient, bail.
|
| + if (parent_it->second.is_qualified ||
|
| + parent_it->second.seen_count * 100 / parent_it->second.entries_count <
|
| + kContainerDirectoryMinimumPercent) {
|
| + break;
|
| + }
|
| + // Otherwise, mark qualified and check parent.
|
| + parent_it->second.is_qualified = true;
|
| + child_directory = parent_directory;
|
| + parent_directory = child_directory.DirName();
|
| + }
|
| + }
|
| + MediaFolderFinder::MediaFolderFinderResults result;
|
| + // Copy and return worthy results.
|
| + for (ContainerCandidates::const_iterator it = candidates.begin();
|
| + it != candidates.end();
|
| + ++it) {
|
| + if (it->second.is_qualified && it->second.seen_count >= 2)
|
| + result[it->first] = MediaGalleryScanResult();
|
| + }
|
| + return result;
|
| +}
|
| +
|
| MediaScanManager::ScanObservers::ScanObservers() : observer(NULL) {}
|
| MediaScanManager::ScanObservers::~ScanObservers() {}
|
|
|
|
|