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

Side by Side Diff: chrome/browser/media_galleries/media_folder_finder.cc

Issue 173853007: Media Galleries: Prune uninteresting folders when scanning. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: rebase Created 6 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media_galleries/media_folder_finder.h" 5 #include "chrome/browser/media_galleries/media_folder_finder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/file_util.h"
10 #include "base/files/file_enumerator.h" 11 #include "base/files/file_enumerator.h"
11 #include "base/path_service.h" 12 #include "base/path_service.h"
12 #include "base/sequence_checker.h" 13 #include "base/sequence_checker.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
15 #include "base/task_runner_util.h" 16 #include "base/task_runner_util.h"
16 #include "base/threading/sequenced_worker_pool.h" 17 #include "base/threading/sequenced_worker_pool.h"
18 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
17 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h" 19 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
20 #include "chrome/common/chrome_paths.h"
18 #include "components/storage_monitor/storage_monitor.h" 21 #include "components/storage_monitor/storage_monitor.h"
19 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
20 23
21 #if defined(OS_CHROMEOS) 24 #if defined(OS_CHROMEOS)
22 #include "chrome/common/chrome_paths.h" 25 #include "chrome/common/chrome_paths.h"
23 #include "chromeos/dbus/cros_disks_client.h" 26 #include "chromeos/dbus/cros_disks_client.h"
24 #endif 27 #endif
25 28
26 using storage_monitor::StorageInfo; 29 using storage_monitor::StorageInfo;
27 using storage_monitor::StorageMonitor; 30 using storage_monitor::StorageMonitor;
28 31
29 typedef base::Callback<void(const std::vector<base::FilePath>& /*roots*/)> 32 typedef base::Callback<void(const std::vector<base::FilePath>& /*roots*/)>
30 DefaultScanRootsCallback; 33 DefaultScanRootsCallback;
31 using content::BrowserThread; 34 using content::BrowserThread;
32 35
33 namespace { 36 namespace {
34 37
35 const int64 kMinimumImageSize = 200 * 1024; // 200 KB 38 const int64 kMinimumImageSize = 200 * 1024; // 200 KB
36 const int64 kMinimumAudioSize = 500 * 1024; // 500 KB 39 const int64 kMinimumAudioSize = 500 * 1024; // 500 KB
37 const int64 kMinimumVideoSize = 1024 * 1024; // 1 MB 40 const int64 kMinimumVideoSize = 1024 * 1024; // 1 MB
38 41
42 const int kPrunedPaths[] = {
43 #if defined(OS_WIN)
44 base::DIR_IE_INTERNET_CACHE,
45 base::DIR_PROGRAM_FILES,
46 base::DIR_PROGRAM_FILESX86,
47 base::DIR_WINDOWS,
48 #endif
49 #if defined(OS_MACOSX) && !defined(OS_IOS)
50 chrome::DIR_USER_APPLICATIONS,
51 chrome::DIR_USER_LIBRARY,
52 #endif
53 #if defined(OS_LINUX)
54 base::DIR_CACHE,
55 #endif
56 #if defined(OS_WIN) || defined(OS_LINUX)
57 base::DIR_TEMP,
58 #endif
59 };
60
39 bool IsValidScanPath(const base::FilePath& path) { 61 bool IsValidScanPath(const base::FilePath& path) {
40 return !path.empty() && path.IsAbsolute(); 62 return !path.empty() && path.IsAbsolute();
41 } 63 }
42 64
43 void CountScanResult(MediaGalleryScanFileType type, 65 void CountScanResult(MediaGalleryScanFileType type,
44 MediaGalleryScanResult* scan_result) { 66 MediaGalleryScanResult* scan_result) {
45 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE) 67 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE)
46 scan_result->image_count += 1; 68 scan_result->image_count += 1;
47 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO) 69 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO)
48 scan_result->audio_count += 1; 70 scan_result->audio_count += 1;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 } // namespace 165 } // namespace
144 166
145 MediaFolderFinder::WorkerReply::WorkerReply() {} 167 MediaFolderFinder::WorkerReply::WorkerReply() {}
146 168
147 MediaFolderFinder::WorkerReply::~WorkerReply() {} 169 MediaFolderFinder::WorkerReply::~WorkerReply() {}
148 170
149 // The Worker is created on the UI thread, but does all its work on a blocking 171 // The Worker is created on the UI thread, but does all its work on a blocking
150 // SequencedTaskRunner. 172 // SequencedTaskRunner.
151 class MediaFolderFinder::Worker { 173 class MediaFolderFinder::Worker {
152 public: 174 public:
153 Worker(); 175 explicit Worker(const std::vector<base::FilePath>& graylisted_folders);
154 ~Worker(); 176 ~Worker();
155 177
156 // Scans |path| and return the results. 178 // Scans |path| and return the results.
157 WorkerReply ScanFolder(const base::FilePath& path); 179 WorkerReply ScanFolder(const base::FilePath& path);
158 180
159 private: 181 private:
182 void MakeFolderPathsAbsolute();
183
184 bool folder_paths_are_absolute_;
185 std::vector<base::FilePath> graylisted_folders_;
186 std::vector<base::FilePath> pruned_folders_;
187
160 scoped_ptr<MediaPathFilter> filter_; 188 scoped_ptr<MediaPathFilter> filter_;
161 189
162 base::SequenceChecker sequence_checker_; 190 base::SequenceChecker sequence_checker_;
163 191
164 DISALLOW_COPY_AND_ASSIGN(Worker); 192 DISALLOW_COPY_AND_ASSIGN(Worker);
165 }; 193 };
166 194
167 MediaFolderFinder::Worker::Worker() { 195 MediaFolderFinder::Worker::Worker(
196 const std::vector<base::FilePath>& graylisted_folders)
197 : folder_paths_are_absolute_(false),
198 graylisted_folders_(graylisted_folders),
199 filter_(new MediaPathFilter) {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
169 filter_.reset(new MediaPathFilter); 201
202 for (size_t i = 0; i < arraysize(kPrunedPaths); ++i) {
203 base::FilePath path;
204 if (PathService::Get(kPrunedPaths[i], &path))
205 pruned_folders_.push_back(path);
206 }
207
170 sequence_checker_.DetachFromSequence(); 208 sequence_checker_.DetachFromSequence();
171 } 209 }
172 210
173 MediaFolderFinder::Worker::~Worker() { 211 MediaFolderFinder::Worker::~Worker() {
174 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 212 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
175 } 213 }
176 214
177 MediaFolderFinder::WorkerReply MediaFolderFinder::Worker::ScanFolder( 215 MediaFolderFinder::WorkerReply MediaFolderFinder::Worker::ScanFolder(
178 const base::FilePath& path) { 216 const base::FilePath& path) {
179 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 217 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
180 CHECK(IsValidScanPath(path)); 218 CHECK(IsValidScanPath(path));
181 219
220 if (!folder_paths_are_absolute_)
221 MakeFolderPathsAbsolute();
222
182 WorkerReply reply; 223 WorkerReply reply;
183 bool folder_meets_size_requirement = false; 224 bool folder_meets_size_requirement = false;
225 bool is_graylisted_folder = false;
226 base::FilePath abspath = base::MakeAbsoluteFilePath(path);
227 if (abspath.empty())
228 return reply;
229
230 for (size_t i = 0; i < graylisted_folders_.size(); ++i) {
231 if (abspath == graylisted_folders_[i] ||
232 abspath.IsParent(graylisted_folders_[i])) {
233 is_graylisted_folder = true;
234 break;
235 }
236 }
237
184 base::FileEnumerator enumerator( 238 base::FileEnumerator enumerator(
185 path, 239 path,
186 false, /* recursive? */ 240 false, /* recursive? */
187 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES 241 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES
188 #if defined(OS_POSIX) 242 #if defined(OS_POSIX)
189 | base::FileEnumerator::SHOW_SYM_LINKS // show symlinks, not follow. 243 | base::FileEnumerator::SHOW_SYM_LINKS // show symlinks, not follow.
190 #endif 244 #endif
191 ); 245 ); // NOLINT
192 while (!enumerator.Next().empty()) { 246 while (!enumerator.Next().empty()) {
193 base::FileEnumerator::FileInfo file_info = enumerator.GetInfo(); 247 base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
194 base::FilePath full_path = path.Append(file_info.GetName()); 248 base::FilePath full_path = path.Append(file_info.GetName());
195 if (MediaPathFilter::ShouldSkip(full_path)) 249 if (MediaPathFilter::ShouldSkip(full_path))
196 continue; 250 continue;
197 251
252 // Enumerating a directory.
198 if (file_info.IsDirectory()) { 253 if (file_info.IsDirectory()) {
199 reply.new_folders.push_back(full_path); 254 bool is_pruned_folder = false;
255 base::FilePath abs_full_path = base::MakeAbsoluteFilePath(full_path);
256 if (abs_full_path.empty())
257 continue;
258 for (size_t i = 0; i < pruned_folders_.size(); ++i) {
259 if (abs_full_path == pruned_folders_[i]) {
260 is_pruned_folder = true;
261 break;
262 }
263 }
264
265 if (!is_pruned_folder)
266 reply.new_folders.push_back(full_path);
200 continue; 267 continue;
201 } 268 }
269
270 // Enumerating a file.
271 //
272 // Do not include scan results for graylisted folders.
273 if (is_graylisted_folder)
274 continue;
275
202 MediaGalleryScanFileType type = filter_->GetType(full_path); 276 MediaGalleryScanFileType type = filter_->GetType(full_path);
203 if (type == MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN) 277 if (type == MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN)
204 continue; 278 continue;
205 279
206 CountScanResult(type, &reply.scan_result); 280 CountScanResult(type, &reply.scan_result);
207 if (!folder_meets_size_requirement) { 281 if (!folder_meets_size_requirement) {
208 folder_meets_size_requirement = 282 folder_meets_size_requirement =
209 FileMeetsSizeRequirement(type, file_info.GetSize()); 283 FileMeetsSizeRequirement(type, file_info.GetSize());
210 } 284 }
211 } 285 }
212 // Make sure there is at least 1 file above a size threshold. 286 // Make sure there is at least 1 file above a size threshold.
213 if (!folder_meets_size_requirement) 287 if (!folder_meets_size_requirement)
214 reply.scan_result = MediaGalleryScanResult(); 288 reply.scan_result = MediaGalleryScanResult();
215 return reply; 289 return reply;
216 } 290 }
217 291
292 void MediaFolderFinder::Worker::MakeFolderPathsAbsolute() {
293 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
294 DCHECK(!folder_paths_are_absolute_);
295 folder_paths_are_absolute_ = true;
296
297 std::vector<base::FilePath> abs_paths;
298 for (size_t i = 0; i < graylisted_folders_.size(); ++i) {
299 base::FilePath path = base::MakeAbsoluteFilePath(graylisted_folders_[i]);
300 if (!path.empty())
301 abs_paths.push_back(path);
302 }
303 graylisted_folders_ = abs_paths;
304 abs_paths.clear();
305 for (size_t i = 0; i < pruned_folders_.size(); ++i) {
306 base::FilePath path = base::MakeAbsoluteFilePath(pruned_folders_[i]);
307 if (!path.empty())
308 abs_paths.push_back(path);
309 }
310 pruned_folders_ = abs_paths;
311 }
312
218 MediaFolderFinder::MediaFolderFinder( 313 MediaFolderFinder::MediaFolderFinder(
219 const MediaFolderFinderResultsCallback& callback) 314 const MediaFolderFinderResultsCallback& callback)
220 : results_callback_(callback), 315 : results_callback_(callback),
316 graylisted_folders_(
317 extensions::file_system_api::GetGrayListedDirectories()),
221 scan_state_(SCAN_STATE_NOT_STARTED), 318 scan_state_(SCAN_STATE_NOT_STARTED),
222 worker_(new Worker()), 319 worker_(new Worker(graylisted_folders_)),
223 has_roots_for_testing_(false), 320 has_roots_for_testing_(false),
224 weak_factory_(this) { 321 weak_factory_(this) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
226 323
227 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); 324 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
228 worker_task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken()); 325 worker_task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken());
229 } 326 }
230 327
231 MediaFolderFinder::~MediaFolderFinder() { 328 MediaFolderFinder::~MediaFolderFinder() {
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 13 matching lines...) Expand all
246 if (scan_state_ != SCAN_STATE_NOT_STARTED) 343 if (scan_state_ != SCAN_STATE_NOT_STARTED)
247 return; 344 return;
248 345
249 scan_state_ = SCAN_STATE_STARTED; 346 scan_state_ = SCAN_STATE_STARTED;
250 GetDefaultScanRoots( 347 GetDefaultScanRoots(
251 base::Bind(&MediaFolderFinder::OnInitialized, weak_factory_.GetWeakPtr()), 348 base::Bind(&MediaFolderFinder::OnInitialized, weak_factory_.GetWeakPtr()),
252 has_roots_for_testing_, 349 has_roots_for_testing_,
253 roots_for_testing_); 350 roots_for_testing_);
254 } 351 }
255 352
353 const std::vector<base::FilePath>&
354 MediaFolderFinder::graylisted_folders() const {
355 return graylisted_folders_;
356 }
357
256 void MediaFolderFinder::SetRootsForTesting( 358 void MediaFolderFinder::SetRootsForTesting(
257 const std::vector<base::FilePath>& roots) { 359 const std::vector<base::FilePath>& roots) {
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
259 DCHECK_EQ(SCAN_STATE_NOT_STARTED, scan_state_); 361 DCHECK_EQ(SCAN_STATE_NOT_STARTED, scan_state_);
260 362
261 has_roots_for_testing_ = true; 363 has_roots_for_testing_ = true;
262 roots_for_testing_ = roots; 364 roots_for_testing_ = roots;
263 } 365 }
264 366
265 void MediaFolderFinder::OnInitialized( 367 void MediaFolderFinder::OnInitialized(
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 435
334 if (!IsEmptyScanResult(reply.scan_result)) 436 if (!IsEmptyScanResult(reply.scan_result))
335 results_[path] = reply.scan_result; 437 results_[path] = reply.scan_result;
336 438
337 // Push new folders to the |folders_to_scan_| in reverse order. 439 // Push new folders to the |folders_to_scan_| in reverse order.
338 std::copy(reply.new_folders.rbegin(), reply.new_folders.rend(), 440 std::copy(reply.new_folders.rbegin(), reply.new_folders.rend(),
339 std::back_inserter(folders_to_scan_)); 441 std::back_inserter(folders_to_scan_));
340 442
341 ScanFolder(); 443 ScanFolder();
342 } 444 }
OLDNEW
« no previous file with comments | « chrome/browser/media_galleries/media_folder_finder.h ('k') | chrome/browser/media_galleries/media_folder_finder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698