pref_value_store.h revision 62178e3990b32e9c89bb7d6f06605044b31adba2
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/callback.h"
15#include "base/gtest_prod_util.h"
16#include "base/ref_counted.h"
17#include "base/scoped_ptr.h"
18#include "base/values.h"
19#ifndef ANDROID
20#include "chrome/browser/browser_thread.h"
21#endif
22#include "chrome/browser/prefs/pref_notifier.h"
23#include "chrome/common/pref_store.h"
24
25class FilePath;
26class PrefStore;
27class Profile;
28
29// The PrefValueStore manages various sources of values for Preferences
30// (e.g., configuration policies, extensions, and user settings). It returns
31// the value of a Preference from the source with the highest priority, and
32// allows setting user-defined values for preferences that are not managed.
33// See PrefNotifier for a list of the available preference sources (PrefStores)
34// and their descriptions.
35//
36// Unless otherwise explicitly noted, all of the methods of this class must
37// be called on the UI thread.
38class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
39 public:
40  // Returns a new PrefValueStore with all applicable PrefStores. The
41  // |pref_filename| points to the user preference file. The |profile| is the
42  // one to which these preferences apply; it may be NULL if we're dealing
43  // with the local state. If |pref_filename| is empty, the user PrefStore will
44  // not be created. If |user_only| is true, no PrefStores will be created
45  // other than the user and default PrefStores. This should not normally be
46  // called directly: the usual way to create a PrefValueStore is by creating a
47  // PrefService.
48  static PrefValueStore* CreatePrefValueStore(const FilePath& pref_filename,
49                                              Profile* profile,
50                                              bool user_only);
51
52#ifdef ANDROID
53  virtual
54#endif
55  ~PrefValueStore();
56
57  // Gets the value for the given preference name that has a valid value type;
58  // that is, the same type the preference was registered with, or NULL for
59  // default values of Dictionaries and Lists. Returns true if a valid value
60  // was found in any of the available PrefStores. Most callers should use
61  // Preference::GetValue() instead of calling this method directly.
62  bool GetValue(const std::string& name, Value** out_value) const;
63
64  // Same as GetValue but only searches USER_STORE.
65  bool GetUserValue(const std::string& name, Value** out_value) const;
66
67  // Adds a preference to the mapping of names to types.
68  void RegisterPreferenceType(const std::string& name, Value::ValueType type);
69
70  // Gets the registered value type for the given preference name. Returns
71  // Value::TYPE_NULL if the preference has never been registered.
72  Value::ValueType GetRegisteredType(const std::string& name) const;
73
74  // Read preference values into the three PrefStores so that they are available
75  // through the GetValue method. Return the first error that occurs (but
76  // continue reading the remaining PrefStores).
77  PrefStore::PrefReadError ReadPrefs();
78
79  // Persists prefs (to disk or elsewhere). Returns true if writing values was
80  // successful. In practice, only the user prefs are expected to be written
81  // out.
82  bool WritePrefs();
83
84  // Calls the method ScheduleWritePrefs on the PrefStores. In practice, only
85  // the user prefs are expected to be written out.
86  void ScheduleWritePrefs();
87
88  // Returns true if the PrefValueStore contains the given preference (i.e.,
89  // it's been registered), and a value with the correct type has been actively
90  // set in some pref store. The application default specified when the pref was
91  // registered does not count as an "actively set" value, but another pref
92  // store setting a value that happens to be equal to the default does.
93  bool HasPrefPath(const char* name) const;
94
95  // Called by the PrefNotifier when the value of the preference at |path| has
96  // changed, been added, or been removed in one of the PrefStores. The
97  // |new_store| is the PrefStoreType of the caller. Returns true if the
98  // effective value of the preference has changed, or if the store controlling
99  // the pref has changed. Virtual so it can be mocked for a unit test.
100  virtual bool PrefHasChanged(const char* path,
101                              PrefNotifier::PrefStoreType new_store);
102
103  // Returns true if the PrefValueStore is read-only.  Because the managed
104  // platform, device management and recommended PrefStores are always
105  // read-only, the PrefValueStore as a whole is read-only if the PrefStore
106  // containing the user preferences is read-only.
107  bool ReadOnly();
108
109  // Alters the user-defined value of a preference. Even if the preference is
110  // managed this method allows the user-defined value of the preference to be
111  // set. But GetValue calls will not return this value as long as the
112  // preference is managed. Instead GetValue will return the managed value
113  // of the preference. Note that the PrefValueStore takes the ownership of
114  // the value referenced by |in_value|. It is an error to call this when no
115  // user PrefStore has been set. Returns true if the user-set value of the
116  // preference was newly added or changed.
117  bool SetUserPrefValue(const char* name, Value* in_value);
118
119  // Removes a value from the user PrefStore. If a preference is managed
120  // this function should have no visible effect. Returns true if there was a
121  // user-set value to be removed.
122  bool RemoveUserPrefValue(const char* name);
123
124  // Sets a value in the DefaultPrefStore, which takes ownership of the Value.
125  void SetDefaultPrefValue(const char* name, Value* in_value);
126
127  // These methods return true if a preference with the given name is in the
128  // indicated pref store, even if that value is currently being overridden by
129  // a higher-priority source.
130  bool PrefValueInManagedPlatformStore(const char* name) const;
131  bool PrefValueInDeviceManagementStore(const char* name) const;
132  bool PrefValueInExtensionStore(const char* name) const;
133  bool PrefValueInUserStore(const char* name) const;
134
135  // Returns true if a preference has an explicit value in any of the
136  // stores in the range specified by |first_checked_store| and
137  // |last_checked_store|, even if that value is currently being
138  // overridden by a higher-priority store.
139  bool PrefValueInStoreRange(const char* name,
140                             PrefNotifier::PrefStoreType first_checked_store,
141                             PrefNotifier::PrefStoreType last_checked_store);
142
143  // These methods return true if a preference with the given name is actually
144  // being controlled by the indicated pref store and not being overridden by
145  // a higher-priority source.
146  bool PrefValueFromExtensionStore(const char* name) const;
147  bool PrefValueFromUserStore(const char* name) const;
148  bool PrefValueFromDefaultStore(const char* name) const;
149
150  // Check whether a Preference value is modifiable by the user, i.e. whether
151  // there is no higher-priority source controlling it.
152  bool PrefValueUserModifiable(const char* name) const;
153
154  // Returns the pref store type identifying the source that controls the
155  // Preference identified by |name|. If none of the sources has a value,
156  // PrefNotifier::INVALID_STORE is returned. In practice, the default PrefStore
157  // should always have a value for any registered preferencem, so INVALID_STORE
158  // indicates an error.
159  PrefNotifier::PrefStoreType ControllingPrefStoreForPref(
160      const char* name) const;
161
162  // Signature of callback triggered after policy refresh. Parameter is not
163  // passed as reference to prevent passing along a pointer to a set whose
164  // lifecycle is managed in another thread.
165  typedef Callback1<std::vector<std::string> >::Type AfterRefreshCallback;
166
167#ifndef ANDROID
168  // Called as a result of a notification of policy change. Triggers a reload of
169  // managed platform, device management and recommended preferences from policy
170  // from a Task on the FILE thread. The Task will take ownership of the
171  // |callback|. |callback| is called with the set of preferences changed by the
172  // policy refresh. |callback| is called on the caller's thread as a Task
173  // after RefreshPolicyPrefs has returned.
174  void RefreshPolicyPrefs(AfterRefreshCallback* callback);
175#endif
176
177  // Returns true if there are proxy preferences in user-modifiable
178  // preference stores (e.g. CommandLinePrefStore, ExtensionPrefStore)
179  // that conflict with proxy settings specified by proxy policy.
180  bool HasPolicyConflictingUserProxySettings();
181
182      protected:
183  // In decreasing order of precedence:
184  //   |managed_platform_prefs| contains all managed platform (non-cloud policy)
185  //        preference values.
186  //   |device_management_prefs| contains all device management (cloud policy)
187  //        preference values.
188  //   |extension_prefs| contains preference values set by extensions.
189  //   |command_line_prefs| contains preference values set by command-line
190  //        switches.
191  //   |user_prefs| contains all user-set preference values.
192  //   |recommended_prefs| contains all recommended (policy) preference values.
193  //   |default_prefs| contains application-default preference values. It must
194  //        be non-null if any preferences are to be registered.
195  //
196  // This constructor should only be used internally, or by subclasses in
197  // testing. The usual way to create a PrefValueStore is by creating a
198  // PrefService.
199  PrefValueStore(PrefStore* managed_platform_prefs,
200                 PrefStore* device_management_prefs,
201                 PrefStore* extension_prefs,
202                 PrefStore* command_line_prefs,
203                 PrefStore* user_prefs,
204                 PrefStore* recommended_prefs,
205                 PrefStore* default_prefs);
206
207 private:
208  friend class PrefValueStoreTest;
209  FRIEND_TEST_ALL_PREFIXES(PrefValueStoreTest,
210                           TestRefreshPolicyPrefsCompletion);
211
212  scoped_ptr<PrefStore> pref_stores_[PrefNotifier::PREF_STORE_TYPE_MAX + 1];
213
214  // A mapping of preference names to their registered types.
215  typedef std::map<std::string, Value::ValueType> PrefTypeMap;
216  PrefTypeMap pref_types_;
217
218  // Returns true if the preference with the given name has a value in the
219  // given PrefStoreType, of the same value type as the preference was
220  // registered with.
221  bool PrefValueInStore(const char* name,
222                        PrefNotifier::PrefStoreType store) const;
223
224  // Get a value from the specified store type.
225  bool GetValueFromStore(const char* name,
226                         PrefNotifier::PrefStoreType store,
227                         Value** out_value) const;
228
229#ifndef ANDROID
230  // Called during policy refresh after ReadPrefs completes on the thread
231  // that initiated the policy refresh. RefreshPolicyPrefsCompletion takes
232  // ownership of the |callback| object.
233  void RefreshPolicyPrefsCompletion(
234      PrefStore* new_managed_platform_pref_store,
235      PrefStore* new_device_management_pref_store,
236      PrefStore* new_recommended_pref_store,
237      AfterRefreshCallback* callback);
238
239  // Called during policy refresh to do the ReadPrefs on the FILE thread.
240  // RefreshPolicyPrefsOnFileThread takes ownership of the |callback| object.
241  void RefreshPolicyPrefsOnFileThread(
242      BrowserThread::ID calling_thread_id,
243      PrefStore* new_managed_platform_pref_store,
244      PrefStore* new_device_management_pref_store,
245      PrefStore* new_recommended_pref_store,
246      AfterRefreshCallback* callback);
247#endif
248
249  DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
250};
251
252#endif  // CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_
253