Home | History | Annotate | Download | only in media_galleries
      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