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/memory/ref_counted.h"
16#include "base/values.h"
17#include "chrome/common/pref_store.h"
18#include "content/browser/browser_thread.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                const 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  // Check whether a Preference value is modifiable by an extension, i.e.
102  // whether there is no higher-priority source controlling it.
103  bool PrefValueExtensionModifiable(const char* name) const;
104
105 private:
106  // PrefStores must be listed here in order from highest to lowest priority.
107  //   MANAGED_PLATFORM contains all managed preference values that are
108  //       provided by a platform-specific policy mechanism (e.g. Windows
109  //       Group Policy).
110  //   MANAGED_CLOUD contains all managed preference values supplied
111  //       by the device management server (cloud policy).
112  //   EXTENSION contains preference values set by extensions.
113  //   COMMAND_LINE contains preference values set by command-line switches.
114  //   USER contains all user-set preference values.
115  //   RECOMMENDED_PLATFORM contains all recommended (policy) preference values
116  //      that are provided by a platform-specific policy mechanism.
117  //   RECOMMENDED_CLOUD contains all recommended (policy) preference values
118  //      that are provided by the device management server (cloud policy).
119  //   DEFAULT contains all application default preference values.
120  enum PrefStoreType {
121    // INVALID_STORE is not associated with an actual PrefStore but used as
122    // an invalid marker, e.g. as a return value.
123    INVALID_STORE = -1,
124    MANAGED_PLATFORM_STORE = 0,
125    MANAGED_CLOUD_STORE,
126    EXTENSION_STORE,
127    COMMAND_LINE_STORE,
128    USER_STORE,
129    RECOMMENDED_PLATFORM_STORE,
130    RECOMMENDED_CLOUD_STORE,
131    DEFAULT_STORE,
132    PREF_STORE_TYPE_MAX = DEFAULT_STORE
133  };
134
135  // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors
136  // the PrefStore for changes, forwarding notifications to PrefValueStore. This
137  // indirection is here for the sake of disambiguating notifications from the
138  // individual PrefStores.
139  class PrefStoreKeeper : public PrefStore::Observer {
140   public:
141    PrefStoreKeeper();
142    virtual ~PrefStoreKeeper();
143
144    // Takes ownership of |pref_store|.
145    void Initialize(PrefValueStore* store,
146                    PrefStore* pref_store,
147                    PrefStoreType type);
148
149    PrefStore* store() { return pref_store_.get(); }
150    const PrefStore* store() const { return pref_store_.get(); }
151
152   private:
153    // PrefStore::Observer implementation.
154    virtual void OnPrefValueChanged(const std::string& key);
155    virtual void OnInitializationCompleted();
156
157    // PrefValueStore this keeper is part of.
158    PrefValueStore* pref_value_store_;
159
160    // The PrefStore managed by this keeper.
161    scoped_refptr<PrefStore> pref_store_;
162
163    // Type of the pref store.
164    PrefStoreType type_;
165
166    DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper);
167  };
168
169  typedef std::map<std::string, Value::ValueType> PrefTypeMap;
170
171  friend class PrefValueStorePolicyRefreshTest;
172  FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestPolicyRefresh);
173  FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
174                           TestRefreshPolicyPrefsCompletion);
175  FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
176                           TestConcurrentPolicyRefresh);
177
178  // Returns true if the preference with the given name has a value in the
179  // given PrefStoreType, of the same value type as the preference was
180  // registered with.
181  bool PrefValueInStore(const char* name, PrefStoreType store) const;
182
183  // Returns true if a preference has an explicit value in any of the
184  // stores in the range specified by |first_checked_store| and
185  // |last_checked_store|, even if that value is currently being
186  // overridden by a higher-priority store.
187  bool PrefValueInStoreRange(const char* name,
188                             PrefStoreType first_checked_store,
189                             PrefStoreType last_checked_store) const;
190
191  // Returns the pref store type identifying the source that controls the
192  // Preference identified by |name|. If none of the sources has a value,
193  // INVALID_STORE is returned. In practice, the default PrefStore
194  // should always have a value for any registered preferencem, so INVALID_STORE
195  // indicates an error.
196  PrefStoreType ControllingPrefStoreForPref(const char* name) const;
197
198  // Get a value from the specified store type.
199  bool GetValueFromStore(const char* name,
200                         PrefStoreType store,
201                         const Value** out_value) const;
202
203  // Called upon changes in individual pref stores in order to determine whether
204  // the user-visible pref value has changed. Triggers the change notification
205  // if the effective value of the preference has changed, or if the store
206  // controlling the pref has changed.
207  void NotifyPrefChanged(const char* path, PrefStoreType new_store);
208
209  // Called from the PrefStoreKeeper implementation when a pref value for |key|
210  // changed in the pref store for |type|.
211  void OnPrefValueChanged(PrefStoreType type, const std::string& key);
212
213  // Handle the event that the store for |type| has completed initialization.
214  void OnInitializationCompleted(PrefStoreType type);
215
216  // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take
217  // ownership of the passed |pref_store|.
218  void InitPrefStore(PrefStoreType type, PrefStore* pref_store);
219
220  // Checks whether initialization is completed and tells the notifier if that
221  // is the case.
222  void CheckInitializationCompleted();
223
224  // Get the PrefStore pointer for the given type. May return NULL if there is
225  // no PrefStore for that type.
226  PrefStore* GetPrefStore(PrefStoreType type) {
227    return pref_stores_[type].store();
228  }
229  const PrefStore* GetPrefStore(PrefStoreType type) const {
230    return pref_stores_[type].store();
231  }
232
233  // Keeps the PrefStore references in order of precedence.
234  PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];
235
236  // Used for generating PREF_CHANGED and PREF_INITIALIZATION_COMPLETED
237  // notifications. This is a weak reference, since the notifier is owned by the
238  // corresponding PrefService.
239  PrefNotifier* pref_notifier_;
240
241  // A mapping of preference names to their registered types.
242  PrefTypeMap pref_types_;
243
244  DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
245};
246
247#endif  // CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_
248