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