Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Unified Diff: chrome/browser/media_galleries/media_folder_finder.cc

Issue 166353002: Media Galleries: Refactor media scan worker function into a worker class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media_galleries/media_folder_finder.cc
diff --git a/chrome/browser/media_galleries/media_folder_finder.cc b/chrome/browser/media_galleries/media_folder_finder.cc
index d2924fbb3e90a1ef557a2071ef00124caca5d6fd..3c15b090613d4af8fa2ffb068c63e3ff69083884 100644
--- a/chrome/browser/media_galleries/media_folder_finder.cc
+++ b/chrome/browser/media_galleries/media_folder_finder.cc
@@ -9,6 +9,7 @@
#include "base/files/file_enumerator.h"
#include "base/path_service.h"
+#include "base/sequence_checker.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/task_runner_util.h"
@@ -35,18 +36,17 @@ bool IsValidScanPath(const base::FilePath& path) {
return !path.empty() && path.IsAbsolute();
}
-MediaGalleryScanFileType FilterPath(MediaPathFilter* filter,
- const base::FilePath& path) {
- DCHECK(IsValidScanPath(path));
- return filter->GetType(path);
+void CountScanResult(MediaGalleryScanFileType type,
+ MediaGalleryScanResult* scan_result) {
+ if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE)
+ scan_result->image_count += 1;
+ if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO)
+ scan_result->audio_count += 1;
+ if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO)
+ scan_result->video_count += 1;
}
-bool FileMeetsSizeRequirement(bool requirement_met,
- MediaGalleryScanFileType type,
- int64 size) {
- if (requirement_met)
- return true;
-
+bool FileMeetsSizeRequirement(MediaGalleryScanFileType type, int64 size) {
if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE)
if (size >= kMinimumImageSize)
return true;
@@ -59,58 +59,6 @@ bool FileMeetsSizeRequirement(bool requirement_met,
return false;
}
-void ScanFolderOnBlockingPool(
- const base::FilePath& path,
- const MediaFolderFinder::FilterCallback& filter_callback_,
- MediaGalleryScanResult* scan_result,
- std::vector<base::FilePath>* new_folders) {
- CHECK(IsValidScanPath(path));
- DCHECK(scan_result);
- DCHECK(new_folders);
- DCHECK(IsEmptyScanResult(*scan_result));
-
- bool folder_meets_size_requirement = false;
- base::FileEnumerator enumerator(
- path,
- false, /* recursive? */
- base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES
-#if defined(OS_POSIX)
- | base::FileEnumerator::SHOW_SYM_LINKS // show symlinks, not follow.
-#endif
- );
- while (!enumerator.Next().empty()) {
- base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
- base::FilePath full_path = path.Append(file_info.GetName());
- if (MediaPathFilter::ShouldSkip(full_path))
- continue;
-
- if (file_info.IsDirectory()) {
- new_folders->push_back(full_path);
- continue;
- }
- MediaGalleryScanFileType type = filter_callback_.Run(full_path);
- if (type == MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN)
- continue;
-
- // Make sure there is at least 1 file above a size threshold.
- if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE)
- scan_result->image_count += 1;
- if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO)
- scan_result->audio_count += 1;
- if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO)
- scan_result->video_count += 1;
- folder_meets_size_requirement =
- FileMeetsSizeRequirement(folder_meets_size_requirement,
- type,
- file_info.GetSize());
- }
- if (!folder_meets_size_requirement) {
- scan_result->image_count = 0;
- scan_result->audio_count = 0;
- scan_result->video_count = 0;
- }
-}
-
// Return true if |path| should not be considered as the starting point for a
// media scan.
bool ShouldIgnoreScanRoot(const base::FilePath& path) {
@@ -189,17 +137,95 @@ void GetDefaultScanRoots(const DefaultScanRootsCallback& callback,
} // namespace
+// The Worker is created on the UI thread, but does all its work on a blocking
+// SequencedTaskRunner.
+class MediaFolderFinder::Worker {
+ public:
+ Worker();
+ ~Worker();
+
+ // Scans |path| and return the results.
+ WorkerReply ScanFolder(const base::FilePath& path);
+
+ private:
+ scoped_ptr<MediaPathFilter> filter_;
+
+ base::SequenceChecker sequence_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(Worker);
+};
+
+MediaFolderFinder::Worker::Worker() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ filter_.reset(new MediaPathFilter);
+ sequence_checker_.DetachFromSequence();
+}
+
+MediaFolderFinder::Worker::~Worker() {
+ DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+}
+
+MediaFolderFinder::WorkerReply MediaFolderFinder::Worker::ScanFolder(
+ const base::FilePath& path) {
+ DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ CHECK(IsValidScanPath(path));
+
+ WorkerReply reply;
+ MediaGalleryScanResult& scan_result = reply.first;
+ std::vector<base::FilePath>& new_folders = reply.second;
+ bool folder_meets_size_requirement = false;
+ base::FileEnumerator enumerator(
+ path,
+ false, /* recursive? */
+ base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES
+#if defined(OS_POSIX)
+ | base::FileEnumerator::SHOW_SYM_LINKS // show symlinks, not follow.
+#endif
+ );
+ while (!enumerator.Next().empty()) {
+ base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
+ base::FilePath full_path = path.Append(file_info.GetName());
+ if (MediaPathFilter::ShouldSkip(full_path))
+ continue;
+
+ if (file_info.IsDirectory()) {
+ new_folders.push_back(full_path);
+ continue;
+ }
+ MediaGalleryScanFileType type = filter_->GetType(full_path);
+ if (type == MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN)
+ continue;
+
+ CountScanResult(type, &scan_result);
+ if (!folder_meets_size_requirement) {
+ folder_meets_size_requirement =
+ FileMeetsSizeRequirement(type, file_info.GetSize());
+ }
+ }
+ // Make sure there is at least 1 file above a size threshold.
+ if (!folder_meets_size_requirement)
+ scan_result = MediaGalleryScanResult();
+ return reply;
+}
+
MediaFolderFinder::MediaFolderFinder(
const MediaFolderFinderResultsCallback& callback)
: results_callback_(callback),
scan_state_(SCAN_STATE_NOT_STARTED),
+ worker_(new Worker()),
has_roots_for_testing_(false),
weak_factory_(this) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
+ worker_task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken());
}
MediaFolderFinder::~MediaFolderFinder() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ worker_task_runner_->DeleteSoon(FROM_HERE, worker_);
+
if (scan_state_ == SCAN_STATE_FINISHED)
return;
@@ -232,8 +258,6 @@ void MediaFolderFinder::SetRootsForTesting(
void MediaFolderFinder::OnInitialized(
const std::vector<base::FilePath>& roots) {
DCHECK_EQ(SCAN_STATE_STARTED, scan_state_);
- DCHECK(!token_.IsValid());
- DCHECK(filter_callback_.is_null());
std::set<base::FilePath> valid_roots;
for (size_t i = 0; i < roots.size(); ++i) {
@@ -268,9 +292,6 @@ void MediaFolderFinder::OnInitialized(
std::copy(valid_roots.begin(), valid_roots.end(),
std::back_inserter(folders_to_scan_));
- token_ = BrowserThread::GetBlockingPool()->GetSequenceToken();
- filter_callback_ = base::Bind(&FilterPath,
- base::Owned(new MediaPathFilter()));
ScanFolder();
}
@@ -284,45 +305,32 @@ void MediaFolderFinder::ScanFolder() {
return;
}
- DCHECK(token_.IsValid());
- DCHECK(!filter_callback_.is_null());
-
base::FilePath folder_to_scan = folders_to_scan_.back();
folders_to_scan_.pop_back();
- MediaGalleryScanResult* scan_result = new MediaGalleryScanResult();
- std::vector<base::FilePath>* new_folders = new std::vector<base::FilePath>();
- scoped_refptr<base::SequencedTaskRunner> task_runner =
- BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(token_);
- task_runner->PostTaskAndReply(
- FROM_HERE,
- base::Bind(&ScanFolderOnBlockingPool,
- folder_to_scan,
- filter_callback_,
- base::Unretained(scan_result),
- base::Unretained(new_folders)),
+ base::PostTaskAndReplyWithResult(
+ worker_task_runner_, FROM_HERE,
+ base::Bind(&Worker::ScanFolder,
+ base::Unretained(worker_),
+ folder_to_scan),
base::Bind(&MediaFolderFinder::GotScanResults,
weak_factory_.GetWeakPtr(),
- folder_to_scan,
- base::Owned(scan_result),
- base::Owned(new_folders)));
+ folder_to_scan));
}
-void MediaFolderFinder::GotScanResults(
- const base::FilePath& path,
- const MediaGalleryScanResult* scan_result,
- const std::vector<base::FilePath>* new_folders) {
+void MediaFolderFinder::GotScanResults(const base::FilePath& path,
+ const WorkerReply& reply) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK_EQ(SCAN_STATE_STARTED, scan_state_);
DCHECK(!path.empty());
- DCHECK(scan_result);
- DCHECK(new_folders);
CHECK(!ContainsKey(results_, path));
- if (!IsEmptyScanResult(*scan_result))
- results_[path] = *scan_result;
+ const MediaGalleryScanResult& scan_result = reply.first;
+ const std::vector<base::FilePath>& new_folders = reply.second;
+ if (!IsEmptyScanResult(scan_result))
+ results_[path] = scan_result;
// Push new folders to the |folders_to_scan_| in reverse order.
- std::copy(new_folders->rbegin(), new_folders->rend(),
+ std::copy(new_folders.rbegin(), new_folders.rend(),
std::back_inserter(folders_to_scan_));
ScanFolder();

Powered by Google App Engine
This is Rietveld 408576698