Home | History | Annotate | Download | only in prefs
      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 BASE_PREFS_PREF_VALUE_STORE_H_
      6 #define BASE_PREFS_PREF_VALUE_STORE_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/gtest_prod_util.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/prefs/base_prefs_export.h"
     17 #include "base/prefs/pref_store.h"
     18 #include "base/values.h"
     19 
     20 class PrefNotifier;
     21 class PrefStore;
     22 
     23 // The PrefValueStore manages various sources of values for Preferences
     24 // (e.g., configuration policies, extensions, and user settings). It returns
     25 // the value of a Preference from the source with the highest priority, and
     26 // allows setting user-defined values for preferences that are not managed.
     27 //
     28 // Unless otherwise explicitly noted, all of the methods of this class must
     29 // be called on the UI thread.
     30 class BASE_PREFS_EXPORT PrefValueStore {
     31  public:
     32   typedef base::Callback<void(const std::string&)> PrefChangedCallback;
     33 
     34   // In decreasing order of precedence:
     35   //   |managed_prefs| contains all preferences from mandatory policies.
     36   //   |extension_prefs| contains preference values set by extensions.
     37   //   |command_line_prefs| contains preference values set by command-line
     38   //        switches.
     39   //   |user_prefs| contains all user-set preference values.
     40   //   |recommended_prefs| contains all preferences from recommended policies.
     41   //   |default_prefs| contains application-default preference values. It must
     42   //        be non-null if any preferences are to be registered.
     43   //
     44   // |pref_notifier| facilitates broadcasting preference change notifications
     45   // to the world.
     46   PrefValueStore(PrefStore* managed_prefs,
     47                  PrefStore* extension_prefs,
     48                  PrefStore* command_line_prefs,
     49                  PrefStore* user_prefs,
     50                  PrefStore* recommended_prefs,
     51                  PrefStore* default_prefs,
     52                  PrefNotifier* pref_notifier);
     53   virtual ~PrefValueStore();
     54 
     55   // Creates a clone of this PrefValueStore with PrefStores overwritten
     56   // by the parameters passed, if unequal NULL.
     57   PrefValueStore* CloneAndSpecialize(PrefStore* managed_prefs,
     58                                      PrefStore* extension_prefs,
     59                                      PrefStore* command_line_prefs,
     60                                      PrefStore* user_prefs,
     61                                      PrefStore* recommended_prefs,
     62                                      PrefStore* default_prefs,
     63                                      PrefNotifier* pref_notifier);
     64 
     65   // A PrefValueStore can have exactly one callback that is directly
     66   // notified of preferences changing in the store. This does not
     67   // filter through the PrefNotifier mechanism, which may not forward
     68   // certain changes (e.g. unregistered prefs).
     69   void set_callback(const PrefChangedCallback& callback);
     70 
     71   // Gets the value for the given preference name that has the specified value
     72   // type. Values stored in a PrefStore that have the matching |name| but
     73   // a non-matching |type| are silently skipped. Returns true if a valid value
     74   // was found in any of the available PrefStores. Most callers should use
     75   // Preference::GetValue() instead of calling this method directly.
     76   bool GetValue(const std::string& name,
     77                 base::Value::Type type,
     78                 const base::Value** out_value) const;
     79 
     80   // Gets the recommended value for the given preference name that has the
     81   // specified value type. A value stored in the recommended PrefStore that has
     82   // the matching |name| but a non-matching |type| is silently ignored. Returns
     83   // true if a valid value was found. Most callers should use
     84   // Preference::GetRecommendedValue() instead of calling this method directly.
     85   bool GetRecommendedValue(const std::string& name,
     86                            base::Value::Type type,
     87                            const base::Value** out_value) const;
     88 
     89   // These methods return true if a preference with the given name is in the
     90   // indicated pref store, even if that value is currently being overridden by
     91   // a higher-priority source.
     92   bool PrefValueInManagedStore(const char* name) const;
     93   bool PrefValueInExtensionStore(const char* name) const;
     94   bool PrefValueInUserStore(const char* name) const;
     95 
     96   // These methods return true if a preference with the given name is actually
     97   // being controlled by the indicated pref store and not being overridden by
     98   // a higher-priority source.
     99   bool PrefValueFromExtensionStore(const char* name) const;
    100   bool PrefValueFromUserStore(const char* name) const;
    101   bool PrefValueFromRecommendedStore(const char* name) const;
    102   bool PrefValueFromDefaultStore(const char* name) const;
    103 
    104   // Check whether a Preference value is modifiable by the user, i.e. whether
    105   // there is no higher-priority source controlling it.
    106   bool PrefValueUserModifiable(const char* name) const;
    107 
    108   // Check whether a Preference value is modifiable by an extension, i.e.
    109   // whether there is no higher-priority source controlling it.
    110   bool PrefValueExtensionModifiable(const char* name) const;
    111 
    112   // Update the command line PrefStore with |command_line_prefs|.
    113   void UpdateCommandLinePrefStore(PrefStore* command_line_prefs);
    114 
    115  private:
    116   // PrefStores must be listed here in order from highest to lowest priority.
    117   //   MANAGED contains all managed preference values that are provided by
    118   //      mandatory policies (e.g. Windows Group Policy or cloud policy).
    119   //   EXTENSION contains preference values set by extensions.
    120   //   COMMAND_LINE contains preference values set by command-line switches.
    121   //   USER contains all user-set preference values.
    122   //   RECOMMENDED contains all preferences that are provided by recommended
    123   //      policies.
    124   //   DEFAULT contains all application default preference values.
    125   enum PrefStoreType {
    126     // INVALID_STORE is not associated with an actual PrefStore but used as
    127     // an invalid marker, e.g. as a return value.
    128     INVALID_STORE = -1,
    129     MANAGED_STORE = 0,
    130     EXTENSION_STORE,
    131     COMMAND_LINE_STORE,
    132     USER_STORE,
    133     RECOMMENDED_STORE,
    134     DEFAULT_STORE,
    135     PREF_STORE_TYPE_MAX = DEFAULT_STORE
    136   };
    137 
    138   // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors
    139   // the PrefStore for changes, forwarding notifications to PrefValueStore. This
    140   // indirection is here for the sake of disambiguating notifications from the
    141   // individual PrefStores.
    142   class PrefStoreKeeper : public PrefStore::Observer {
    143    public:
    144     PrefStoreKeeper();
    145     virtual ~PrefStoreKeeper();
    146 
    147     // Takes ownership of |pref_store|.
    148     void Initialize(PrefValueStore* store,
    149                     PrefStore* pref_store,
    150                     PrefStoreType type);
    151 
    152     PrefStore* store() { return pref_store_.get(); }
    153     const PrefStore* store() const { return pref_store_.get(); }
    154 
    155    private:
    156     // PrefStore::Observer implementation.
    157     virtual void OnPrefValueChanged(const std::string& key) OVERRIDE;
    158     virtual void OnInitializationCompleted(bool succeeded) OVERRIDE;
    159 
    160     // PrefValueStore this keeper is part of.
    161     PrefValueStore* pref_value_store_;
    162 
    163     // The PrefStore managed by this keeper.
    164     scoped_refptr<PrefStore> pref_store_;
    165 
    166     // Type of the pref store.
    167     PrefStoreType type_;
    168 
    169     DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper);
    170   };
    171 
    172   typedef std::map<std::string, base::Value::Type> PrefTypeMap;
    173 
    174   friend class PrefValueStorePolicyRefreshTest;
    175   FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestPolicyRefresh);
    176   FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
    177                            TestRefreshPolicyPrefsCompletion);
    178   FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
    179                            TestConcurrentPolicyRefresh);
    180 
    181   // Returns true if the preference with the given name has a value in the
    182   // given PrefStoreType, of the same value type as the preference was
    183   // registered with.
    184   bool PrefValueInStore(const char* name, PrefStoreType store) const;
    185 
    186   // Returns true if a preference has an explicit value in any of the
    187   // stores in the range specified by |first_checked_store| and
    188   // |last_checked_store|, even if that value is currently being
    189   // overridden by a higher-priority store.
    190   bool PrefValueInStoreRange(const char* name,
    191                              PrefStoreType first_checked_store,
    192                              PrefStoreType last_checked_store) const;
    193 
    194   // Returns the pref store type identifying the source that controls the
    195   // Preference identified by |name|. If none of the sources has a value,
    196   // INVALID_STORE is returned. In practice, the default PrefStore
    197   // should always have a value for any registered preferencem, so INVALID_STORE
    198   // indicates an error.
    199   PrefStoreType ControllingPrefStoreForPref(const char* name) const;
    200 
    201   // Get a value from the specified |store|.
    202   bool GetValueFromStore(const char* name,
    203                          PrefStoreType store,
    204                          const base::Value** out_value) const;
    205 
    206   // Get a value from the specified |store| if its |type| matches.
    207   bool GetValueFromStoreWithType(const char* name,
    208                                  base::Value::Type type,
    209                                  PrefStoreType store,
    210                                  const base::Value** out_value) const;
    211 
    212   // Called upon changes in individual pref stores in order to determine whether
    213   // the user-visible pref value has changed. Triggers the change notification
    214   // if the effective value of the preference has changed, or if the store
    215   // controlling the pref has changed.
    216   void NotifyPrefChanged(const char* path, PrefStoreType new_store);
    217 
    218   // Called from the PrefStoreKeeper implementation when a pref value for |key|
    219   // changed in the pref store for |type|.
    220   void OnPrefValueChanged(PrefStoreType type, const std::string& key);
    221 
    222   // Handle the event that the store for |type| has completed initialization.
    223   void OnInitializationCompleted(PrefStoreType type, bool succeeded);
    224 
    225   // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take
    226   // ownership of the passed |pref_store|.
    227   void InitPrefStore(PrefStoreType type, PrefStore* pref_store);
    228 
    229   // Checks whether initialization is completed and tells the notifier if that
    230   // is the case.
    231   void CheckInitializationCompleted();
    232 
    233   // Get the PrefStore pointer for the given type. May return NULL if there is
    234   // no PrefStore for that type.
    235   PrefStore* GetPrefStore(PrefStoreType type) {
    236     return pref_stores_[type].store();
    237   }
    238   const PrefStore* GetPrefStore(PrefStoreType type) const {
    239     return pref_stores_[type].store();
    240   }
    241 
    242   // Keeps the PrefStore references in order of precedence.
    243   PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];
    244 
    245   PrefChangedCallback pref_changed_callback_;
    246 
    247   // Used for generating notifications. This is a weak reference,
    248   // since the notifier is owned by the corresponding PrefService.
    249   PrefNotifier* pref_notifier_;
    250 
    251   // A mapping of preference names to their registered types.
    252   PrefTypeMap pref_types_;
    253 
    254   // True if not all of the PrefStores were initialized successfully.
    255   bool initialization_failed_;
    256 
    257   DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
    258 };
    259 
    260 #endif  // BASE_PREFS_PREF_VALUE_STORE_H_
    261