Home | History | Annotate | Download | only in prefs
      1 // Copyright (c) 2011 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 // This provides a way to access the application's current preferences.
      6 
      7 #ifndef CHROME_BROWSER_PREFS_PREF_SERVICE_H_
      8 #define CHROME_BROWSER_PREFS_PREF_SERVICE_H_
      9 #pragma once
     10 
     11 #include <set>
     12 #include <string>
     13 
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/threading/non_thread_safe.h"
     17 #include "base/values.h"
     18 #include "chrome/common/json_pref_store.h"
     19 
     20 class DefaultPrefStore;
     21 class FilePath;
     22 class NotificationObserver;
     23 class PersistentPrefStore;
     24 class PrefChangeObserver;
     25 class PrefNotifier;
     26 class PrefNotifierImpl;
     27 class PrefStore;
     28 class PrefValueStore;
     29 class Profile;
     30 
     31 namespace subtle {
     32 class PrefMemberBase;
     33 class ScopedUserPrefUpdateBase;
     34 };
     35 
     36 class PrefService : public base::NonThreadSafe,
     37                     public JsonPrefStore::Delegate {
     38  public:
     39   // A helper class to store all the information associated with a preference.
     40   class Preference {
     41    public:
     42 
     43     // The type of the preference is determined by the type with which it is
     44     // registered. This type needs to be a boolean, integer, double, string,
     45     // dictionary (a branch), or list.  You shouldn't need to construct this on
     46     // your own; use the PrefService::Register*Pref methods instead.
     47     Preference(const PrefService* service,
     48                const char* name,
     49                Value::ValueType type);
     50     ~Preference() {}
     51 
     52     // Returns the name of the Preference (i.e., the key, e.g.,
     53     // browser.window_placement).
     54     const std::string name() const { return name_; }
     55 
     56     // Returns the registered type of the preference.
     57     Value::ValueType GetType() const;
     58 
     59     // Returns the value of the Preference, falling back to the registered
     60     // default value if no other has been set.
     61     const Value* GetValue() const;
     62 
     63     // Returns true if the Preference is managed, i.e. set by an admin policy.
     64     // Since managed prefs have the highest priority, this also indicates
     65     // whether the pref is actually being controlled by the policy setting.
     66     bool IsManaged() const;
     67 
     68     // Returns true if the Preference has a value set by an extension, even if
     69     // that value is being overridden by a higher-priority source.
     70     bool HasExtensionSetting() const;
     71 
     72     // Returns true if the Preference has a user setting, even if that value is
     73     // being overridden by a higher-priority source.
     74     bool HasUserSetting() const;
     75 
     76     // Returns true if the Preference value is currently being controlled by an
     77     // extension, and not by any higher-priority source.
     78     bool IsExtensionControlled() const;
     79 
     80     // Returns true if the Preference value is currently being controlled by a
     81     // user setting, and not by any higher-priority source.
     82     bool IsUserControlled() const;
     83 
     84     // Returns true if the Preference is currently using its default value,
     85     // and has not been set by any higher-priority source (even with the same
     86     // value).
     87     bool IsDefaultValue() const;
     88 
     89     // Returns true if the user can change the Preference value, which is the
     90     // case if no higher-priority source than the user store controls the
     91     // Preference.
     92     bool IsUserModifiable() const;
     93 
     94     // Returns true if an extension can change the Preference value, which is
     95     // the case if no higher-priority source than the extension store controls
     96     // the Preference.
     97     bool IsExtensionModifiable() const;
     98 
     99    private:
    100     friend class PrefService;
    101 
    102     PrefValueStore* pref_value_store() const {
    103       return pref_service_->pref_value_store_.get();
    104     }
    105 
    106     std::string name_;
    107 
    108     Value::ValueType type_;
    109 
    110     // Reference to the PrefService in which this pref was created.
    111     const PrefService* pref_service_;
    112 
    113     DISALLOW_COPY_AND_ASSIGN(Preference);
    114   };
    115 
    116   class Delegate {
    117    public:
    118     virtual void OnPrefsLoaded(PrefService* prefs, bool success) = 0;
    119 #ifdef ANDROID
    120     virtual ~Delegate() {};
    121 #endif
    122   };
    123 
    124   // JsonPrefStore::Delegate implementaion.
    125   virtual void OnPrefsRead(PersistentPrefStore::PrefReadError error,
    126                            bool no_dir);
    127 
    128   // Factory method that creates a new instance of a PrefService with the
    129   // applicable PrefStores. The |pref_filename| points to the user preference
    130   // file. The |profile| is the one to which these preferences apply; it may be
    131   // NULL if we're dealing with the local state. This is the usual way to create
    132   // a new PrefService. |extension_pref_store| is used as the source for
    133   // extension-controlled preferences and may be NULL. The PrefService takes
    134   // ownership of |extension_pref_store|.
    135   static PrefService* CreatePrefService(const FilePath& pref_filename,
    136                                         PrefStore* extension_pref_store,
    137                                         Profile* profile);
    138 
    139   // Same as above, but with async initialization.
    140   static PrefService* CreatePrefServiceAsync(const FilePath& pref_filename,
    141                                              PrefStore* extension_pref_store,
    142                                              Profile* profile,
    143                                              Delegate* delegate);
    144 
    145   // Creates an incognito copy of the pref service that shares most pref stores
    146   // but uses a fresh non-persistent overlay for the user pref store and an
    147   // individual extension pref store (to cache the effective extension prefs for
    148   // incognito windows).
    149   PrefService* CreateIncognitoPrefService(PrefStore* incognito_extension_prefs);
    150 
    151   virtual ~PrefService();
    152 
    153   // Reloads the data from file. This should only be called when the importer
    154   // is running during first run, and the main process may not change pref
    155   // values while the importer process is running. Returns true on success.
    156   bool ReloadPersistentPrefs();
    157 
    158   // Returns true if the preference for the given preference name is available
    159   // and is managed.
    160   bool IsManagedPreference(const char* pref_name) const;
    161 
    162   // Writes the data to disk. The return value only reflects whether
    163   // serialization was successful; we don't know whether the data actually made
    164   // it on disk (since it's on a different thread).  This should only be used if
    165   // we need to save immediately (basically, during shutdown).  Otherwise, you
    166   // should use ScheduleSavePersistentPrefs.
    167   bool SavePersistentPrefs();
    168 
    169   // Serializes the data and schedules save using ImportantFileWriter.
    170   void ScheduleSavePersistentPrefs();
    171 
    172   // Lands pending writes to disk.
    173   void CommitPendingWrite();
    174 
    175   // Make the PrefService aware of a pref.
    176   void RegisterBooleanPref(const char* path, bool default_value);
    177   void RegisterIntegerPref(const char* path, int default_value);
    178   void RegisterDoublePref(const char* path, double default_value);
    179   void RegisterStringPref(const char* path, const std::string& default_value);
    180   void RegisterFilePathPref(const char* path, const FilePath& default_value);
    181   void RegisterListPref(const char* path);
    182   void RegisterDictionaryPref(const char* path);
    183   // These take ownership of the default_value:
    184   void RegisterListPref(const char* path, ListValue* default_value);
    185   void RegisterDictionaryPref(const char* path, DictionaryValue* default_value);
    186 
    187   // These variants use a default value from the locale dll instead.
    188   void RegisterLocalizedBooleanPref(const char* path,
    189                                     int locale_default_message_id);
    190   void RegisterLocalizedIntegerPref(const char* path,
    191                                     int locale_default_message_id);
    192   void RegisterLocalizedDoublePref(const char* path,
    193                                    int locale_default_message_id);
    194   void RegisterLocalizedStringPref(const char* path,
    195                                    int locale_default_message_id);
    196 
    197   // If the path is valid and the value at the end of the path matches the type
    198   // specified, it will return the specified value.  Otherwise, the default
    199   // value (set when the pref was registered) will be returned.
    200   bool GetBoolean(const char* path) const;
    201   int GetInteger(const char* path) const;
    202   double GetDouble(const char* path) const;
    203   std::string GetString(const char* path) const;
    204   FilePath GetFilePath(const char* path) const;
    205 
    206   // Returns the branch if it exists, or the registered default value otherwise.
    207   // Note that |path| must point to a registered preference. In that case, these
    208   // functions will never return NULL.
    209   const DictionaryValue* GetDictionary(const char* path) const;
    210   const ListValue* GetList(const char* path) const;
    211 
    212   // Removes a user pref and restores the pref to its default value.
    213   void ClearPref(const char* path);
    214 
    215   // If the path is valid (i.e., registered), update the pref value in the user
    216   // prefs.
    217   // To set the value of dictionary or list values in the pref tree use
    218   // Set(), but to modify the value of a dictionary or list use either
    219   // ListPrefUpdate or DictionaryPrefUpdate from scoped_user_pref_update.h.
    220   void Set(const char* path, const Value& value);
    221   void SetBoolean(const char* path, bool value);
    222   void SetInteger(const char* path, int value);
    223   void SetDouble(const char* path, double value);
    224   void SetString(const char* path, const std::string& value);
    225   void SetFilePath(const char* path, const FilePath& value);
    226   // SetList() takes ownership of |value|. Pass a copy of the ListValue to
    227   // keep ownership of the original list, if necessary.
    228   void SetList(const char* path, ListValue* value);
    229 
    230   // Int64 helper methods that actually store the given value as a string.
    231   // Note that if obtaining the named value via GetDictionary or GetList, the
    232   // Value type will be TYPE_STRING.
    233   void SetInt64(const char* path, int64 value);
    234   int64 GetInt64(const char* path) const;
    235   void RegisterInt64Pref(const char* path, int64 default_value);
    236 
    237   // Returns true if a value has been set for the specified path.
    238   // NOTE: this is NOT the same as FindPreference. In particular
    239   // FindPreference returns whether RegisterXXX has been invoked, where as
    240   // this checks if a value exists for the path.
    241   bool HasPrefPath(const char* path) const;
    242 
    243   // Returns a dictionary with effective preference values. The ownership
    244   // is passed to the caller.
    245   DictionaryValue* GetPreferenceValues() const;
    246 
    247   // A helper method to quickly look up a preference.  Returns NULL if the
    248   // preference is not registered.
    249   const Preference* FindPreference(const char* pref_name) const;
    250 
    251   bool ReadOnly() const;
    252 
    253  protected:
    254   // Construct a new pref service, specifying the pref sources as explicit
    255   // PrefStore pointers. This constructor is what CreatePrefService() ends up
    256   // calling. It's also used for unit tests.
    257   PrefService(PrefStore* managed_platform_prefs,
    258               PrefStore* managed_cloud_prefs,
    259               PrefStore* extension_prefs,
    260               PrefStore* command_line_prefs,
    261               PersistentPrefStore* user_prefs,
    262               PrefStore* recommended_platform_prefs,
    263               PrefStore* recommended_cloud_prefs,
    264               DefaultPrefStore* default_store,
    265               Delegate* delegate);
    266 
    267   // The PrefNotifier handles registering and notifying preference observers.
    268   // It is created and owned by this PrefService. Subclasses may access it for
    269   // unit testing.
    270   scoped_ptr<PrefNotifierImpl> pref_notifier_;
    271 
    272  private:
    273   class PreferencePathComparator {
    274    public:
    275     bool operator() (Preference* lhs, Preference* rhs) const {
    276       return lhs->name() < rhs->name();
    277     }
    278   };
    279   typedef std::set<Preference*, PreferencePathComparator> PreferenceSet;
    280 
    281   friend class PrefServiceMockBuilder;
    282 
    283   // Registration of pref change observers must be done using the
    284   // PrefChangeRegistrar, which is declared as a friend here to grant it
    285   // access to the otherwise protected members Add/RemovePrefObserver.
    286   // PrefMember registers for preferences changes notification directly to
    287   // avoid the storage overhead of the registrar, so its base class must be
    288   // declared as a friend, too.
    289   friend class PrefChangeRegistrar;
    290   friend class subtle::PrefMemberBase;
    291 
    292   // Give access to ReportUserPrefChanged() and GetMutableUserPref().
    293   friend class subtle::ScopedUserPrefUpdateBase;
    294 
    295   // Construct an incognito version of the pref service. Use
    296   // CreateIncognitoPrefService() instead of calling this constructor directly.
    297   PrefService(const PrefService& original,
    298               PrefStore* incognito_extension_prefs);
    299 
    300   // Sends notification of a changed preference. This needs to be called by
    301   // a ScopedUserPrefUpdate if a DictionaryValue or ListValue is changed.
    302   void ReportUserPrefChanged(const std::string& key);
    303 
    304   // If the pref at the given path changes, we call the observer's Observe
    305   // method with PREF_CHANGED. Note that observers should not call these methods
    306   // directly but rather use a PrefChangeRegistrar to make sure the observer
    307   // gets cleaned up properly.
    308   virtual void AddPrefObserver(const char* path, NotificationObserver* obs);
    309   virtual void RemovePrefObserver(const char* path, NotificationObserver* obs);
    310 
    311   // Registers a new preference at |path|. The |default_value| must not be
    312   // NULL as it determines the preference value's type.
    313   // RegisterPreference must not be called twice for the same path.
    314   // This method takes ownership of |default_value|.
    315   void RegisterPreference(const char* path, Value* default_value);
    316 
    317   // Sets the value for this pref path in the user pref store and informs the
    318   // PrefNotifier of the change.
    319   void SetUserPrefValue(const char* path, Value* new_value);
    320 
    321   // Load preferences from storage, attempting to diagnose and handle errors.
    322   // This should only be called from the constructor.
    323   void InitFromStorage();
    324 
    325   // Used to set the value of dictionary or list values in the user pref store.
    326   // This will create a dictionary or list if one does not exist in the user
    327   // pref store. This method returns NULL only if you're requesting an
    328   // unregistered pref or a non-dict/non-list pref.
    329   // |type| may only be Values::TYPE_DICTIONARY or Values::TYPE_LIST and
    330   // |path| must point to a registered preference of type |type|.
    331   // Ownership of the returned value remains at the user pref store.
    332   Value* GetMutableUserPref(const char* path, Value::ValueType type);
    333 
    334   // The PrefValueStore provides prioritized preference values. It is created
    335   // and owned by this PrefService. Subclasses may access it for unit testing.
    336   scoped_ptr<PrefValueStore> pref_value_store_;
    337 
    338   // Pref Stores and profile that we passed to the PrefValueStore.
    339   scoped_refptr<PersistentPrefStore> user_pref_store_;
    340   scoped_refptr<DefaultPrefStore> default_store_;
    341 
    342   // Local cache of registered Preference objects. The default_store_
    343   // is authoritative with respect to what the types and default values
    344   // of registered preferences are.
    345   mutable PreferenceSet prefs_;
    346 
    347   // Holds delegator to be called after initialization, if async version
    348   // is used.
    349   Delegate* delegate_;
    350 
    351   DISALLOW_COPY_AND_ASSIGN(PrefService);
    352 };
    353 
    354 #endif  // CHROME_BROWSER_PREFS_PREF_SERVICE_H_
    355