pref_service.h revision b401d151b3ce4e803c0e71a2381d4a3735c3829f
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// This provides a way to access the application's current preferences.
6
7#ifndef CHROME_BROWSER_PREFS_PREF_SERVICE_H_
8#define CHROME_BROWSER_PREFS_PREF_SERVICE_H_
9#pragma once
10
11#include <set>
12#include <string>
13
14#include "base/non_thread_safe.h"
15#include "base/ref_counted.h"
16#include "base/scoped_ptr.h"
17#include "base/values.h"
18
19class DefaultPrefStore;
20class FilePath;
21class NotificationObserver;
22class PersistentPrefStore;
23class PrefChangeObserver;
24class PrefNotifier;
25class PrefNotifierImpl;
26class PrefStore;
27class PrefValueStore;
28class Profile;
29
30namespace subtle {
31class PrefMemberBase;
32};
33
34class PrefService : public NonThreadSafe {
35 public:
36  // A helper class to store all the information associated with a preference.
37  class Preference {
38   public:
39
40    // The type of the preference is determined by the type with which it is
41    // registered. This type needs to be a boolean, integer, real, string,
42    // dictionary (a branch), or list.  You shouldn't need to construct this on
43    // your own; use the PrefService::Register*Pref methods instead.
44    Preference(const PrefService* service,
45               const char* name);
46    ~Preference() {}
47
48    // Returns the name of the Preference (i.e., the key, e.g.,
49    // browser.window_placement).
50    const std::string name() const { return name_; }
51
52    // Returns the registered type of the preference.
53    Value::ValueType GetType() const;
54
55    // Returns the value of the Preference, falling back to the registered
56    // default value if no other has been set.
57    const Value* GetValue() const;
58
59    // Returns true if the Preference is managed, i.e. set by an admin policy.
60    // Since managed prefs have the highest priority, this also indicates
61    // whether the pref is actually being controlled by the policy setting.
62    bool IsManaged() const;
63
64    // Returns true if the Preference has a value set by an extension, even if
65    // that value is being overridden by a higher-priority source.
66    bool HasExtensionSetting() const;
67
68    // Returns true if the Preference has a user setting, even if that value is
69    // being overridden by a higher-priority source.
70    bool HasUserSetting() const;
71
72    // Returns true if the Preference value is currently being controlled by an
73    // extension, and not by any higher-priority source.
74    bool IsExtensionControlled() const;
75
76    // Returns true if the Preference value is currently being controlled by a
77    // user setting, and not by any higher-priority source.
78    bool IsUserControlled() const;
79
80    // Returns true if the Preference is currently using its default value,
81    // and has not been set by any higher-priority source (even with the same
82    // value).
83    bool IsDefaultValue() const;
84
85    // Returns true if the user can change the Preference value, which is the
86    // case if no higher-priority source than the user store controls the
87    // Preference.
88    bool IsUserModifiable() const;
89
90   private:
91    friend class PrefService;
92
93    std::string name_;
94
95    // Reference to the PrefService in which this pref was created.
96    const PrefService* pref_service_;
97
98    DISALLOW_COPY_AND_ASSIGN(Preference);
99  };
100
101  // Factory method that creates a new instance of a PrefService with the
102  // applicable PrefStores. The |pref_filename| points to the user preference
103  // file. The |profile| is the one to which these preferences apply; it may be
104  // NULL if we're dealing with the local state. This is the usual way to create
105  // a new PrefService. |extension_pref_store| is used as the source for
106  // extension-controlled preferences and may be NULL. The PrefService takes
107  // ownership of |extension_pref_store|.
108  static PrefService* CreatePrefService(const FilePath& pref_filename,
109                                        PrefStore* extension_pref_store,
110                                        Profile* profile);
111
112  virtual ~PrefService();
113
114  // Reloads the data from file. This should only be called when the importer
115  // is running during first run, and the main process may not change pref
116  // values while the importer process is running. Returns true on success.
117  bool ReloadPersistentPrefs();
118
119  // Returns true if the preference for the given preference name is available
120  // and is managed.
121  bool IsManagedPreference(const char* pref_name) const;
122
123  // Writes the data to disk. The return value only reflects whether
124  // serialization was successful; we don't know whether the data actually made
125  // it on disk (since it's on a different thread).  This should only be used if
126  // we need to save immediately (basically, during shutdown).  Otherwise, you
127  // should use ScheduleSavePersistentPrefs.
128  bool SavePersistentPrefs();
129
130  // Serializes the data and schedules save using ImportantFileWriter.
131  void ScheduleSavePersistentPrefs();
132
133  // Make the PrefService aware of a pref.
134  void RegisterBooleanPref(const char* path, bool default_value);
135  void RegisterIntegerPref(const char* path, int default_value);
136  void RegisterRealPref(const char* path, double default_value);
137  void RegisterStringPref(const char* path, const std::string& default_value);
138  void RegisterFilePathPref(const char* path, const FilePath& default_value);
139  void RegisterListPref(const char* path);
140  void RegisterDictionaryPref(const char* path);
141
142  // These variants use a default value from the locale dll instead.
143  void RegisterLocalizedBooleanPref(const char* path,
144                                    int locale_default_message_id);
145  void RegisterLocalizedIntegerPref(const char* path,
146                                    int locale_default_message_id);
147  void RegisterLocalizedRealPref(const char* path,
148                                 int locale_default_message_id);
149  void RegisterLocalizedStringPref(const char* path,
150                                   int locale_default_message_id);
151
152  // If the path is valid and the value at the end of the path matches the type
153  // specified, it will return the specified value.  Otherwise, the default
154  // value (set when the pref was registered) will be returned.
155  bool GetBoolean(const char* path) const;
156  int GetInteger(const char* path) const;
157  double GetReal(const char* path) const;
158  std::string GetString(const char* path) const;
159  FilePath GetFilePath(const char* path) const;
160
161  // Returns the branch if it exists.  If it's not a branch or the branch does
162  // not exist, returns NULL.
163  const DictionaryValue* GetDictionary(const char* path) const;
164  const ListValue* GetList(const char* path) const;
165
166  // Removes a user pref and restores the pref to its default value.
167  void ClearPref(const char* path);
168
169  // If the path is valid (i.e., registered), update the pref value in the user
170  // prefs. Seting a null value on a preference of List or Dictionary type is
171  // equivalent to removing the user value for that preference, allowing the
172  // default value to take effect unless another value takes precedence.
173  void Set(const char* path, const Value& value);
174  void SetBoolean(const char* path, bool value);
175  void SetInteger(const char* path, int value);
176  void SetReal(const char* path, double value);
177  void SetString(const char* path, const std::string& value);
178  void SetFilePath(const char* path, const FilePath& value);
179
180  // Int64 helper methods that actually store the given value as a string.
181  // Note that if obtaining the named value via GetDictionary or GetList, the
182  // Value type will be TYPE_STRING.
183  void SetInt64(const char* path, int64 value);
184  int64 GetInt64(const char* path) const;
185  void RegisterInt64Pref(const char* path, int64 default_value);
186
187  // Used to set the value of dictionary or list values in the pref tree.  This
188  // will create a dictionary or list if one does not exist in the pref tree.
189  // This method returns NULL only if you're requesting an unregistered pref or
190  // a non-dict/non-list pref.
191  // WARNING: Changes to the dictionary or list will not automatically notify
192  // pref observers.
193  // Use a ScopedPrefUpdate to update observers on changes.
194  // These should really be GetUserMutable... since we will only ever get
195  // a mutable from the user preferences store.
196  DictionaryValue* GetMutableDictionary(const char* path);
197  ListValue* GetMutableList(const char* path);
198
199  // Returns true if a value has been set for the specified path.
200  // NOTE: this is NOT the same as FindPreference. In particular
201  // FindPreference returns whether RegisterXXX has been invoked, where as
202  // this checks if a value exists for the path.
203  bool HasPrefPath(const char* path) const;
204
205  class PreferencePathComparator {
206   public:
207    bool operator() (Preference* lhs, Preference* rhs) const {
208      return lhs->name() < rhs->name();
209    }
210  };
211  typedef std::set<Preference*, PreferencePathComparator> PreferenceSet;
212  const PreferenceSet& preference_set() const { return prefs_; }
213
214  // A helper method to quickly look up a preference.  Returns NULL if the
215  // preference is not registered.
216  const Preference* FindPreference(const char* pref_name) const;
217
218  bool ReadOnly() const;
219
220#ifndef ANDROID
221  PrefNotifier* pref_notifier() const { return pref_notifier_.get(); }
222#endif
223
224  // TODO(mnissler): This should not be public. Change client code to call a
225  // preference setter or use ScopedPrefUpdate.
226  PrefNotifier* pref_notifier() const;
227
228 protected:
229  // Construct a new pref service, specifying the pref sources as explicit
230  // PrefStore pointers. This constructor is what CreatePrefService() ends up
231  // calling. It's also used for unit tests.
232  PrefService(PrefStore* managed_platform_prefs,
233              PrefStore* device_management_prefs,
234              PrefStore* extension_prefs,
235              PrefStore* command_line_prefs,
236              PersistentPrefStore* user_prefs,
237              PrefStore* recommended_prefs);
238
239#ifndef ANDROID
240  // The PrefNotifier handles registering and notifying preference observers.
241  // It is created and owned by this PrefService. Subclasses may access it for
242  // unit testing.
243  scoped_ptr<PrefNotifierImpl> pref_notifier_;
244#endif
245
246 private:
247  friend class PrefServiceMockBuilder;
248
249  // Registration of pref change observers must be done using the
250  // PrefChangeRegistrar, which is declared as a friend here to grant it
251  // access to the otherwise protected members Add/RemovePrefObserver.
252  // PrefMember registers for preferences changes notification directly to
253  // avoid the storage overhead of the registrar, so its base class must be
254  // declared as a friend, too.
255  friend class PrefChangeRegistrar;
256  friend class subtle::PrefMemberBase;
257
258#ifndef ANDROID
259  // If the pref at the given path changes, we call the observer's Observe
260  // method with PREF_CHANGED. Note that observers should not call these methods
261  // directly but rather use a PrefChangeRegistrar to make sure the observer
262  // gets cleaned up properly.
263  virtual void AddPrefObserver(const char* path, NotificationObserver* obs);
264  virtual void RemovePrefObserver(const char* path, NotificationObserver* obs);
265#endif
266
267  // Add a preference to the PreferenceMap.  If the pref already exists, return
268  // false.  This method takes ownership of |default_value|.
269  void RegisterPreference(const char* path, Value* default_value);
270
271  // Sets the value for this pref path in the user pref store and informs the
272  // PrefNotifier of the change.
273  void SetUserPrefValue(const char* path, Value* new_value);
274
275  // Load preferences from storage, attempting to diagnose and handle errors.
276  // This should only be called from the constructor.
277  void InitFromStorage();
278
279  // The PrefValueStore provides prioritized preference values. It is created
280  // and owned by this PrefService. Subclasses may access it for unit testing.
281  scoped_refptr<PrefValueStore> pref_value_store_;
282
283  // The persistent pref store used for actual user data.
284  PersistentPrefStore* user_pref_store_;
285
286  // Points to the default pref store we passed to the PrefValueStore.
287  DefaultPrefStore* default_store_;
288
289  // A set of all the registered Preference objects.
290  PreferenceSet prefs_;
291
292  DISALLOW_COPY_AND_ASSIGN(PrefService);
293};
294
295#endif  // CHROME_BROWSER_PREFS_PREF_SERVICE_H_
296