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. 4 5 #ifndef CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_ 6 #define CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/basictypes.h" 13 #include "base/files/file_path.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/observer_list.h" 16 #include "base/strings/string16.h" 17 #include "base/time/time.h" 18 #include "chrome/browser/storage_monitor/removable_storage_observer.h" 19 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 20 21 class Profile; 22 23 namespace base { 24 class DictionaryValue; 25 } 26 27 namespace extensions { 28 class Extension; 29 class ExtensionPrefs; 30 } 31 32 namespace user_prefs { 33 class PrefRegistrySyncable; 34 } 35 36 namespace chrome { 37 38 typedef uint64 MediaGalleryPrefId; 39 const MediaGalleryPrefId kInvalidMediaGalleryPrefId = 0; 40 41 struct MediaGalleryPermission { 42 MediaGalleryPrefId pref_id; 43 bool has_permission; 44 }; 45 46 struct MediaGalleryPrefInfo { 47 enum Type { 48 kAutoDetected, // Auto added to the list of galleries. 49 kUserAdded, // Explicitly added by the user. 50 kBlackListed, // Auto added but then removed by the user. 51 kInvalidType, 52 }; 53 54 MediaGalleryPrefInfo(); 55 ~MediaGalleryPrefInfo(); 56 57 // The absolute path of the gallery. 58 base::FilePath AbsolutePath() const; 59 60 // The ID that identifies this gallery in this Profile. 61 MediaGalleryPrefId pref_id; 62 63 // The user-visible name of this gallery. 64 string16 display_name; 65 66 // A string which uniquely and persistently identifies the device that the 67 // gallery lives on. 68 std::string device_id; 69 70 // The root of the gallery, relative to the root of the device. 71 base::FilePath path; 72 73 // The type of gallery. 74 Type type; 75 76 // The volume label of the volume/device on which the gallery 77 // resides. Empty if there is no such label or it is unknown. 78 string16 volume_label; 79 80 // Vendor name for the volume/device on which the gallery is located. 81 // Will be empty if unknown. 82 string16 vendor_name; 83 84 // Model name for the volume/device on which the gallery is located. 85 // Will be empty if unknown. 86 string16 model_name; 87 88 // The capacity in bytes of the volume/device on which the gallery is 89 // located. Will be zero if unknown. 90 uint64 total_size_in_bytes; 91 92 // If the gallery is on a removable device, the time that device was last 93 // attached. It is stored in preferences by the base::Time internal value, 94 // which is microseconds since the epoch. 95 base::Time last_attach_time; 96 97 // Set to true if the volume metadata fields (volume_label, vendor_name, 98 // model_name, total_size_in_bytes) were set. False if these fields were 99 // never written. 100 bool volume_metadata_valid; 101 102 // 0 if the display_name is set externally and always used for display. 103 // 1 if the display_name is only set externally when it is overriding 104 // the name constructed from volume metadata. 105 int prefs_version; 106 107 // Called by views to provide details for the gallery permission entries. 108 string16 GetGalleryDisplayName() const; 109 string16 GetGalleryTooltip() const; 110 string16 GetGalleryAdditionalDetails() const; 111 112 // Returns true if the gallery is currently a removable device gallery which 113 // is now attached, or a fixed storage gallery. 114 bool IsGalleryAvailable() const; 115 }; 116 117 typedef std::map<MediaGalleryPrefId, MediaGalleryPrefInfo> 118 MediaGalleriesPrefInfoMap; 119 typedef std::set<MediaGalleryPrefId> MediaGalleryPrefIdSet; 120 121 // A class to manage the media gallery preferences. There is one instance per 122 // user profile. 123 class MediaGalleriesPreferences : public BrowserContextKeyedService, 124 public RemovableStorageObserver { 125 public: 126 class GalleryChangeObserver { 127 public: 128 // |extension_id| specifies the extension affected by this change. 129 // It is empty if the gallery change affects all extensions. 130 // If not empty, |pref_id| and |has_permission| are relevant 131 // and refer to a specific relationship. 132 virtual void OnGalleryChanged(MediaGalleriesPreferences* pref, 133 const std::string& extension_id, 134 MediaGalleryPrefId pref_id, 135 bool has_permission) = 0; 136 137 protected: 138 virtual ~GalleryChangeObserver(); 139 }; 140 141 explicit MediaGalleriesPreferences(Profile* profile); 142 virtual ~MediaGalleriesPreferences(); 143 144 void AddGalleryChangeObserver(GalleryChangeObserver* observer); 145 void RemoveGalleryChangeObserver(GalleryChangeObserver* observer); 146 147 // RemovableStorageObserver implementation. 148 virtual void OnRemovableStorageAttached(const StorageInfo& info) OVERRIDE; 149 150 // Lookup a media gallery and fill in information about it and return true if 151 // it exists. Return false if it does not, filling in default information. 152 // TODO(vandebo) figure out if we want this to be async, in which case: 153 // void LookUpGalleryByPath(base::FilePath& path, 154 // callback(const MediaGalleryInfo&)) 155 bool LookUpGalleryByPath(const base::FilePath& path, 156 MediaGalleryPrefInfo* gallery) const; 157 158 MediaGalleryPrefIdSet LookUpGalleriesByDeviceId( 159 const std::string& device_id) const; 160 161 // Returns the absolute file path of the gallery specified by the 162 // |gallery_id|. Returns an empty file path if the |gallery_id| is invalid. 163 // Set |include_unpermitted_galleries| to true to get the file path of the 164 // gallery to which this |extension| has no access permission. 165 base::FilePath LookUpGalleryPathForExtension( 166 MediaGalleryPrefId gallery_id, 167 const extensions::Extension* extension, 168 bool include_unpermitted_galleries); 169 170 // Teaches the registry about a new gallery. 171 // Returns the gallery's pref id. 172 MediaGalleryPrefId AddGallery(const std::string& device_id, 173 const base::FilePath& relative_path, 174 bool user_added, 175 const string16& volume_label, 176 const string16& vendor_name, 177 const string16& model_name, 178 uint64 total_size_in_bytes, 179 base::Time last_attach_time); 180 181 // Teach the registry about a user added registry simply from the path. 182 // Returns the gallery's pref id. 183 MediaGalleryPrefId AddGalleryByPath(const base::FilePath& path); 184 185 // Removes the gallery identified by |id| from the store. 186 void ForgetGalleryById(MediaGalleryPrefId id); 187 188 MediaGalleryPrefIdSet GalleriesForExtension( 189 const extensions::Extension& extension) const; 190 191 void SetGalleryPermissionForExtension(const extensions::Extension& extension, 192 MediaGalleryPrefId pref_id, 193 bool has_permission); 194 195 const MediaGalleriesPrefInfoMap& known_galleries() const { 196 return known_galleries_; 197 } 198 199 // BrowserContextKeyedService implementation: 200 virtual void Shutdown() OVERRIDE; 201 202 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 203 204 // Returns true if the media gallery preferences system has ever been used 205 // for this profile. To be exact, it checks if a gallery has ever been added 206 // (including defaults). 207 static bool APIHasBeenUsed(Profile* profile); 208 209 private: 210 friend class MediaGalleriesPreferencesTest; 211 friend class MediaGalleriesPermissionsTest; 212 213 typedef std::map<std::string /*device id*/, MediaGalleryPrefIdSet> 214 DeviceIdPrefIdsMap; 215 216 // Populates the default galleries if this is a fresh profile. 217 void AddDefaultGalleriesIfFreshProfile(); 218 219 // This is a hack - Some devices (iTunes, Picasa) are singletons in that only 220 // one instance of that type is supported at a time. As such, the device id 221 // should just be "itunes:" or "picasa:" but that would mean finding the 222 // location of the database file multiple times, which may be an async 223 // operation. Storing the location of the backing database in the device 224 // id allows that look up to be avoided. However, the cost is that if the 225 // database moves, the device id in preferences has to be updated. This 226 // method searches for a gallery of the type passed in and updates its 227 // device id. It returns true if the device id is up to date. 228 bool UpdateDeviceIDForSingletonType(const std::string& device_id); 229 230 // Try to add an entry for the iTunes 'device'. 231 void OnITunesDeviceID(const std::string& device_id); 232 233 // Try to add an entry for the Picasa 'device'. 234 void OnPicasaDeviceID(const std::string& device_id); 235 236 // Builds |known_galleries_| from the persistent store. 237 // Notifies GalleryChangeObservers if |notify_observers| is true. 238 void InitFromPrefs(bool notify_observers); 239 240 // Notifies |gallery_change_observers_| about changes in |known_galleries_|. 241 void NotifyChangeObservers(const std::string& extension_id, 242 MediaGalleryPrefId pref_id, 243 bool has_permission); 244 245 MediaGalleryPrefId AddGalleryInternal(const std::string& device_id, 246 const string16& display_name, 247 const base::FilePath& relative_path, 248 bool user_added, 249 const string16& volume_label, 250 const string16& vendor_name, 251 const string16& model_name, 252 uint64 total_size_in_bytes, 253 base::Time last_attach_time, 254 bool volume_metadata_valid, 255 int prefs_version); 256 257 // Sets permission for the media galleries identified by |gallery_id| for the 258 // extension in the given |prefs|. 259 void SetGalleryPermissionInPrefs(const std::string& extension_id, 260 MediaGalleryPrefId gallery_id, 261 bool has_access); 262 263 // Removes the entry for the media galleries permissions identified by 264 // |gallery_id| for the extension in the given |prefs|. 265 void UnsetGalleryPermissionInPrefs(const std::string& extension_id, 266 MediaGalleryPrefId gallery_id); 267 268 // Return all media gallery permissions for the extension in the given 269 // |prefs|. 270 std::vector<MediaGalleryPermission> GetGalleryPermissionsFromPrefs( 271 const std::string& extension_id) const; 272 273 // Remove all the media gallery permissions in |prefs| for the gallery 274 // specified by |gallery_id|. 275 void RemoveGalleryPermissionsFromPrefs(MediaGalleryPrefId gallery_id); 276 277 // Get the ExtensionPrefs to use; this will be either the ExtensionPrefs 278 // object associated with |profile_|, or extension_prefs_for_testing_, if 279 // SetExtensionPrefsForTesting() has been called. 280 extensions::ExtensionPrefs* GetExtensionPrefs() const; 281 282 // Set the ExtensionPrefs object to be returned by GetExtensionPrefs(). 283 void SetExtensionPrefsForTesting(extensions::ExtensionPrefs* extension_prefs); 284 285 base::WeakPtrFactory<MediaGalleriesPreferences> weak_factory_; 286 287 // The profile that owns |this|. 288 Profile* profile_; 289 290 // The ExtensionPrefs used in a testing environment, where 291 // BrowserContextKeyedServices aren't used. This will be NULL unless it is 292 // set with SetExtensionPrefsForTesting(). 293 extensions::ExtensionPrefs* extension_prefs_for_testing_; 294 295 // An in-memory cache of known galleries. 296 MediaGalleriesPrefInfoMap known_galleries_; 297 298 // A mapping from device id to the set of gallery pref ids on that device. 299 // All pref ids in |device_map_| are also in |known_galleries_|. 300 DeviceIdPrefIdsMap device_map_; 301 302 ObserverList<GalleryChangeObserver> gallery_change_observers_; 303 304 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPreferences); 305 }; 306 307 } // namespace chrome 308 309 #endif // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_ 310