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_
12 #include "base/basictypes.h"
13 #include "base/callback_forward.h"
14 #include "base/files/file_path.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/strings/string16.h"
18 #include "base/time/time.h"
19 #include "chrome/browser/storage_monitor/removable_storage_observer.h"
20 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
25 class DictionaryValue
;
28 namespace extensions
{
33 namespace user_prefs
{
34 class PrefRegistrySyncable
;
37 typedef uint64 MediaGalleryPrefId
;
38 const MediaGalleryPrefId kInvalidMediaGalleryPrefId
= 0;
40 struct MediaGalleryPermission
{
41 MediaGalleryPrefId pref_id
;
45 struct MediaGalleryPrefInfo
{
47 kUserAdded
, // Explicitly added by the user.
48 kAutoDetected
, // Auto added to the list of galleries.
49 kBlackListed
, // Auto added but then removed by the user.
50 kScanResult
, // Discovered by a disk scan.
51 kRemovedScan
, // Discovered by a disk scan but then removed by the user.
55 MediaGalleryPrefInfo();
56 ~MediaGalleryPrefInfo();
58 // The absolute path of the gallery.
59 base::FilePath
AbsolutePath() const;
61 // True if the gallery should not be displayed to the user
62 // i.e. kBlackListed || kRemovedScan.
63 bool IsBlackListedType() const;
65 // The ID that identifies this gallery in this Profile.
66 MediaGalleryPrefId pref_id
;
68 // The user-visible name of this gallery.
69 base::string16 display_name
;
71 // A string which uniquely and persistently identifies the device that the
73 std::string device_id
;
75 // The root of the gallery, relative to the root of the device.
78 // The type of gallery.
81 // The volume label of the volume/device on which the gallery
82 // resides. Empty if there is no such label or it is unknown.
83 base::string16 volume_label
;
85 // Vendor name for the volume/device on which the gallery is located.
86 // Will be empty if unknown.
87 base::string16 vendor_name
;
89 // Model name for the volume/device on which the gallery is located.
90 // Will be empty if unknown.
91 base::string16 model_name
;
93 // The capacity in bytes of the volume/device on which the gallery is
94 // located. Will be zero if unknown.
95 uint64 total_size_in_bytes
;
97 // If the gallery is on a removable device, the time that device was last
98 // attached. It is stored in preferences by the base::Time internal value,
99 // which is microseconds since the epoch.
100 base::Time last_attach_time
;
102 // Set to true if the volume metadata fields (volume_label, vendor_name,
103 // model_name, total_size_in_bytes) were set. False if these fields were
105 bool volume_metadata_valid
;
107 // The following fields are populated with the image, music, and video file
108 // counts from the last scan if |type| is kScanResult. For files where it is
109 // hard to determine the exact type, the file should be counted in all
115 // 0 if the display_name is set externally and always used for display.
116 // 1 if the display_name is only set externally when it is overriding
117 // the name constructed from volume metadata.
120 // Called by views to provide details for the gallery permission entries.
121 base::string16
GetGalleryDisplayName() const;
122 base::string16
GetGalleryTooltip() const;
123 base::string16
GetGalleryAdditionalDetails() const;
125 // Returns true if the gallery is currently a removable device gallery which
126 // is now attached, or a fixed storage gallery.
127 bool IsGalleryAvailable() const;
130 typedef std::map
<MediaGalleryPrefId
, MediaGalleryPrefInfo
>
131 MediaGalleriesPrefInfoMap
;
132 typedef std::set
<MediaGalleryPrefId
> MediaGalleryPrefIdSet
;
134 // A class to manage the media gallery preferences. There is one instance per
136 class MediaGalleriesPreferences
: public BrowserContextKeyedService
,
137 public RemovableStorageObserver
{
139 class GalleryChangeObserver
{
141 // |extension_id| specifies the extension affected by this change.
142 // |pref_id| refers to the gallery.
143 virtual void OnPermissionAdded(MediaGalleriesPreferences
* pref
,
144 const std::string
& extension_id
,
145 MediaGalleryPrefId pref_id
) {}
147 virtual void OnPermissionRemoved(MediaGalleriesPreferences
* pref
,
148 const std::string
& extension_id
,
149 MediaGalleryPrefId pref_id
) {}
151 virtual void OnGalleryAdded(MediaGalleriesPreferences
* pref
,
152 MediaGalleryPrefId pref_id
) {}
154 virtual void OnGalleryRemoved(MediaGalleriesPreferences
* pref
,
155 MediaGalleryPrefId pref_id
) {}
157 virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences
* pref
,
158 MediaGalleryPrefId pref_id
) {}
160 virtual ~GalleryChangeObserver();
163 explicit MediaGalleriesPreferences(Profile
* profile
);
164 virtual ~MediaGalleriesPreferences();
166 // Ensures that the preferences is initialized. The provided callback, if
167 // non-null, will be called when initialization is complete. If initialization
168 // has already completed, this callback will be invoked in the calling stack.
169 // Before the callback is run, other calls may not return the correct results.
170 // Should be invoked on the UI thread; callbacks will be run on the UI thread.
171 // This call also ensures that the StorageMonitor is initialized.
172 // Note for unit tests: This requires an active FILE thread and
173 // EnsureMediaDirectoriesExists instance to complete reliably.
174 void EnsureInitialized(base::Closure callback
);
176 // Return true if the storage monitor has already been initialized.
177 bool IsInitialized() const;
181 void AddGalleryChangeObserver(GalleryChangeObserver
* observer
);
182 void RemoveGalleryChangeObserver(GalleryChangeObserver
* observer
);
184 // RemovableStorageObserver implementation.
185 virtual void OnRemovableStorageAttached(const StorageInfo
& info
) OVERRIDE
;
187 // Lookup a media gallery and fill in information about it and return true if
188 // it exists. Return false if it does not, filling in default information.
189 bool LookUpGalleryByPath(const base::FilePath
& path
,
190 MediaGalleryPrefInfo
* gallery
) const;
192 MediaGalleryPrefIdSet
LookUpGalleriesByDeviceId(
193 const std::string
& device_id
) const;
195 // Returns the absolute file path of the gallery specified by the
196 // |gallery_id|. Returns an empty file path if the |gallery_id| is invalid.
197 // Set |include_unpermitted_galleries| to true to get the file path of the
198 // gallery to which this |extension| has no access permission.
199 base::FilePath
LookUpGalleryPathForExtension(
200 MediaGalleryPrefId gallery_id
,
201 const extensions::Extension
* extension
,
202 bool include_unpermitted_galleries
);
204 // Teaches the registry about a new gallery. If the gallery is in a
205 // blacklisted state, it is unblacklisted. |type| should not be a blacklisted
206 // type. Returns the gallery's pref id.
207 MediaGalleryPrefId
AddGallery(const std::string
& device_id
,
208 const base::FilePath
& relative_path
,
209 MediaGalleryPrefInfo::Type type
,
210 const base::string16
& volume_label
,
211 const base::string16
& vendor_name
,
212 const base::string16
& model_name
,
213 uint64 total_size_in_bytes
,
214 base::Time last_attach_time
,
219 // Teach the registry about a gallery simply from the path. If the gallery is
220 // in a blacklisted state, it is unblacklisted. |type| should not be a
221 // blacklisted type. Returns the gallery's pref id.
222 MediaGalleryPrefId
AddGalleryByPath(const base::FilePath
& path
,
223 MediaGalleryPrefInfo::Type type
);
225 // Removes the gallery identified by |id| from the store.
226 void ForgetGalleryById(MediaGalleryPrefId id
);
228 MediaGalleryPrefIdSet
GalleriesForExtension(
229 const extensions::Extension
& extension
) const;
231 // Returns true if the permission changed. Returns false if there was
233 bool SetGalleryPermissionForExtension(const extensions::Extension
& extension
,
234 MediaGalleryPrefId pref_id
,
235 bool has_permission
);
237 const MediaGalleriesPrefInfoMap
& known_galleries() const;
239 // BrowserContextKeyedService implementation:
240 virtual void Shutdown() OVERRIDE
;
242 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
);
244 // Returns true if the media gallery preferences system has ever been used
245 // for this profile. To be exact, it checks if a gallery has ever been added
246 // (including defaults).
247 static bool APIHasBeenUsed(Profile
* profile
);
250 friend class MediaGalleriesPreferencesTest
;
251 friend class MediaGalleriesPermissionsTest
;
253 typedef std::map
<std::string
/*device id*/, MediaGalleryPrefIdSet
>
256 // These must be called on the UI thread.
257 void OnInitializationCallbackReturned();
258 void FinishInitialization();
260 // Populates the default galleries. Call only on fresh profiles.
261 void AddDefaultGalleries();
263 // This is a hack - Some devices (iTunes, Picasa) are singletons in that only
264 // one instance of that type is supported at a time. As such, the device id
265 // should just be "itunes:" or "picasa:" but that would mean finding the
266 // location of the database file multiple times, which may be an async
267 // operation. Storing the location of the backing database in the device
268 // id allows that look up to be avoided. However, the cost is that if the
269 // database moves, the device id in preferences has to be updated. This
270 // method searches for a gallery of the type passed in and updates its
271 // device id. It returns true if the device id is up to date.
272 bool UpdateDeviceIDForSingletonType(const std::string
& device_id
);
274 void OnStorageMonitorInit(bool add_default_galleries
);
276 // Handle an iPhoto, iTunes, or Picasa finder returning a device ID to us.
277 void OnFinderDeviceID(const std::string
& device_id
);
279 // Builds |known_galleries_| from the persistent store.
280 void InitFromPrefs();
282 MediaGalleryPrefId
AddGalleryInternal(const std::string
& device_id
,
283 const base::string16
& display_name
,
284 const base::FilePath
& relative_path
,
285 MediaGalleryPrefInfo::Type type
,
286 const base::string16
& volume_label
,
287 const base::string16
& vendor_name
,
288 const base::string16
& model_name
,
289 uint64 total_size_in_bytes
,
290 base::Time last_attach_time
,
291 bool volume_metadata_valid
,
297 // Sets permission for the media galleries identified by |gallery_id| for the
298 // extension in the given |prefs|. Returns true only if anything changed.
299 bool SetGalleryPermissionInPrefs(const std::string
& extension_id
,
300 MediaGalleryPrefId gallery_id
,
303 // Removes the entry for the media galleries permissions identified by
304 // |gallery_id| for the extension in the given |prefs|.
305 // Returns true only if anything changed.
306 bool UnsetGalleryPermissionInPrefs(const std::string
& extension_id
,
307 MediaGalleryPrefId gallery_id
);
309 // Return all media gallery permissions for the extension in the given
311 std::vector
<MediaGalleryPermission
> GetGalleryPermissionsFromPrefs(
312 const std::string
& extension_id
) const;
314 // Remove all the media gallery permissions in |prefs| for the gallery
315 // specified by |gallery_id|.
316 void RemoveGalleryPermissionsFromPrefs(MediaGalleryPrefId gallery_id
);
318 // Get the ExtensionPrefs to use; this will be either the ExtensionPrefs
319 // object associated with |profile_|, or extension_prefs_for_testing_, if
320 // SetExtensionPrefsForTesting() has been called.
321 extensions::ExtensionPrefs
* GetExtensionPrefs() const;
323 // Set the ExtensionPrefs object to be returned by GetExtensionPrefs().
324 void SetExtensionPrefsForTesting(extensions::ExtensionPrefs
* extension_prefs
);
327 std::vector
<base::Closure
> on_initialize_callbacks_
;
328 int pre_initialization_callbacks_waiting_
;
330 // The profile that owns |this|.
333 // The ExtensionPrefs used in a testing environment, where
334 // BrowserContextKeyedServices aren't used. This will be NULL unless it is
335 // set with SetExtensionPrefsForTesting().
336 extensions::ExtensionPrefs
* extension_prefs_for_testing_
;
338 // An in-memory cache of known galleries.
339 MediaGalleriesPrefInfoMap known_galleries_
;
341 // A mapping from device id to the set of gallery pref ids on that device.
342 // All pref ids in |device_map_| are also in |known_galleries_|.
343 DeviceIdPrefIdsMap device_map_
;
345 ObserverList
<GalleryChangeObserver
> gallery_change_observers_
;
347 base::WeakPtrFactory
<MediaGalleriesPreferences
> weak_factory_
;
349 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPreferences
);
352 #endif // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_