[Media Router] Add integration tests and e2e tests for media router and presentation...
[chromium-blink-merge.git] / chrome / browser / media_galleries / media_galleries_preferences.h
blobc60c75ab2d5e060f91867f557ef2722cd53dae30
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_
6 #define CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
13 #include "base/basictypes.h"
14 #include "base/callback_forward.h"
15 #include "base/files/file_path.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/observer_list.h"
18 #include "base/strings/string16.h"
19 #include "base/time/time.h"
20 #include "components/keyed_service/core/keyed_service.h"
21 #include "components/storage_monitor/removable_storage_observer.h"
23 class Profile;
25 namespace base {
26 class DictionaryValue;
29 namespace extensions {
30 class Extension;
31 class ExtensionPrefs;
34 namespace user_prefs {
35 class PrefRegistrySyncable;
38 typedef uint64 MediaGalleryPrefId;
39 const MediaGalleryPrefId kInvalidMediaGalleryPrefId = 0;
41 const char kMediaGalleriesPrefsVersionKey[] = "preferencesVersion";
42 const char kMediaGalleriesDefaultGalleryTypeKey[] = "defaultGalleryType";
44 struct MediaGalleryPermission {
45 MediaGalleryPrefId pref_id;
46 bool has_permission;
49 struct MediaGalleryPrefInfo {
50 enum Type {
51 kUserAdded, // Explicitly added by the user.
52 kAutoDetected, // Auto added to the list of galleries.
53 kBlackListed, // Auto added but then removed by the user.
54 kScanResult, // Discovered by a disk scan.
55 kRemovedScan, // Discovered by a disk scan but then removed by the user.
56 kInvalidType,
59 enum DefaultGalleryType {
60 kNotDefault, // Normal gallery
61 kMusicDefault,
62 kPicturesDefault,
63 kVideosDefault,
66 MediaGalleryPrefInfo();
67 ~MediaGalleryPrefInfo();
69 // The absolute path of the gallery.
70 base::FilePath AbsolutePath() const;
72 // True if the gallery should not be displayed to the user
73 // i.e. kBlackListed || kRemovedScan.
74 bool IsBlackListedType() const;
76 // The ID that identifies this gallery in this Profile.
77 MediaGalleryPrefId pref_id;
79 // The user-visible name of this gallery.
80 base::string16 display_name;
82 // A string which uniquely and persistently identifies the device that the
83 // gallery lives on.
84 std::string device_id;
86 // The root of the gallery, relative to the root of the device.
87 base::FilePath path;
89 // The type of gallery.
90 Type type;
92 // The volume label of the volume/device on which the gallery
93 // resides. Empty if there is no such label or it is unknown.
94 base::string16 volume_label;
96 // Vendor name for the volume/device on which the gallery is located.
97 // Will be empty if unknown.
98 base::string16 vendor_name;
100 // Model name for the volume/device on which the gallery is located.
101 // Will be empty if unknown.
102 base::string16 model_name;
104 // The capacity in bytes of the volume/device on which the gallery is
105 // located. Will be zero if unknown.
106 uint64 total_size_in_bytes;
108 // If the gallery is on a removable device, the time that device was last
109 // attached. It is stored in preferences by the base::Time internal value,
110 // which is microseconds since the epoch.
111 base::Time last_attach_time;
113 // Set to true if the volume metadata fields (volume_label, vendor_name,
114 // model_name, total_size_in_bytes) were set. False if these fields were
115 // never written.
116 bool volume_metadata_valid;
118 // The following fields are populated with the audio, image, and video file
119 // counts from the last scan. For files where it is hard to determine the
120 // exact type, the file should be counted in all possible counts.
121 int audio_count;
122 int image_count;
123 int video_count;
125 // Which default gallery this corresponds to (or not default at all).
126 DefaultGalleryType default_gallery_type;
128 // 0 if the display_name is set externally and always used for display.
129 // 1 if the display_name is only set externally when it is overriding
130 // the name constructed from volume metadata.
131 // 2 if the display_name is set in a consistent manner that has resolved
132 // the issues in earlier versions.
133 // 3 if the default_gallery_type is set (new field for this version).
134 int prefs_version;
136 // Called by views to provide details for the gallery permission entries.
137 base::string16 GetGalleryDisplayName() const;
138 base::string16 GetGalleryTooltip() const;
139 base::string16 GetGalleryAdditionalDetails() const;
141 // Returns true if the gallery is currently a removable device gallery which
142 // is now attached, or a fixed storage gallery.
143 bool IsGalleryAvailable() const;
146 typedef std::map<MediaGalleryPrefId, MediaGalleryPrefInfo>
147 MediaGalleriesPrefInfoMap;
148 typedef std::set<MediaGalleryPrefId> MediaGalleryPrefIdSet;
150 // A class to manage the media gallery preferences. There is one instance per
151 // user profile. This class lives on the UI thread.
152 class MediaGalleriesPreferences
153 : public KeyedService,
154 public storage_monitor::RemovableStorageObserver {
155 public:
156 class GalleryChangeObserver {
157 public:
158 // |extension_id| specifies the extension affected by this change.
159 // |pref_id| refers to the gallery.
160 virtual void OnPermissionAdded(MediaGalleriesPreferences* pref,
161 const std::string& extension_id,
162 MediaGalleryPrefId pref_id) {}
164 virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
165 const std::string& extension_id,
166 MediaGalleryPrefId pref_id) {}
168 virtual void OnGalleryAdded(MediaGalleriesPreferences* pref,
169 MediaGalleryPrefId pref_id) {}
171 virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
172 MediaGalleryPrefId pref_id) {}
174 virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
175 MediaGalleryPrefId pref_id) {}
177 protected:
178 virtual ~GalleryChangeObserver();
181 explicit MediaGalleriesPreferences(Profile* profile);
182 ~MediaGalleriesPreferences() override;
184 // Ensures that the preferences is initialized. The provided callback, if
185 // non-null, will be called when initialization is complete. If initialization
186 // has already completed, this callback will be invoked in the calling stack.
187 // Before the callback is run, other calls may not return the correct results.
188 // Should be invoked on the UI thread; callbacks will be run on the UI thread.
189 // This call also ensures that the StorageMonitor is initialized.
190 // Note for unit tests: This requires an active FILE thread and
191 // EnsureMediaDirectoriesExists instance to complete reliably.
192 void EnsureInitialized(base::Closure callback);
194 // Return true if the storage monitor has already been initialized.
195 bool IsInitialized() const;
197 Profile* profile();
199 void AddGalleryChangeObserver(GalleryChangeObserver* observer);
200 void RemoveGalleryChangeObserver(GalleryChangeObserver* observer);
202 // RemovableStorageObserver implementation.
203 void OnRemovableStorageAttached(
204 const storage_monitor::StorageInfo& info) override;
206 // Lookup a media gallery and fill in information about it and return true if
207 // it exists. Return false if it does not, filling in default information.
208 bool LookUpGalleryByPath(const base::FilePath& path,
209 MediaGalleryPrefInfo* gallery) const;
211 MediaGalleryPrefIdSet LookUpGalleriesByDeviceId(
212 const std::string& device_id) const;
214 // Returns the absolute file path of the gallery specified by the
215 // |gallery_id|. Returns an empty file path if the |gallery_id| is invalid.
216 // Set |include_unpermitted_galleries| to true to get the file path of the
217 // gallery to which this |extension| has no access permission.
219 // TODO(tommycli): Remove this function after Media Galleries API Private
220 // is transitioned over to public. Also, the body of the function wrong.
221 // It just returns the absolute path to the device, not the gallery.
222 base::FilePath LookUpGalleryPathForExtension(
223 MediaGalleryPrefId gallery_id,
224 const extensions::Extension* extension,
225 bool include_unpermitted_galleries);
227 // Teaches the registry about a new gallery. If the gallery is in a
228 // blacklisted state, it is unblacklisted. |type| should not be a blacklisted
229 // type. Returns the gallery's pref id.
230 MediaGalleryPrefId AddGallery(const std::string& device_id,
231 const base::FilePath& relative_path,
232 MediaGalleryPrefInfo::Type type,
233 const base::string16& volume_label,
234 const base::string16& vendor_name,
235 const base::string16& model_name,
236 uint64 total_size_in_bytes,
237 base::Time last_attach_time,
238 int audio_count,
239 int image_count,
240 int video_count);
242 // Teach the registry about a gallery simply from the path. If the gallery is
243 // in a blacklisted state, it is unblacklisted. |type| should not be a
244 // blacklisted type. Returns the gallery's pref id.
245 MediaGalleryPrefId AddGalleryByPath(const base::FilePath& path,
246 MediaGalleryPrefInfo::Type type);
248 // Logically removes the gallery identified by |id| from the store. For
249 // auto added or scan result galleries, this means moving them into a
250 // blacklisted state, otherwise they may come back when they are detected
251 // again.
252 void ForgetGalleryById(MediaGalleryPrefId id);
254 // Remove the gallery identified by |id| from the store entirely. If it is an
255 // auto added or scan result gallery, it could get added again when the
256 // location is noticed again.
257 void EraseGalleryById(MediaGalleryPrefId id);
259 // Returns true if some extension has permission for |id|, which may not be
260 // an auto detected type.
261 bool NonAutoGalleryHasPermission(MediaGalleryPrefId id) const;
263 MediaGalleryPrefIdSet GalleriesForExtension(
264 const extensions::Extension& extension);
266 // Returns true if the permission changed. Returns false if there was
267 // no change.
268 bool SetGalleryPermissionForExtension(const extensions::Extension& extension,
269 MediaGalleryPrefId pref_id,
270 bool has_permission);
272 const MediaGalleriesPrefInfoMap& known_galleries() const;
274 // These keep track of when we last successfully completed a media scan.
275 // This is used to provide cached results when appropriate.
276 base::Time GetLastScanCompletionTime() const;
277 void SetLastScanCompletionTime(const base::Time& time);
279 // KeyedService implementation:
280 void Shutdown() override;
282 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
284 // Returns true if the media gallery preferences system has ever been used
285 // for this profile. To be exact, it checks if a gallery has ever been added
286 // (including defaults).
287 static bool APIHasBeenUsed(Profile* profile);
289 private:
290 friend class MediaGalleriesPreferencesTest;
291 friend class MediaGalleriesPermissionsTest;
293 typedef std::map<std::string /*device id*/, MediaGalleryPrefIdSet>
294 DeviceIdPrefIdsMap;
296 // These must be called on the UI thread.
297 void OnInitializationCallbackReturned();
298 void FinishInitialization();
300 // Populates the default galleries. Call only on fresh profiles.
301 void AddDefaultGalleries();
303 // This is a hack - Some devices (iTunes, Picasa) are singletons in that only
304 // one instance of that type is supported at a time. As such, the device id
305 // should just be "itunes:" or "picasa:" but that would mean finding the
306 // location of the database file multiple times, which may be an async
307 // operation. Storing the location of the backing database in the device
308 // id allows that look up to be avoided. However, the cost is that if the
309 // database moves, the device id in preferences has to be updated. This
310 // method searches for a gallery of the type passed in and updates its
311 // device id. It returns true if the device id is up to date.
312 bool UpdateDeviceIDForSingletonType(const std::string& device_id);
314 void OnStorageMonitorInit(bool api_has_been_used);
316 // Handle an iPhoto, iTunes, or Picasa finder returning a device ID to us.
317 void OnFinderDeviceID(const std::string& device_id);
319 // Builds |known_galleries_| from the persistent store.
320 void InitFromPrefs();
322 // Adds a new gallery with the given parameters, or updates in-place an
323 // existing gallery with the given device_id if one exists.
324 // TODO(orenb): Simplify this and reduce the number of parameters.
325 MediaGalleryPrefId AddOrUpdateGalleryInternal(
326 const std::string& device_id,
327 const base::string16& display_name,
328 const base::FilePath& relative_path,
329 MediaGalleryPrefInfo::Type type,
330 const base::string16& volume_label,
331 const base::string16& vendor_name,
332 const base::string16& model_name,
333 uint64 total_size_in_bytes,
334 base::Time last_attach_time,
335 bool volume_metadata_valid,
336 int audio_count,
337 int image_count,
338 int video_count,
339 int prefs_version,
340 MediaGalleryPrefInfo::DefaultGalleryType default_gallery_type);
342 void EraseOrBlacklistGalleryById(MediaGalleryPrefId id, bool erase);
344 // Updates the default galleries: finds the previously default galleries
345 // and updates their device IDs (i.e., their paths) inplace if they have
346 // changed.
347 void UpdateDefaultGalleriesPaths();
349 // Sets permission for the media galleries identified by |gallery_id| for the
350 // extension in the given |prefs|. Returns true only if anything changed.
351 bool SetGalleryPermissionInPrefs(const std::string& extension_id,
352 MediaGalleryPrefId gallery_id,
353 bool has_access);
355 // Removes the entry for the media galleries permissions identified by
356 // |gallery_id| for the extension in the given |prefs|.
357 // Returns true only if anything changed.
358 bool UnsetGalleryPermissionInPrefs(const std::string& extension_id,
359 MediaGalleryPrefId gallery_id);
361 // Return all media gallery permissions for the extension in the given
362 // |prefs|.
363 std::vector<MediaGalleryPermission> GetGalleryPermissionsFromPrefs(
364 const std::string& extension_id) const;
366 // Remove all the media gallery permissions in |prefs| for the gallery
367 // specified by |gallery_id|.
368 void RemoveGalleryPermissionsFromPrefs(MediaGalleryPrefId gallery_id);
370 // Get the ExtensionPrefs to use; this will be either the ExtensionPrefs
371 // object associated with |profile_|, or extension_prefs_for_testing_, if
372 // SetExtensionPrefsForTesting() has been called.
373 extensions::ExtensionPrefs* GetExtensionPrefs() const;
375 // Set the ExtensionPrefs object to be returned by GetExtensionPrefs().
376 void SetExtensionPrefsForTesting(extensions::ExtensionPrefs* extension_prefs);
378 bool initialized_;
379 std::vector<base::Closure> on_initialize_callbacks_;
380 int pre_initialization_callbacks_waiting_;
382 // The profile that owns |this|.
383 Profile* profile_;
385 // The ExtensionPrefs used in a testing environment, where KeyedServices
386 // aren't used. This will be NULL unless it is set with
387 // SetExtensionPrefsForTesting().
388 extensions::ExtensionPrefs* extension_prefs_for_testing_;
390 // An in-memory cache of known galleries.
391 MediaGalleriesPrefInfoMap known_galleries_;
393 // A mapping from device id to the set of gallery pref ids on that device.
394 // All pref ids in |device_map_| are also in |known_galleries_|.
395 DeviceIdPrefIdsMap device_map_;
397 base::ObserverList<GalleryChangeObserver> gallery_change_observers_;
399 base::WeakPtrFactory<MediaGalleriesPreferences> weak_factory_;
401 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPreferences);
404 #endif // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_