OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/fileapi/itunes_data_provider.h" | 5 #include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/platform_file.h" | 14 #include "base/platform_file.h" |
15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 18 #include "chrome/browser/media_galleries/fileapi/data_provider_helper.h" |
18 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" | 19 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" |
19 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" | 20 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" |
20 #include "chrome/common/media_galleries/itunes_library.h" | 21 #include "chrome/common/media_galleries/itunes_library.h" |
21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
22 #include "third_party/icu/source/common/unicode/locid.h" | 23 #include "third_party/icu/source/common/unicode/locid.h" |
23 #include "webkit/browser/fileapi/native_file_util.h" | 24 #include "webkit/browser/fileapi/native_file_util.h" |
24 | 25 |
25 using chrome::MediaFileSystemBackend; | 26 using chrome::MediaFileSystemBackend; |
26 | 27 |
27 namespace itunes { | 28 namespace itunes { |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 typedef base::Callback<void(scoped_ptr<base::FilePathWatcher> watcher)> | |
32 FileWatchStartedCallback; | |
33 | |
34 ITunesDataProvider::Album MakeUniqueTrackNames(const parser::Album& album) { | 32 ITunesDataProvider::Album MakeUniqueTrackNames(const parser::Album& album) { |
35 // TODO(vandebo): It would be nice to ensure that names returned from here | 33 // TODO(vandebo): It would be nice to ensure that names returned from here |
36 // are stable, but aside from persisting every name returned, it's not | 34 // are stable, but aside from persisting every name returned, it's not |
37 // obvious how to do that (without including the track id in every name). | 35 // obvious how to do that (without including the track id in every name). |
38 typedef std::set<const parser::Track*> TrackRefs; | 36 typedef std::set<const parser::Track*> TrackRefs; |
39 typedef std::map<ITunesDataProvider::TrackName, TrackRefs> AlbumInfo; | 37 typedef std::map<ITunesDataProvider::TrackName, TrackRefs> AlbumInfo; |
40 | 38 |
41 ITunesDataProvider::Album result; | 39 ITunesDataProvider::Album result; |
42 AlbumInfo duped_tracks; | 40 AlbumInfo duped_tracks; |
43 | 41 |
(...skipping 19 matching lines...) Expand all Loading... |
63 base::FilePath unique_name = | 61 base::FilePath unique_name = |
64 (*track_it)->location.BaseName().InsertBeforeExtensionASCII(id); | 62 (*track_it)->location.BaseName().InsertBeforeExtensionASCII(id); |
65 result[unique_name.AsUTF8Unsafe()] = (*track_it)->location; | 63 result[unique_name.AsUTF8Unsafe()] = (*track_it)->location; |
66 } | 64 } |
67 } | 65 } |
68 } | 66 } |
69 | 67 |
70 return result; | 68 return result; |
71 } | 69 } |
72 | 70 |
73 // Bounces |path| and |error| to |callback| from the FILE thread to the media | |
74 // task runner. | |
75 void OnLibraryChanged(const base::FilePathWatcher::Callback& callback, | |
76 const base::FilePath& path, | |
77 bool error) { | |
78 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
79 MediaFileSystemBackend::MediaTaskRunner()->PostTask( | |
80 FROM_HERE, base::Bind(callback, path, error)); | |
81 } | |
82 | |
83 // The watch has to be started on the FILE thread, and the callback called by | |
84 // the FilePathWatcher also needs to run on the FILE thread. | |
85 void StartLibraryWatchOnFileThread( | |
86 const base::FilePath& library_path, | |
87 const FileWatchStartedCallback& watch_started_callback, | |
88 const base::FilePathWatcher::Callback& library_changed_callback) { | |
89 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
90 // The watcher is created on the FILE thread because it is very difficult | |
91 // to safely pass an already-created member to a different thread. | |
92 scoped_ptr<base::FilePathWatcher> watcher(new base::FilePathWatcher); | |
93 bool success = watcher->Watch( | |
94 library_path, false /*recursive*/, | |
95 base::Bind(&OnLibraryChanged, library_changed_callback)); | |
96 if (!success) | |
97 LOG(ERROR) << "Adding watch for " << library_path.value() << " failed"; | |
98 MediaFileSystemBackend::MediaTaskRunner()->PostTask( | |
99 FROM_HERE, | |
100 base::Bind(watch_started_callback, base::Passed(&watcher))); | |
101 } | |
102 | |
103 // |result_path| is set if |locale_string| maps to a localized directory name | 71 // |result_path| is set if |locale_string| maps to a localized directory name |
104 // and it exists in the filesystem. | 72 // and it exists in the filesystem. |
105 bool CheckLocaleStringAutoAddPath( | 73 bool CheckLocaleStringAutoAddPath( |
106 const base::FilePath& media_path, | 74 const base::FilePath& media_path, |
107 const std::map<std::string, std::string>& localized_dir_names, | 75 const std::map<std::string, std::string>& localized_dir_names, |
108 const std::string& locale_string, | 76 const std::string& locale_string, |
109 base::FilePath* result_path) { | 77 base::FilePath* result_path) { |
110 DCHECK(!media_path.empty()); | 78 DCHECK(!media_path.empty()); |
111 DCHECK(!localized_dir_names.empty()); | 79 DCHECK(!localized_dir_names.empty()); |
112 DCHECK(!locale_string.empty()); | 80 DCHECK(!locale_string.empty()); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 | 169 |
202 ITunesDataProvider::ITunesDataProvider(const base::FilePath& library_path) | 170 ITunesDataProvider::ITunesDataProvider(const base::FilePath& library_path) |
203 : library_path_(library_path), | 171 : library_path_(library_path), |
204 auto_add_path_(GetAutoAddPath(library_path)), | 172 auto_add_path_(GetAutoAddPath(library_path)), |
205 needs_refresh_(true), | 173 needs_refresh_(true), |
206 is_valid_(false), | 174 is_valid_(false), |
207 weak_factory_(this) { | 175 weak_factory_(this) { |
208 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | 176 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); |
209 DCHECK(!library_path_.empty()); | 177 DCHECK(!library_path_.empty()); |
210 | 178 |
211 content::BrowserThread::PostTask( | 179 chrome::StartFilePathWatchOnMediaTaskRunner( |
212 content::BrowserThread::FILE, | 180 library_path_, |
213 FROM_HERE, | 181 false /* recursive */, |
214 base::Bind(StartLibraryWatchOnFileThread, | 182 base::Bind(&ITunesDataProvider::OnLibraryWatchStarted, |
215 library_path_, | 183 weak_factory_.GetWeakPtr()), |
216 base::Bind(&ITunesDataProvider::OnLibraryWatchStarted, | 184 base::Bind(&ITunesDataProvider::OnLibraryChanged, |
217 weak_factory_.GetWeakPtr()), | 185 weak_factory_.GetWeakPtr())); |
218 base::Bind(&ITunesDataProvider::OnLibraryChanged, | |
219 weak_factory_.GetWeakPtr()))); | |
220 } | 186 } |
221 | 187 |
222 ITunesDataProvider::~ITunesDataProvider() {} | 188 ITunesDataProvider::~ITunesDataProvider() {} |
223 | 189 |
224 // TODO(vandebo): add a file watch that resets |needs_refresh_| when the | 190 // TODO(vandebo): add a file watch that resets |needs_refresh_| when the |
225 // file changes. | 191 // file changes. |
226 void ITunesDataProvider::RefreshData(const ReadyCallback& ready_callback) { | 192 void ITunesDataProvider::RefreshData(const ReadyCallback& ready_callback) { |
227 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | 193 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); |
228 if (!needs_refresh_) { | 194 if (!needs_refresh_) { |
229 ready_callback.Run(is_valid_); | 195 ready_callback.Run(is_valid_); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 ++album_it) { | 321 ++album_it) { |
356 library_[artist_it->first][album_it->first] = | 322 library_[artist_it->first][album_it->first] = |
357 MakeUniqueTrackNames(album_it->second); | 323 MakeUniqueTrackNames(album_it->second); |
358 } | 324 } |
359 } | 325 } |
360 } | 326 } |
361 ready_callback.Run(is_valid_); | 327 ready_callback.Run(is_valid_); |
362 } | 328 } |
363 | 329 |
364 } // namespace itunes | 330 } // namespace itunes |
OLD | NEW |