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

Side by Side Diff: chrome/browser/chromeos/arc/arc_downloads_watcher_service.cc

Issue 2379323002: arc: Exclude non-media files from Android media scanning. (Closed)
Patch Set: Addressed comments. Created 4 years, 2 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/chromeos/arc/arc_downloads_watcher_service.h" 5 #include "chrome/browser/chromeos/arc/arc_downloads_watcher_service.h"
6 6
7 #include <algorithm>
8 #include <iterator>
7 #include <map> 9 #include <map>
8 #include <memory> 10 #include <memory>
9 #include <utility> 11 #include <utility>
10 12
Yusuke Sato 2016/10/03 16:54:54 IWYU: #include <string.h> ?
Shuhei Takahashi 2016/10/04 03:48:12 Done.
11 #include "base/callback.h" 13 #include "base/callback.h"
12 #include "base/files/file_enumerator.h" 14 #include "base/files/file_enumerator.h"
13 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
14 #include "base/files/file_path_watcher.h" 16 #include "base/files/file_path_watcher.h"
15 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
18 #include "base/strings/string_util.h"
16 #include "base/time/time.h" 19 #include "base/time/time.h"
17 #include "chrome/browser/download/download_prefs.h" 20 #include "chrome/browser/download/download_prefs.h"
18 #include "chrome/browser/profiles/profile_manager.h" 21 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/chrome_paths.h" 22 #include "chrome/common/chrome_paths.h"
20 #include "components/arc/arc_bridge_service.h" 23 #include "components/arc/arc_bridge_service.h"
21 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
22 #include "mojo/public/cpp/bindings/array.h" 25 #include "mojo/public/cpp/bindings/array.h"
23 26
24 using content::BrowserThread; 27 using content::BrowserThread;
25 28
26 // Mapping from Android file paths to last modified timestamps. 29 // Mapping from Android file paths to last modified timestamps.
27 using TimestampMap = std::map<base::FilePath, base::Time>; 30 using TimestampMap = std::map<base::FilePath, base::Time>;
28 31
29 namespace arc { 32 namespace arc {
30 33
31 namespace { 34 namespace {
32 35
33 const base::FilePath::CharType kAndroidDownloadDir[] = 36 const base::FilePath::CharType kAndroidDownloadDir[] =
34 FILE_PATH_LITERAL("/storage/emulated/0/Download"); 37 FILE_PATH_LITERAL("/storage/emulated/0/Download");
35 38
36 // How long to wait for new inotify events before building the updated timestamp 39 // How long to wait for new inotify events before building the updated timestamp
37 // map. 40 // map.
38 const base::TimeDelta kBuildTimestampMapDelay = 41 const base::TimeDelta kBuildTimestampMapDelay =
39 base::TimeDelta::FromMilliseconds(1000); 42 base::TimeDelta::FromMilliseconds(1000);
40 43
44 // The set of media file extensions supported by Android MediaScanner.
45 // Entries must be lower-case and sorted by lexicographical order for
46 // binary search.
47 // The current list was taken from aosp-marshmallow version of
48 // frameworks/base/media/java/android/media/MediaFile.java.
49 const char* kAndroidSupportedMediaExtensions[] = {
50 ".3g2", // FILE_TYPE_3GPP2, video/3gpp2
51 ".3gp", // FILE_TYPE_3GPP, video/3gpp
52 ".3gpp", // FILE_TYPE_3GPP, video/3gpp
53 ".3gpp2", // FILE_TYPE_3GPP2, video/3gpp2
54 ".aac", // FILE_TYPE_AAC, audio/aac, audio/aac-adts
55 ".amr", // FILE_TYPE_AMR, audio/amr
56 ".asf", // FILE_TYPE_ASF, video/x-ms-asf
57 ".avi", // FILE_TYPE_AVI, video/avi
58 ".awb", // FILE_TYPE_AWB, audio/amr-wb
59 ".bmp", // FILE_TYPE_BMP, image/x-ms-bmp
60 ".fl", // FILE_TYPE_FL, application/x-android-drm-fl
61 ".gif", // FILE_TYPE_GIF, image/gif
62 ".imy", // FILE_TYPE_IMY, audio/imelody
63 ".jpeg", // FILE_TYPE_JPEG, image/jpeg
64 ".jpg", // FILE_TYPE_JPEG, image/jpeg
65 ".m4a", // FILE_TYPE_M4A, audio/mp4
66 ".m4v", // FILE_TYPE_M4V, video/mp4
67 ".mid", // FILE_TYPE_MID, audio/midi
68 ".midi", // FILE_TYPE_MID, audio/midi
69 ".mka", // FILE_TYPE_MKA, audio/x-matroska
70 ".mkv", // FILE_TYPE_MKV, video/x-matroska
71 ".mp3", // FILE_TYPE_MP3, audio/mpeg
72 ".mp4", // FILE_TYPE_MP4, video/mp4
73 ".mpeg", // FILE_TYPE_MP4, video/mpeg, video/mp2p
74 ".mpg", // FILE_TYPE_MP4, video/mpeg, video/mp2p
75 ".mpga", // FILE_TYPE_MP3, audio/mpeg
76 ".mxmf", // FILE_TYPE_MID, audio/midi
77 ".oga", // FILE_TYPE_OGG, application/ogg
78 ".ogg", // FILE_TYPE_OGG, audio/ogg, application/ogg
79 ".ota", // FILE_TYPE_MID, audio/midi
80 ".png", // FILE_TYPE_PNG, image/png
81 ".rtttl", // FILE_TYPE_MID, audio/midi
82 ".rtx", // FILE_TYPE_MID, audio/midi
83 ".smf", // FILE_TYPE_SMF, audio/sp-midi
84 ".ts", // FILE_TYPE_MP2TS, video/mp2ts
85 ".wav", // FILE_TYPE_WAV, audio/x-wav
86 ".wbmp", // FILE_TYPE_WBMP, image/vnd.wap.wbmp
87 ".webm", // FILE_TYPE_WEBM, video/webm
88 ".webp", // FILE_TYPE_WEBP, image/webp
89 ".wma", // FILE_TYPE_WMA, audio/x-ms-wma
90 ".wmv", // FILE_TYPE_WMV, video/x-ms-wmv
91 ".xmf", // FILE_TYPE_MID, audio/midi
92 };
93
41 // Compares two TimestampMaps and returns the list of file paths added/removed 94 // Compares two TimestampMaps and returns the list of file paths added/removed
42 // or whose timestamp have changed. 95 // or whose timestamp have changed.
43 std::vector<base::FilePath> CollectChangedPaths( 96 std::vector<base::FilePath> CollectChangedPaths(
44 const TimestampMap& timestamp_map_a, 97 const TimestampMap& timestamp_map_a,
45 const TimestampMap& timestamp_map_b) { 98 const TimestampMap& timestamp_map_b) {
46 std::vector<base::FilePath> changed_paths; 99 std::vector<base::FilePath> changed_paths;
47 100
48 TimestampMap::const_iterator iter_a = timestamp_map_a.begin(); 101 TimestampMap::const_iterator iter_a = timestamp_map_a.begin();
49 TimestampMap::const_iterator iter_b = timestamp_map_b.begin(); 102 TimestampMap::const_iterator iter_b = timestamp_map_b.begin();
50 while (iter_a != timestamp_map_a.end() && iter_b != timestamp_map_b.end()) { 103 while (iter_a != timestamp_map_a.end() && iter_b != timestamp_map_b.end()) {
(...skipping 28 matching lines...) Expand all
79 // paths (in Android filesystem) to last modified timestamps. 132 // paths (in Android filesystem) to last modified timestamps.
80 TimestampMap BuildTimestampMap(base::FilePath downloads_dir) { 133 TimestampMap BuildTimestampMap(base::FilePath downloads_dir) {
81 DCHECK(!downloads_dir.EndsWithSeparator()); 134 DCHECK(!downloads_dir.EndsWithSeparator());
82 TimestampMap timestamp_map; 135 TimestampMap timestamp_map;
83 136
84 // Enumerate normal files only; directories and symlinks are skipped. 137 // Enumerate normal files only; directories and symlinks are skipped.
85 base::FileEnumerator enumerator(downloads_dir, true, 138 base::FileEnumerator enumerator(downloads_dir, true,
86 base::FileEnumerator::FILES); 139 base::FileEnumerator::FILES);
87 for (base::FilePath cros_path = enumerator.Next(); !cros_path.empty(); 140 for (base::FilePath cros_path = enumerator.Next(); !cros_path.empty();
88 cros_path = enumerator.Next()) { 141 cros_path = enumerator.Next()) {
142 // Skip non-media files for efficiency.
143 if (!HasAndroidSupportedMediaExtension(cros_path))
144 continue;
89 // Android file path can be obtained by replacing |downloads_dir| prefix 145 // Android file path can be obtained by replacing |downloads_dir| prefix
90 // with |kAndroidDownloadDir|. 146 // with |kAndroidDownloadDir|.
91 base::FilePath android_path(kAndroidDownloadDir); 147 base::FilePath android_path(kAndroidDownloadDir);
92 downloads_dir.AppendRelativePath(cros_path, &android_path); 148 downloads_dir.AppendRelativePath(cros_path, &android_path);
93 const base::FileEnumerator::FileInfo& info = enumerator.GetInfo(); 149 const base::FileEnumerator::FileInfo& info = enumerator.GetInfo();
94 timestamp_map[android_path] = info.GetLastModifiedTime(); 150 timestamp_map[android_path] = info.GetLastModifiedTime();
95 } 151 }
96 return timestamp_map; 152 return timestamp_map;
97 } 153 }
98 154
99 std::pair<base::TimeTicks, TimestampMap> BuildTimestampMapCallback( 155 std::pair<base::TimeTicks, TimestampMap> BuildTimestampMapCallback(
100 base::FilePath downloads_dir) { 156 base::FilePath downloads_dir) {
101 // The TimestampMap may include changes form after snapshot_time. 157 // The TimestampMap may include changes form after snapshot_time.
102 // We must take the snapshot_time before we build the TimestampMap since 158 // We must take the snapshot_time before we build the TimestampMap since
103 // changes that occur while building the map may not be captured. 159 // changes that occur while building the map may not be captured.
104 base::TimeTicks snapshot_time = base::TimeTicks::Now(); 160 base::TimeTicks snapshot_time = base::TimeTicks::Now();
105 TimestampMap current_timestamp_map = BuildTimestampMap(downloads_dir); 161 TimestampMap current_timestamp_map = BuildTimestampMap(downloads_dir);
106 return std::make_pair(snapshot_time, std::move(current_timestamp_map)); 162 return std::make_pair(snapshot_time, std::move(current_timestamp_map));
107 } 163 }
108 164
109 } // namespace 165 } // namespace
110 166
167 bool HasAndroidSupportedMediaExtension(const base::FilePath& path) {
168 const std::string extension = base::ToLowerASCII(path.Extension());
169 const auto less_comparator = [](const char* a, const char* b) {
170 return strcmp(a, b) < 0;
171 };
172 DCHECK(std::is_sorted(std::begin(kAndroidSupportedMediaExtensions),
173 std::end(kAndroidSupportedMediaExtensions),
174 less_comparator));
175 auto iter = std::lower_bound(std::begin(kAndroidSupportedMediaExtensions),
176 std::end(kAndroidSupportedMediaExtensions),
177 extension.c_str(), less_comparator);
178 return iter != std::end(kAndroidSupportedMediaExtensions) &&
179 strcmp(*iter, extension.c_str()) == 0;
Yusuke Sato 2016/10/03 16:54:54 Can you run git cl format if you haven't?
Shuhei Takahashi 2016/10/04 03:48:12 Actually this is the result of git cl format.
180 }
181
111 // The core part of ArcDownloadsWatcherService to watch for file changes in 182 // The core part of ArcDownloadsWatcherService to watch for file changes in
112 // Downloads directory. 183 // Downloads directory.
113 class ArcDownloadsWatcherService::DownloadsWatcher { 184 class ArcDownloadsWatcherService::DownloadsWatcher {
114 public: 185 public:
115 using Callback = base::Callback<void(mojo::Array<mojo::String> paths)>; 186 using Callback = base::Callback<void(mojo::Array<mojo::String> paths)>;
116 187
117 explicit DownloadsWatcher(const Callback& callback); 188 explicit DownloadsWatcher(const Callback& callback);
118 ~DownloadsWatcher(); 189 ~DownloadsWatcher();
119 190
120 // Starts watching Downloads directory. 191 // Starts watching Downloads directory.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 DCHECK_CURRENTLY_ON(BrowserThread::UI); 360 DCHECK_CURRENTLY_ON(BrowserThread::UI);
290 361
291 auto* instance = arc_bridge_service()->file_system()->GetInstanceForMethod( 362 auto* instance = arc_bridge_service()->file_system()->GetInstanceForMethod(
292 "RequestMediaScan"); 363 "RequestMediaScan");
293 if (!instance) 364 if (!instance)
294 return; 365 return;
295 instance->RequestMediaScan(std::move(paths)); 366 instance->RequestMediaScan(std::move(paths));
296 } 367 }
297 368
298 } // namespace arc 369 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698