pref_value_store.h revision 5af4e3efaa07e1369024c188538dcf582ed5a21e
1// Copyright (c) 2010 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_PREFS_PREF_VALUE_STORE_H_
6#define CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_
7#pragma once
8
9#include <map>
10#include <string>
11#include <vector>
12
13#include "base/basictypes.h"
14#include "base/gtest_prod_util.h"
15#include "base/ref_counted.h"
16#include "base/scoped_ptr.h"
17#include "base/values.h"
18#ifndef ANDROID
19#include "chrome/browser/browser_thread.h"
20#endif
21#include "chrome/common/pref_store.h"
22
23class FilePath;
24class PrefNotifier;
25class PrefStore;
26class Profile;
27
28// The PrefValueStore manages various sources of values for Preferences
29// (e.g., configuration policies, extensions, and user settings). It returns
30// the value of a Preference from the source with the highest priority, and
31// allows setting user-defined values for preferences that are not managed.
32//
33// Unless otherwise explicitly noted, all of the methods of this class must
34// be called on the UI thread.
35class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
36 public:
37  // In decreasing order of precedence:
38  //   |managed_platform_prefs| contains all managed platform (non-cloud policy)
39  //        preference values.
40  //   |device_management_prefs| contains all device management (cloud policy)
41  //        preference values.
42  //   |extension_prefs| contains preference values set by extensions.
43  //   |command_line_prefs| contains preference values set by command-line
44  //        switches.
45  //   |user_prefs| contains all user-set preference values.
46  //   |recommended_prefs| contains all recommended (policy) preference values.
47  //   |default_prefs| contains application-default preference values. It must
48  //        be non-null if any preferences are to be registered.
49  //
50  // |pref_notifier| facilitates broadcasting preference change notifications
51  // to the world.
52  //
53  // The |profile| parameter is used to construct a replacement device
54  // management pref store. This is done after policy refresh when we swap out
55  // the policy pref stores for new ones, so the |profile| pointer needs to be
56  // kept around for then. It is safe to pass a NULL pointer for local state
57  // preferences.
58  PrefValueStore(PrefStore* managed_platform_prefs,
59                 PrefStore* device_management_prefs,
60                 PrefStore* extension_prefs,
61                 PrefStore* command_line_prefs,
62                 PrefStore* user_prefs,
63                 PrefStore* recommended_prefs,
64                 PrefStore* default_prefs,
65                 PrefNotifier* pref_notifier);
66  virtual ~PrefValueStore();
67
68  // Gets the value for the given preference name that has a valid value type;
69  // that is, the same type the preference was registered with, or NULL for
70  // default values of Dictionaries and Lists. Returns true if a valid value
71  // was found in any of the available PrefStores. Most callers should use
72  // Preference::GetValue() instead of calling this method directly.
73  bool GetValue(const std::string& name, Value** out_value) const;
74
75  // Adds a preference to the mapping of names to types.
76  void RegisterPreferenceType(const std::string& name, Value::ValueType type);
77
78  // Gets the registered value type for the given preference name. Returns
79  // Value::TYPE_NULL if the preference has never been registered.
80  Value::ValueType GetRegisteredType(const std::string& name) const;
81
82  // Returns true if the PrefValueStore contains the given preference (i.e.,
83  // it's been registered), and a value with the correct type has been actively
84  // set in some pref store. The application default specified when the pref was
85  // registered does not count as an "actively set" value, but another pref
86  // store setting a value that happens to be equal to the default does.
87  bool HasPrefPath(const char* name) 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 PrefValueInManagedPlatformStore(const char* name) const;
93  bool PrefValueInDeviceManagementStore(const char* name) const;
94  bool PrefValueInExtensionStore(const char* name) const;
95  bool PrefValueInUserStore(const char* name) const;
96
97  // These methods return true if a preference with the given name is actually
98  // being controlled by the indicated pref store and not being overridden by
99  // a higher-priority source.
100  bool PrefValueFromExtensionStore(const char* name) const;
101  bool PrefValueFromUserStore(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 private:
109  // PrefStores must be listed here in order from highest to lowest priority.
110  //   MANAGED_PLATFORM contains all managed preference values that are
111  //       provided by a platform-specific policy mechanism (e.g. Windows
112  //       Group Policy).
113  //   DEVICE_MANAGEMENT contains all managed preference values supplied
114  //       by the device management server (cloud policy).
115  //   EXTENSION contains preference values set by extensions.
116  //   COMMAND_LINE contains preference values set by command-line switches.
117  //   USER contains all user-set preference values.
118  //   RECOMMENDED contains all recommended (policy) preference values.
119  //   DEFAULT contains all application default preference values.
120  enum PrefStoreType {
121    // INVALID_STORE is not associated with an actual PrefStore but used as
122    // an invalid marker, e.g. as a return value.
123    INVALID_STORE = -1,
124    MANAGED_PLATFORM_STORE = 0,
125    DEVICE_MANAGEMENT_STORE,
126    EXTENSION_STORE,
127    COMMAND_LINE_STORE,
128    USER_STORE,
129    RECOMMENDED_STORE,
130    DEFAULT_STORE,
131    PREF_STORE_TYPE_MAX = DEFAULT_STORE
132  };
133
134  // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors
135  // the PrefStore for changes, forwarding notifications to PrefValueStore. This
136  // indirection is here for the sake of disambiguating notifications from the
137  // individual PrefStores.
138  class PrefStoreKeeper : public PrefStore::Observer {
139   public:
140    PrefStoreKeeper();
141    virtual ~PrefStoreKeeper();
142
143    // Takes ownership of |pref_store|.
144    void Initialize(PrefValueStore* store,
145                    PrefStore* pref_store,
146                    PrefStoreType type);
147
148    PrefStore* store() { return pref_store_.get(); }
149    const PrefStore* store() const { return pref_store_.get(); }
150
151   private:
152    // PrefStore::Observer implementation.
153    virtual void OnPrefValueChanged(const std::string& key);
154    virtual void OnInitializationCompleted();
155
156    // PrefValueStore this keeper is part of.
157    PrefValueStore* pref_value_store_;
158
159    // The PrefStore managed by this keeper.
160    scoped_ptr<PrefStore> pref_store_;
161
162    // Type of the pref store.
163    PrefStoreType type_;
164
165    DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper);
166  };
167
168  typedef std::map<std::string, Value::ValueType> PrefTypeMap;
169
170  friend class PrefValueStorePolicyRefreshTest;
171  FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestPolicyRefresh);
172  FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
173                           TestRefreshPolicyPrefsCompletion);
174  FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
175                           TestConcurrentPolicyRefresh);
176
177  // Returns true if the actual type is a valid type for the expected type when
178  // found in the given store.
179  static bool IsValidType(Value::ValueType expected,
180                          Value::ValueType actual,
181                          PrefStoreType store);
182
183  // Returns true if the preference with the given name has a value in the
184  // given PrefStoreType, of the same value type as the preference was
185  // registered with.
186  bool PrefValueInStore(const char* name, PrefStoreType store) const;
187
188  // Returns true if a preference has an explicit value in any of the
189  // stores in the range specified by |first_checked_store| and
190  // |last_checked_store|, even if that value is currently being
191  // overridden by a higher-priority store.
192  bool PrefValueInStoreRange(const char* name,
193                             PrefStoreType first_checked_store,
194                             PrefStoreType last_checked_store) const;
195
196  // Returns the pref store type identifying the source that controls the
197  // Preference identified by |name|. If none of the sources has a value,
198  // INVALID_STORE is returned. In practice, the default PrefStore
199  // should always have a value for any registered preferencem, so INVALID_STORE
200  // indicates an error.
201  PrefStoreType ControllingPrefStoreForPref(const char* name) const;
202
203  // Get a value from the specified store type.
204  bool GetValueFromStore(const char* name,
205                         PrefStoreType store,
206                         Value** out_value) const;
207
208  // Called upon changes in individual pref stores in order to determine whether
209  // the user-visible pref value has changed. Triggers the change notification
210  // if the effective value of the preference has changed, or if the store
211  // controlling the pref has changed.
212  void NotifyPrefChanged(const char* path, PrefStoreType new_store);
213
214  // Called from the PrefStoreKeeper implementation when a pref value for |key|
215  // changed in the pref store for |type|.
216  void OnPrefValueChanged(PrefStoreType type, const std::string& key);
217
218  // Handle the event that the store for |type| has completed initialization.
219  void OnInitializationCompleted(PrefStoreType type);
220
221  // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take
222  // ownership of the passed |pref_store|.
223  void InitPrefStore(PrefStoreType type, PrefStore* pref_store);
224
225  // Checks whether initialization is completed and tells the notifier if that
226  // is the case.
227  void CheckInitializationCompleted();
228
229  // Get the PrefStore pointer for the given type. May return NULL if there is
230  // no PrefStore for that type.
231  PrefStore* GetPrefStore(PrefStoreType type) {
232    return pref_stores_[type].store();
233  }
234  const PrefStore* GetPrefStore(PrefStoreType type) const {
235    return pref_stores_[type].store();
236  }
237
238  // Keeps the PrefStore references in order of precedence.
239  PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];
240
241  // Used for generating PREF_CHANGED and PREF_INITIALIZATION_COMPLETED
242  // notifications. This is a weak reference, since the notifier is owned by the
243  // corresponding PrefService.
244  PrefNotifier* pref_notifier_;
245
246  // A mapping of preference names to their registered types.
247  PrefTypeMap pref_types_;
248
249  DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
250};
251
252#endif  // CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_
253