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