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

Unified Diff: chrome/browser/media_galleries/fileapi/media_scanner.cc

Issue 149363004: Media Galleries: Initial media scanner implementation. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 6 years, 11 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/fileapi/media_scanner.cc
===================================================================
--- chrome/browser/media_galleries/fileapi/media_scanner.cc (revision 0)
+++ chrome/browser/media_galleries/fileapi/media_scanner.cc (revision 0)
@@ -0,0 +1,165 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/media_galleries/fileapi/media_scanner.h"
+
+#include "base/files/file_enumerator.h"
+#include "base/stl_util.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_worker_pool.h"
vandebo (ex-Chrome) 2014/01/29 18:41:45 nit: you may omit this - in header
Lei Zhang 2014/01/30 00:10:49 Done.
+#include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace {
+
+bool IsValidScanPath(const base::FilePath& path) {
+ return !path.empty() && path.IsAbsolute();
+}
+
+bool IsEmptyScanResult(const MediaGalleryScanResult& scan_result) {
+ return (scan_result.image_count == 0 &&
+ scan_result.audio_count == 0 &&
+ scan_result.video_count == 0);
+}
+
+MediaGalleryScanFileType FilterPath(MediaPathFilter* filter,
+ const base::FilePath& path) {
+ DCHECK(IsValidScanPath(path));
+ return filter->GetType(path);
+}
+
+void DoScanOnBlockingPool(const base::FilePath& path,
+ const MediaScanner::FilterCallback& filter_callback_,
+ std::vector<base::FilePath>* new_folders,
+ MediaGalleryScanResult* scan_result) {
+ DCHECK(IsValidScanPath(path));
+ DCHECK(new_folders);
+ DCHECK(scan_result);
+ DCHECK(IsEmptyScanResult(*scan_result));
+
+ base::FileEnumerator enumerator(
+ path,
+ false, /* recursive? */
+ base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
+ while (!enumerator.Next().empty()) {
+ base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
vandebo (ex-Chrome) 2014/01/29 18:41:45 Feel free to do in a follow up CL, but we want to
Lei Zhang 2014/01/30 00:10:49 Heh, I knew we had more requirements. I'll follow
+ base::FilePath full_path = path.Append(file_info.GetName());
+ if (file_info.IsDirectory()) {
+ new_folders->push_back(full_path);
+ continue;
+ }
+ MediaGalleryScanFileType type = filter_callback_.Run(full_path);
vandebo (ex-Chrome) 2014/01/29 18:41:45 Some types might be audio or video (.ogg ?) Count
Lei Zhang 2014/01/30 00:10:49 Done.
+ switch (type) {
+ case MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE:
+ scan_result->image_count += 1;
+ break;
+ case MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO:
+ scan_result->audio_count += 1;
+ break;
+ case MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO:
+ scan_result->video_count += 1;
+ break;
+ case MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN:
+ break;
+ }
+ }
+}
+
+} // namespace
+
+MediaScanner::MediaScanner(const std::vector<base::FilePath>& roots,
+ const MediaScannerResultsCallback& callback)
+ : callback_(callback),
+ started_scan_(false),
+ weak_factory_(this) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ for (size_t i = 0; i < roots.size(); ++i) {
+ if (!IsValidScanPath(roots[i]))
+ continue;
+ folders_to_scan_.push(roots[i]);
+ }
+}
+
+MediaScanner::~MediaScanner() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
+void MediaScanner::StartScan() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (started_scan_)
+ return;
+
+ DCHECK(!token_.IsValid());
+ DCHECK(filter_callback_.is_null());
+ token_ = BrowserThread::GetBlockingPool()->GetSequenceToken();
+ filter_callback_ = base::Bind(&FilterPath,
+ base::Owned(new MediaPathFilter()));
+ started_scan_ = true;
+ DoScan();
+}
+
+void MediaScanner::CancelScan() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
vandebo (ex-Chrome) 2014/01/29 18:41:45 Looks like you also need to set a bool scan_cancel
Lei Zhang 2014/01/30 00:10:49 I removed CancelScan() and added |scan_state_|.
+ MediaScannerResults empty_results;
+ callback_.Run(false, empty_results);
+}
+
+void MediaScanner::DoScan() {
vandebo (ex-Chrome) 2014/01/29 18:41:45 DoScan -> ScanDirectory ?
Lei Zhang 2014/01/30 00:10:49 Done.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (folders_to_scan_.empty()) {
+ callback_.Run(false, results_);
+ return;
+ }
+
+ DCHECK(token_.IsValid());
+ DCHECK(!filter_callback_.is_null());
+ std::vector<base::FilePath>* new_folders = new std::vector<base::FilePath>();
+ MediaGalleryScanResult* scan_result = new MediaGalleryScanResult();
+ scoped_refptr<base::SequencedTaskRunner> task_runner =
+ BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(token_);
+ task_runner->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&DoScanOnBlockingPool,
+ folders_to_scan_.top(),
+ filter_callback_,
+ base::Unretained(new_folders),
+ base::Unretained(scan_result)),
+ base::Bind(&MediaScanner::GotScanResults,
+ weak_factory_.GetWeakPtr(),
+ folders_to_scan_.top(),
+ base::Owned(new_folders),
+ base::Owned(scan_result)));
+ folders_to_scan_.pop();
vandebo (ex-Chrome) 2014/01/29 18:41:45 nit: easier to reason about if you pop it off befo
Lei Zhang 2014/01/30 00:10:49 Done.
+}
+
+void MediaScanner::GotScanResults(
+ const base::FilePath& path,
+ const std::vector<base::FilePath>* new_folders,
+ const MediaGalleryScanResult* scan_result) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!path.empty());
+ DCHECK(new_folders);
+ DCHECK(scan_result);
+ CHECK(!ContainsKey(results_, path));
+
+ if (!IsEmptyScanResult(*scan_result))
+ results_[path] = *scan_result;
+
+ // Push new folders to the |folders_to_scan_| stack in reverse order.
+ if (!new_folders->empty()) {
+ for (size_t i = new_folders->size(); i > 0; --i) {
+ const base::FilePath& path_to_add = (*new_folders)[i - 1];
+ CHECK(!path_to_add.empty());
+ folders_to_scan_.push(path_to_add);
+ }
+ }
+
+ DoScan();
+}
Property changes on: chrome/browser/media_galleries/fileapi/media_scanner.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698