summaryrefslogtreecommitdiffstats
path: root/chrome/browser/pref_value_store.h
blob: c1901f644c5db9c6a69e4fee016665b5508a2745 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_PREF_VALUE_STORE_H_
#define CHROME_BROWSER_PREF_VALUE_STORE_H_
#pragma once

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/ref_counted.h"
#include "base/string16.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/pref_notifier.h"
#include "chrome/common/pref_store.h"

class PrefStore;
class Profile;

// The PrefValueStore manages various sources of values for Preferences
// (e.g., configuration policies, extensions, and user settings). It returns
// the value of a Preference from the source with the highest priority, and
// allows setting user-defined values for preferences that are not managed.
// See PrefNotifier for a list of the available preference sources (PrefStores)
// and their descriptions.
//
// Unless otherwise explicitly noted, all of the methods of this class must
// be called on the UI thread.
class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
 public:
  // Returns a new PrefValueStore with all applicable PrefStores. The
  // |pref_filename| points to the user preference file. The |profile| is the
  // one to which these preferences apply; it may be NULL if we're dealing
  // with the local state. If |pref_filename| is empty, the user PrefStore will
  // not be created. If |user_only| is true, no PrefStores will be created
  // other than the user PrefStore (if |pref_filename| is not empty). This
  // should not normally be called directly: the usual way to create a
  // PrefValueStore is by creating a PrefService.
  static PrefValueStore* CreatePrefValueStore(const FilePath& pref_filename,
                                              Profile* profile,
                                              bool user_only);

  ~PrefValueStore();

  // Get the preference value for the given preference name.
  // Return true if a value for the given preference name was found.
  bool GetValue(const std::string& name, Value** out_value) const;

  // Read preference values into the three PrefStores so that they are available
  // through the GetValue method. Return the first error that occurs (but
  // continue reading the remaining PrefStores).
  PrefStore::PrefReadError ReadPrefs();

  // Persists prefs (to disk or elsewhere). Returns true if writing values was
  // successful. In practice, only the user prefs are expected to be written
  // out.
  bool WritePrefs();

  // Calls the method ScheduleWritePrefs on the PrefStores. In practice, only
  // the user prefs are expected to be written out.
  void ScheduleWritePrefs();

  // Returns true if the PrefValueStore contains the given preference.
  bool HasPrefPath(const char* name) const;

  // Returns true if the effective value of the preference has changed from its
  // |old_value|. Virtual so it can be mocked for a unit test.
  // TODO(pamg): Also return true when the controlling PrefStore changes.
  virtual bool PrefHasChanged(const char* path, const Value* old_value);

  // Returns true if the PrefValueStore is read-only.
  // Because the managed and recommended PrefStores are always read-only, the
  // PrefValueStore as a whole is read-only if the PrefStore containing the user
  // preferences is read-only.
  bool ReadOnly();

  // Alters the user-defined value of a preference. Even if the preference is
  // managed this method allows the user-defined value of the preference to be
  // set. But GetValue calls will not return this value as long as the
  // preference is managed. Instead GetValue will return the managed value
  // of the preference. Note that the PrefValueStore takes the ownership of
  // the value referenced by |in_value|. It is an error to call this when no
  // user PrefStore has been set.
  void SetUserPrefValue(const char* name, Value* in_value);

  // Removes a value from the PrefValueStore. If a preference is managed
  // or recommended this function should have no effect.
  void RemoveUserPrefValue(const char* name);

  // These methods return true if a preference with the given name is in the
  // indicated pref store, even if that value is currently being overridden by
  // a higher-priority source.
  bool PrefValueInManagedStore(const char* name);
  bool PrefValueInExtensionStore(const char* name);
  bool PrefValueInUserStore(const char* name);

  // These methods return true if a preference with the given name is actually
  // being controlled by the indicated pref store and not being overridden by
  // a higher-priority source.
  bool PrefValueFromExtensionStore(const char* name);
  bool PrefValueFromUserStore(const char* name);

  // Check whether a Preference value is modifiable by the user, i.e. whether
  // there is no higher-priority source controlling it.
  bool PrefValueUserModifiable(const char* name);

  // Signature of callback triggered after policy refresh. Parameter is not
  // passed as reference to prevent passing along a pointer to a set whose
  // lifecycle is managed in another thread.
  typedef Callback1<std::vector<std::string> >::Type AfterRefreshCallback;

  // Called as a result of a notification of policy change. Triggers a
  // reload of managed preferences from policy. Caller must pass in
  // new, uninitialized managed and recommended PrefStores in
  // |managed_pref_store| and |recommended_pref_store| respectively, since
  // PrefValueStore doesn't know about policy-specific PrefStores.
  // |callback| is called with the set of preferences changed by the policy
  // refresh. |callback| is called on the caller's thread as a Task
  // after RefreshPolicyPrefs has returned. RefreshPolicyPrefs takes ownership
  // of the |callback| object.
  void RefreshPolicyPrefs(PrefStore* managed_pref_store,
                          PrefStore* recommended_pref_store,
                          AfterRefreshCallback* callback);

 protected:
  // In decreasing order of precedence:
  //   |managed_prefs| contains all managed (policy) preference values.
  //   |extension_prefs| contains preference values set by extensions.
  //   |command_line_prefs| contains preference values set by command-line
  //        switches.
  //   |user_prefs| contains all user-set preference values.
  //   |recommended_prefs| contains all recommended (policy) preference values.
  //
  // This constructor should only be used internally, or by subclasses in
  // testing. The usual way to create a PrefValueStore is by creating a
  // PrefService.
  PrefValueStore(PrefStore* managed_prefs,
                 PrefStore* extension_prefs,
                 PrefStore* command_line_prefs,
                 PrefStore* user_prefs,
                 PrefStore* recommended_prefs);

 private:
  friend class PrefValueStoreTest;
  FRIEND_TEST_ALL_PREFIXES(PrefValueStoreTest,
                           TestRefreshPolicyPrefsCompletion);

  scoped_ptr<PrefStore> pref_stores_[PrefNotifier::PREF_STORE_TYPE_MAX + 1];

  bool PrefValueInStore(const char* name, PrefNotifier::PrefStoreType type);

  // Returns the pref store type identifying the source that controls the
  // Preference identified by |name|. If none of the sources has a value,
  // INVALID is returned.
  PrefNotifier::PrefStoreType ControllingPrefStoreForPref(const char* name);

  // Called during policy refresh after ReadPrefs completes on the thread
  // that initiated the policy refresh. RefreshPolicyPrefsCompletion takes
  // ownership of the |callback| object.
  void RefreshPolicyPrefsCompletion(
      PrefStore* new_managed_pref_store,
      PrefStore* new_recommended_pref_store,
      AfterRefreshCallback* callback);

  // Called during policy refresh to do the ReadPrefs on the FILE thread.
  // RefreshPolicyPrefsOnFileThread takes ownership of the |callback| object.
  void RefreshPolicyPrefsOnFileThread(
      ChromeThread::ID calling_thread_id,
      PrefStore* new_managed_pref_store,
      PrefStore* new_recommended_pref_store,
      AfterRefreshCallback* callback);

  DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
};

#endif  // CHROME_BROWSER_PREF_VALUE_STORE_H_