1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_PREFS_PREF_VALUE_STORE_H_
6 #define COMPONENTS_PREFS_PREF_VALUE_STORE_H_
12 #include <type_traits>
15 #include "base/functional/callback.h"
16 #include "base/memory/raw_ptr.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/strings/string_piece.h"
19 #include "base/values.h"
20 #include "components/prefs/pref_store.h"
21 #include "components/prefs/prefs_export.h"
26 // The PrefValueStore manages various sources of values for Preferences
27 // (e.g., configuration policies, extensions, and user settings). It returns
28 // the value of a Preference from the source with the highest priority, and
29 // allows setting user-defined values for preferences that are not managed.
31 // Unless otherwise explicitly noted, all of the methods of this class must
32 // be called on the UI thread.
33 class COMPONENTS_PREFS_EXPORT PrefValueStore {
35 using PrefChangedCallback = base::RepeatingCallback<void(const std::string&)>;
37 // PrefStores must be listed here in order from highest to lowest priority.
38 // MANAGED contains all managed preferences that are provided by
39 // mandatory policies (e.g. Windows Group Policy or cloud policy).
40 // SUPERVISED_USER contains preferences that are valid for supervised users.
41 // EXTENSION contains preferences set by extensions.
42 // STANDALONE_BROWSER contains system preferences inherited from a separate
43 // Chrome instance. One relevant source is extension prefs in lacros
44 // passed to ash, so these prefs have similar precedence to extension
46 // COMMAND_LINE contains preferences set by command-line switches.
47 // USER contains all user-set preferences.
48 // RECOMMENDED contains all preferences that are provided by recommended
50 // DEFAULT contains all application default preferences.
52 // INVALID_STORE is not associated with an actual PrefStore but used as
53 // an invalid marker, e.g. as a return value.
56 SUPERVISED_USER_STORE,
58 STANDALONE_BROWSER_STORE,
63 PREF_STORE_TYPE_MAX = DEFAULT_STORE
66 // In decreasing order of precedence:
67 // |managed_prefs| contains all preferences from mandatory policies.
68 // |supervised_user_prefs| contains all preferences from supervised user
69 // settings, i.e. settings configured for a supervised user by their
71 // |extension_prefs| contains preference values set by extensions.
72 // |command_line_prefs| contains preference values set by command-line
74 // |user_prefs| contains all user-set preference values.
75 // |recommended_prefs| contains all preferences from recommended policies.
76 // |default_prefs| contains application-default preference values. It must
77 // be non-null if any preferences are to be registered.
79 // |pref_notifier| facilitates broadcasting preference change notifications
81 PrefValueStore(PrefStore* managed_prefs,
82 PrefStore* supervised_user_prefs,
83 PrefStore* extension_prefs,
84 PrefStore* standalone_browser_prefs,
85 PrefStore* command_line_prefs,
86 PrefStore* user_prefs,
87 PrefStore* recommended_prefs,
88 PrefStore* default_prefs,
89 PrefNotifier* pref_notifier);
91 PrefValueStore(const PrefValueStore&) = delete;
92 PrefValueStore& operator=(const PrefValueStore&) = delete;
94 virtual ~PrefValueStore();
96 // Creates a clone of this PrefValueStore with PrefStores overwritten
97 // by the parameters passed, if unequal NULL.
99 // The new PrefValueStore is passed the |delegate| in its constructor.
100 std::unique_ptr<PrefValueStore> CloneAndSpecialize(
101 PrefStore* managed_prefs,
102 PrefStore* supervised_user_prefs,
103 PrefStore* extension_prefs,
104 PrefStore* standalone_browser_prefs,
105 PrefStore* command_line_prefs,
106 PrefStore* user_prefs,
107 PrefStore* recommended_prefs,
108 PrefStore* default_prefs,
109 PrefNotifier* pref_notifier);
111 // Returns the pref store type identifying the source that controls the
112 // Preference identified by |name|. If none of the sources has a value,
113 // INVALID_STORE is returned. In practice, the default PrefStore
114 // should always have a value for any registered preferencem, so INVALID_STORE
115 // indicates an error.
116 PrefStoreType ControllingPrefStoreForPref(const std::string& name) const;
118 // Gets the value for the given preference name that has the specified value
119 // type. Values stored in a PrefStore that have the matching |name| but
120 // a non-matching |type| are silently skipped. Returns true if a valid value
121 // was found in any of the available PrefStores. Most callers should use
122 // Preference::GetValue() instead of calling this method directly.
123 bool GetValue(base::StringPiece name,
124 base::Value::Type type,
125 const base::Value** out_value) const;
127 // Gets the recommended value for the given preference name that has the
128 // specified value type. A value stored in the recommended PrefStore that has
129 // the matching |name| but a non-matching |type| is silently ignored. Returns
130 // true if a valid value was found. Most callers should use
131 // Preference::GetRecommendedValue() instead of calling this method directly.
132 bool GetRecommendedValue(const std::string& name,
133 base::Value::Type type,
134 const base::Value** out_value) const;
136 // These methods return true if a preference with the given name is in the
137 // indicated pref store, even if that value is currently being overridden by
138 // a higher-priority source.
139 bool PrefValueInManagedStore(const std::string& name) const;
140 bool PrefValueInSupervisedStore(const std::string& name) const;
141 bool PrefValueInExtensionStore(const std::string& name) const;
142 bool PrefValueInUserStore(const std::string& name) const;
143 bool PrefValueInStandaloneBrowserStore(const std::string& name) const;
145 // These methods return true if a preference with the given name is actually
146 // being controlled by the indicated pref store and not being overridden by
147 // a higher-priority source.
148 bool PrefValueFromExtensionStore(const std::string& name) const;
149 bool PrefValueFromUserStore(const std::string& name) const;
150 bool PrefValueFromRecommendedStore(const std::string& name) const;
151 bool PrefValueFromDefaultStore(const std::string& name) const;
152 bool PrefValueFromStandaloneBrowserStore(const std::string& name) const;
154 // Check whether a Preference value is modifiable by the user, i.e. whether
155 // there is no higher-priority source controlling it.
156 bool PrefValueUserModifiable(const std::string& name) const;
158 // Check whether a Preference value is modifiable by an extension, i.e.
159 // whether there is no higher-priority source controlling it.
160 bool PrefValueExtensionModifiable(const std::string& name) const;
162 // Check whether a Preference value is modifiable by a standalone browser
163 // (lacros), i.e. whether there is no higher-priority source controlling it.
164 bool PrefValueStandaloneBrowserModifiable(const std::string& name) const;
166 // Update the command line PrefStore with |command_line_prefs|.
167 void UpdateCommandLinePrefStore(PrefStore* command_line_prefs);
169 bool IsInitializationComplete() const;
172 // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors
173 // the PrefStore for changes, forwarding notifications to PrefValueStore. This
174 // indirection is here for the sake of disambiguating notifications from the
175 // individual PrefStores.
176 class PrefStoreKeeper : public PrefStore::Observer {
180 PrefStoreKeeper(const PrefStoreKeeper&) = delete;
181 PrefStoreKeeper& operator=(const PrefStoreKeeper&) = delete;
183 ~PrefStoreKeeper() override;
185 // Takes ownership of |pref_store|.
186 void Initialize(PrefValueStore* store,
187 PrefStore* pref_store,
190 PrefStore* store() { return pref_store_.get(); }
191 const PrefStore* store() const { return pref_store_.get(); }
194 // PrefStore::Observer implementation.
195 void OnPrefValueChanged(const std::string& key) override;
196 void OnInitializationCompleted(bool succeeded) override;
198 // PrefValueStore this keeper is part of.
199 raw_ptr<PrefValueStore> pref_value_store_;
201 // The PrefStore managed by this keeper.
202 scoped_refptr<PrefStore> pref_store_;
204 // Type of the pref store.
208 typedef std::map<std::string, base::Value::Type> PrefTypeMap;
210 // Returns true if the preference with the given name has a value in the
211 // given PrefStoreType, of the same value type as the preference was
213 bool PrefValueInStore(const std::string& name, PrefStoreType store) const;
215 // Returns true if a preference has an explicit value in any of the
216 // stores in the range specified by |first_checked_store| and
217 // |last_checked_store|, even if that value is currently being
218 // overridden by a higher-priority store.
219 bool PrefValueInStoreRange(const std::string& name,
220 PrefStoreType first_checked_store,
221 PrefStoreType last_checked_store) const;
223 // Get a value from the specified |store|.
224 bool GetValueFromStore(base::StringPiece name,
226 const base::Value** out_value) const;
228 // Get a value from the specified |store| if its |type| matches.
229 bool GetValueFromStoreWithType(base::StringPiece name,
230 base::Value::Type type,
232 const base::Value** out_value) const;
234 // Called upon changes in individual pref stores in order to determine whether
235 // the user-visible pref value has changed. Triggers the change notification
236 // if the effective value of the preference has changed, or if the store
237 // controlling the pref has changed.
238 void NotifyPrefChanged(const std::string& path, PrefStoreType new_store);
240 // Called from the PrefStoreKeeper implementation when a pref value for |key|
241 // changed in the pref store for |type|.
242 void OnPrefValueChanged(PrefStoreType type, const std::string& key);
244 // Handle the event that the store for |type| has completed initialization.
245 void OnInitializationCompleted(PrefStoreType type, bool succeeded);
247 // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take
248 // ownership of the passed |pref_store|.
249 void InitPrefStore(PrefStoreType type, PrefStore* pref_store);
251 // Checks whether initialization is completed and tells the notifier if that
253 void CheckInitializationCompleted();
255 // Get the PrefStore pointer for the given type. May return NULL if there is
256 // no PrefStore for that type.
257 PrefStore* GetPrefStore(PrefStoreType type) {
258 return pref_stores_[type].store();
260 const PrefStore* GetPrefStore(PrefStoreType type) const {
261 return pref_stores_[type].store();
264 // Keeps the PrefStore references in order of precedence.
265 PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];
267 // Used for generating notifications. This is a weak reference,
268 // since the notifier is owned by the corresponding PrefService.
269 raw_ptr<PrefNotifier> pref_notifier_;
271 // A mapping of preference names to their registered types.
272 PrefTypeMap pref_types_;
274 // True if not all of the PrefStores were initialized successfully.
275 bool initialization_failed_;
281 struct hash<PrefValueStore::PrefStoreType> {
282 size_t operator()(PrefValueStore::PrefStoreType type) const {
284 std::underlying_type<PrefValueStore::PrefStoreType>::type>()(type);
290 #endif // COMPONENTS_PREFS_PREF_VALUE_STORE_H_