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

Side by Side 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, 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/media_galleries/fileapi/media_scanner.h"
6
7 #include "base/files/file_enumerator.h"
8 #include "base/stl_util.h"
9 #include "base/task_runner_util.h"
10 #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.
11 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
12 #include "content/public/browser/browser_thread.h"
13
14 using content::BrowserThread;
15
16 namespace {
17
18 bool IsValidScanPath(const base::FilePath& path) {
19 return !path.empty() && path.IsAbsolute();
20 }
21
22 bool IsEmptyScanResult(const MediaGalleryScanResult& scan_result) {
23 return (scan_result.image_count == 0 &&
24 scan_result.audio_count == 0 &&
25 scan_result.video_count == 0);
26 }
27
28 MediaGalleryScanFileType FilterPath(MediaPathFilter* filter,
29 const base::FilePath& path) {
30 DCHECK(IsValidScanPath(path));
31 return filter->GetType(path);
32 }
33
34 void DoScanOnBlockingPool(const base::FilePath& path,
35 const MediaScanner::FilterCallback& filter_callback_,
36 std::vector<base::FilePath>* new_folders,
37 MediaGalleryScanResult* scan_result) {
38 DCHECK(IsValidScanPath(path));
39 DCHECK(new_folders);
40 DCHECK(scan_result);
41 DCHECK(IsEmptyScanResult(*scan_result));
42
43 base::FileEnumerator enumerator(
44 path,
45 false, /* recursive? */
46 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
47 while (!enumerator.Next().empty()) {
48 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
49 base::FilePath full_path = path.Append(file_info.GetName());
50 if (file_info.IsDirectory()) {
51 new_folders->push_back(full_path);
52 continue;
53 }
54 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.
55 switch (type) {
56 case MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE:
57 scan_result->image_count += 1;
58 break;
59 case MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO:
60 scan_result->audio_count += 1;
61 break;
62 case MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO:
63 scan_result->video_count += 1;
64 break;
65 case MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN:
66 break;
67 }
68 }
69 }
70
71 } // namespace
72
73 MediaScanner::MediaScanner(const std::vector<base::FilePath>& roots,
74 const MediaScannerResultsCallback& callback)
75 : callback_(callback),
76 started_scan_(false),
77 weak_factory_(this) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79
80 for (size_t i = 0; i < roots.size(); ++i) {
81 if (!IsValidScanPath(roots[i]))
82 continue;
83 folders_to_scan_.push(roots[i]);
84 }
85 }
86
87 MediaScanner::~MediaScanner() {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89 }
90
91 void MediaScanner::StartScan() {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93
94 if (started_scan_)
95 return;
96
97 DCHECK(!token_.IsValid());
98 DCHECK(filter_callback_.is_null());
99 token_ = BrowserThread::GetBlockingPool()->GetSequenceToken();
100 filter_callback_ = base::Bind(&FilterPath,
101 base::Owned(new MediaPathFilter()));
102 started_scan_ = true;
103 DoScan();
104 }
105
106 void MediaScanner::CancelScan() {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108
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_|.
109 MediaScannerResults empty_results;
110 callback_.Run(false, empty_results);
111 }
112
113 void MediaScanner::DoScan() {
vandebo (ex-Chrome) 2014/01/29 18:41:45 DoScan -> ScanDirectory ?
Lei Zhang 2014/01/30 00:10:49 Done.
114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
115
116 if (folders_to_scan_.empty()) {
117 callback_.Run(false, results_);
118 return;
119 }
120
121 DCHECK(token_.IsValid());
122 DCHECK(!filter_callback_.is_null());
123 std::vector<base::FilePath>* new_folders = new std::vector<base::FilePath>();
124 MediaGalleryScanResult* scan_result = new MediaGalleryScanResult();
125 scoped_refptr<base::SequencedTaskRunner> task_runner =
126 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(token_);
127 task_runner->PostTaskAndReply(
128 FROM_HERE,
129 base::Bind(&DoScanOnBlockingPool,
130 folders_to_scan_.top(),
131 filter_callback_,
132 base::Unretained(new_folders),
133 base::Unretained(scan_result)),
134 base::Bind(&MediaScanner::GotScanResults,
135 weak_factory_.GetWeakPtr(),
136 folders_to_scan_.top(),
137 base::Owned(new_folders),
138 base::Owned(scan_result)));
139 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.
140 }
141
142 void MediaScanner::GotScanResults(
143 const base::FilePath& path,
144 const std::vector<base::FilePath>* new_folders,
145 const MediaGalleryScanResult* scan_result) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
147 DCHECK(!path.empty());
148 DCHECK(new_folders);
149 DCHECK(scan_result);
150 CHECK(!ContainsKey(results_, path));
151
152 if (!IsEmptyScanResult(*scan_result))
153 results_[path] = *scan_result;
154
155 // Push new folders to the |folders_to_scan_| stack in reverse order.
156 if (!new_folders->empty()) {
157 for (size_t i = new_folders->size(); i > 0; --i) {
158 const base::FilePath& path_to_add = (*new_folders)[i - 1];
159 CHECK(!path_to_add.empty());
160 folders_to_scan_.push(path_to_add);
161 }
162 }
163
164 DoScan();
165 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698