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

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

Powered by Google App Engine
This is Rietveld 408576698