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

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

Issue 149363004: Media Galleries: Initial media scanner implementation. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: with test 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/media_folder_finder.h"
6
7 #include "base/files/file_enumerator.h"
8 #include "base/stl_util.h"
9 #include "base/task_runner_util.h"
10 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
11 #include "content/public/browser/browser_thread.h"
12
13 using content::BrowserThread;
14
15 namespace {
16
17 bool IsValidScanPath(const base::FilePath& path) {
18 return !path.empty() && path.IsAbsolute();
19 }
20
21 MediaGalleryScanFileType FilterPath(MediaPathFilter* filter,
22 const base::FilePath& path) {
23 DCHECK(IsValidScanPath(path));
24 return filter->GetType(path);
25 }
26
27 void ScanFolderOnBlockingPool(
28 const base::FilePath& path,
29 const MediaFolderFinder::FilterCallback& filter_callback_,
30 MediaGalleryScanResult* scan_result,
31 std::vector<base::FilePath>* new_folders) {
32 CHECK(IsValidScanPath(path));
33 DCHECK(scan_result);
34 DCHECK(new_folders);
35 DCHECK(IsEmptyScanResult(*scan_result));
36
37 base::FileEnumerator enumerator(
38 path,
39 false, /* recursive? */
40 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
41 while (!enumerator.Next().empty()) {
42 base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
43 base::FilePath full_path = path.Append(file_info.GetName());
44 if (file_info.IsDirectory()) {
45 new_folders->push_back(full_path);
46 continue;
47 }
48 // TODO(thestig) Make sure there is at least 1 file above a size threshold:
49 // images >= 200KB, videos >= 1MB, music >= 500KB.
50 MediaGalleryScanFileType type = filter_callback_.Run(full_path);
51 if (type == MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN)
52 continue;
53
54 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE)
55 scan_result->image_count += 1;
56 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO)
57 scan_result->audio_count += 1;
58 if (type & MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO)
59 scan_result->video_count += 1;
60 }
61 }
62
63 } // namespace
64
65 MediaFolderFinder::MediaFolderFinder(
66 const std::vector<base::FilePath>& roots,
67 const MediaFolderFinderResultsCallback& callback)
68 : results_callback_(callback),
69 scan_state_(SCAN_STATE_NOT_STARTED),
70 weak_factory_(this) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72
73 for (size_t i = 0; i < roots.size(); ++i) {
74 const base::FilePath& path = roots[i];
75 if (!IsValidScanPath(path))
76 continue;
77 // TODO(thestig) Check |path| for overlap with the rest of |roots|.
78 folders_to_scan_.push(path);
79 }
80 }
81
82 MediaFolderFinder::~MediaFolderFinder() {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84 if (scan_state_ == SCAN_STATE_FINISHED)
85 return;
86
87 MediaFolderFinderResults empty_results;
88 results_callback_.Run(false /* success? */, empty_results);
89 }
90
91 void MediaFolderFinder::StartScan() {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93
94 if (scan_state_ != SCAN_STATE_NOT_STARTED)
95 return;
96 scan_state_ = SCAN_STATE_STARTED;
97
98 DCHECK(!token_.IsValid());
99 DCHECK(filter_callback_.is_null());
100 token_ = BrowserThread::GetBlockingPool()->GetSequenceToken();
101 filter_callback_ = base::Bind(&FilterPath,
102 base::Owned(new MediaPathFilter()));
103 ScanFolder();
104 }
105
106 void MediaFolderFinder::ScanFolder() {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108 DCHECK_EQ(SCAN_STATE_STARTED, scan_state_);
109
110 if (folders_to_scan_.empty()) {
111 scan_state_ = SCAN_STATE_FINISHED;
112 results_callback_.Run(true /* success? */, results_);
113 return;
114 }
115
116 DCHECK(token_.IsValid());
117 DCHECK(!filter_callback_.is_null());
118
119 base::FilePath folder_to_scan = folders_to_scan_.top();
120 folders_to_scan_.pop();
121 MediaGalleryScanResult* scan_result = new MediaGalleryScanResult();
122 std::vector<base::FilePath>* new_folders = new std::vector<base::FilePath>();
123 scoped_refptr<base::SequencedTaskRunner> task_runner =
124 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(token_);
125 task_runner->PostTaskAndReply(
126 FROM_HERE,
127 base::Bind(&ScanFolderOnBlockingPool,
128 folder_to_scan,
129 filter_callback_,
130 base::Unretained(scan_result),
131 base::Unretained(new_folders)),
132 base::Bind(&MediaFolderFinder::GotScanResults,
133 weak_factory_.GetWeakPtr(),
134 folder_to_scan,
135 base::Owned(scan_result),
136 base::Owned(new_folders)));
137 }
138
139 void MediaFolderFinder::GotScanResults(
140 const base::FilePath& path,
141 const MediaGalleryScanResult* scan_result,
142 const std::vector<base::FilePath>* new_folders) {
143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
144 DCHECK_EQ(SCAN_STATE_STARTED, scan_state_);
145 DCHECK(!path.empty());
146 DCHECK(scan_result);
147 DCHECK(new_folders);
148 CHECK(!ContainsKey(results_, path));
149
150 if (!IsEmptyScanResult(*scan_result))
151 results_[path] = *scan_result;
152
153 // Push new folders to the |folders_to_scan_| stack in reverse order.
154 for (size_t i = new_folders->size(); i > 0; --i) {
155 const base::FilePath& path_to_add = (*new_folders)[i - 1];
156 folders_to_scan_.push(path_to_add);
157 }
158
159 ScanFolder();
160 }
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