OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 #include "base/prefs/pref_value_store.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/prefs/pref_notifier.h" | |
11 #include "base/prefs/pref_observer.h" | |
12 | |
13 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() | |
14 : pref_value_store_(NULL), | |
15 type_(PrefValueStore::INVALID_STORE) { | |
16 } | |
17 | |
18 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { | |
19 if (pref_store_.get()) { | |
20 pref_store_->RemoveObserver(this); | |
21 pref_store_ = NULL; | |
22 } | |
23 pref_value_store_ = NULL; | |
24 } | |
25 | |
26 void PrefValueStore::PrefStoreKeeper::Initialize( | |
27 PrefValueStore* store, | |
28 PrefStore* pref_store, | |
29 PrefValueStore::PrefStoreType type) { | |
30 if (pref_store_.get()) { | |
31 pref_store_->RemoveObserver(this); | |
32 DCHECK(!pref_store_->HasObservers()); | |
33 } | |
34 type_ = type; | |
35 pref_value_store_ = store; | |
36 pref_store_ = pref_store; | |
37 if (pref_store_.get()) | |
38 pref_store_->AddObserver(this); | |
39 } | |
40 | |
41 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( | |
42 const std::string& key) { | |
43 pref_value_store_->OnPrefValueChanged(type_, key); | |
44 } | |
45 | |
46 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted( | |
47 bool succeeded) { | |
48 pref_value_store_->OnInitializationCompleted(type_, succeeded); | |
49 } | |
50 | |
51 PrefValueStore::PrefValueStore(PrefStore* managed_prefs, | |
52 PrefStore* supervised_user_prefs, | |
53 PrefStore* extension_prefs, | |
54 PrefStore* command_line_prefs, | |
55 PrefStore* user_prefs, | |
56 PrefStore* recommended_prefs, | |
57 PrefStore* default_prefs, | |
58 PrefNotifier* pref_notifier) | |
59 : pref_notifier_(pref_notifier), | |
60 initialization_failed_(false) { | |
61 InitPrefStore(MANAGED_STORE, managed_prefs); | |
62 InitPrefStore(SUPERVISED_USER_STORE, supervised_user_prefs); | |
63 InitPrefStore(EXTENSION_STORE, extension_prefs); | |
64 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | |
65 InitPrefStore(USER_STORE, user_prefs); | |
66 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); | |
67 InitPrefStore(DEFAULT_STORE, default_prefs); | |
68 | |
69 CheckInitializationCompleted(); | |
70 } | |
71 | |
72 PrefValueStore::~PrefValueStore() {} | |
73 | |
74 PrefValueStore* PrefValueStore::CloneAndSpecialize( | |
75 PrefStore* managed_prefs, | |
76 PrefStore* supervised_user_prefs, | |
77 PrefStore* extension_prefs, | |
78 PrefStore* command_line_prefs, | |
79 PrefStore* user_prefs, | |
80 PrefStore* recommended_prefs, | |
81 PrefStore* default_prefs, | |
82 PrefNotifier* pref_notifier) { | |
83 DCHECK(pref_notifier); | |
84 if (!managed_prefs) | |
85 managed_prefs = GetPrefStore(MANAGED_STORE); | |
86 if (!supervised_user_prefs) | |
87 supervised_user_prefs = GetPrefStore(SUPERVISED_USER_STORE); | |
88 if (!extension_prefs) | |
89 extension_prefs = GetPrefStore(EXTENSION_STORE); | |
90 if (!command_line_prefs) | |
91 command_line_prefs = GetPrefStore(COMMAND_LINE_STORE); | |
92 if (!user_prefs) | |
93 user_prefs = GetPrefStore(USER_STORE); | |
94 if (!recommended_prefs) | |
95 recommended_prefs = GetPrefStore(RECOMMENDED_STORE); | |
96 if (!default_prefs) | |
97 default_prefs = GetPrefStore(DEFAULT_STORE); | |
98 | |
99 return new PrefValueStore( | |
100 managed_prefs, supervised_user_prefs, extension_prefs, command_line_prefs, | |
101 user_prefs, recommended_prefs, default_prefs, pref_notifier); | |
102 } | |
103 | |
104 void PrefValueStore::set_callback(const PrefChangedCallback& callback) { | |
105 pref_changed_callback_ = callback; | |
106 } | |
107 | |
108 bool PrefValueStore::GetValue(const std::string& name, | |
109 base::Value::Type type, | |
110 const base::Value** out_value) const { | |
111 // Check the |PrefStore|s in order of their priority from highest to lowest, | |
112 // looking for the first preference value with the given |name| and |type|. | |
113 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
114 if (GetValueFromStoreWithType(name, type, static_cast<PrefStoreType>(i), | |
115 out_value)) | |
116 return true; | |
117 } | |
118 return false; | |
119 } | |
120 | |
121 bool PrefValueStore::GetRecommendedValue(const std::string& name, | |
122 base::Value::Type type, | |
123 const base::Value** out_value) const { | |
124 return GetValueFromStoreWithType(name, type, RECOMMENDED_STORE, out_value); | |
125 } | |
126 | |
127 void PrefValueStore::NotifyPrefChanged( | |
128 const std::string& path, | |
129 PrefValueStore::PrefStoreType new_store) { | |
130 DCHECK(new_store != INVALID_STORE); | |
131 // A notification is sent when the pref value in any store changes. If this | |
132 // store is currently being overridden by a higher-priority store, the | |
133 // effective value of the pref will not have changed. | |
134 pref_notifier_->OnPreferenceChanged(path); | |
135 if (!pref_changed_callback_.is_null()) | |
136 pref_changed_callback_.Run(path); | |
137 } | |
138 | |
139 bool PrefValueStore::PrefValueInManagedStore(const std::string& name) const { | |
140 return PrefValueInStore(name, MANAGED_STORE); | |
141 } | |
142 | |
143 bool PrefValueStore::PrefValueInSupervisedStore(const std::string& name) const { | |
144 return PrefValueInStore(name, SUPERVISED_USER_STORE); | |
145 } | |
146 | |
147 bool PrefValueStore::PrefValueInExtensionStore(const std::string& name) const { | |
148 return PrefValueInStore(name, EXTENSION_STORE); | |
149 } | |
150 | |
151 bool PrefValueStore::PrefValueInUserStore(const std::string& name) const { | |
152 return PrefValueInStore(name, USER_STORE); | |
153 } | |
154 | |
155 bool PrefValueStore::PrefValueFromExtensionStore( | |
156 const std::string& name) const { | |
157 return ControllingPrefStoreForPref(name) == EXTENSION_STORE; | |
158 } | |
159 | |
160 bool PrefValueStore::PrefValueFromUserStore(const std::string& name) const { | |
161 return ControllingPrefStoreForPref(name) == USER_STORE; | |
162 } | |
163 | |
164 bool PrefValueStore::PrefValueFromRecommendedStore( | |
165 const std::string& name) const { | |
166 return ControllingPrefStoreForPref(name) == RECOMMENDED_STORE; | |
167 } | |
168 | |
169 bool PrefValueStore::PrefValueFromDefaultStore(const std::string& name) const { | |
170 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; | |
171 } | |
172 | |
173 bool PrefValueStore::PrefValueUserModifiable(const std::string& name) const { | |
174 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | |
175 return effective_store >= USER_STORE || | |
176 effective_store == INVALID_STORE; | |
177 } | |
178 | |
179 bool PrefValueStore::PrefValueExtensionModifiable( | |
180 const std::string& name) const { | |
181 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | |
182 return effective_store >= EXTENSION_STORE || | |
183 effective_store == INVALID_STORE; | |
184 } | |
185 | |
186 void PrefValueStore::UpdateCommandLinePrefStore(PrefStore* command_line_prefs) { | |
187 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | |
188 } | |
189 | |
190 bool PrefValueStore::PrefValueInStore( | |
191 const std::string& name, | |
192 PrefValueStore::PrefStoreType store) const { | |
193 // Declare a temp Value* and call GetValueFromStore, | |
194 // ignoring the output value. | |
195 const base::Value* tmp_value = NULL; | |
196 return GetValueFromStore(name, store, &tmp_value); | |
197 } | |
198 | |
199 bool PrefValueStore::PrefValueInStoreRange( | |
200 const std::string& name, | |
201 PrefValueStore::PrefStoreType first_checked_store, | |
202 PrefValueStore::PrefStoreType last_checked_store) const { | |
203 if (first_checked_store > last_checked_store) { | |
204 NOTREACHED(); | |
205 return false; | |
206 } | |
207 | |
208 for (size_t i = first_checked_store; | |
209 i <= static_cast<size_t>(last_checked_store); ++i) { | |
210 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) | |
211 return true; | |
212 } | |
213 return false; | |
214 } | |
215 | |
216 PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( | |
217 const std::string& name) const { | |
218 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
219 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) | |
220 return static_cast<PrefStoreType>(i); | |
221 } | |
222 return INVALID_STORE; | |
223 } | |
224 | |
225 bool PrefValueStore::GetValueFromStore(const std::string& name, | |
226 PrefValueStore::PrefStoreType store_type, | |
227 const base::Value** out_value) const { | |
228 // Only return true if we find a value and it is the correct type, so stale | |
229 // values with the incorrect type will be ignored. | |
230 const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type)); | |
231 if (store && store->GetValue(name, out_value)) | |
232 return true; | |
233 | |
234 // No valid value found for the given preference name: set the return value | |
235 // to false. | |
236 *out_value = NULL; | |
237 return false; | |
238 } | |
239 | |
240 bool PrefValueStore::GetValueFromStoreWithType( | |
241 const std::string& name, | |
242 base::Value::Type type, | |
243 PrefStoreType store, | |
244 const base::Value** out_value) const { | |
245 if (GetValueFromStore(name, store, out_value)) { | |
246 if ((*out_value)->IsType(type)) | |
247 return true; | |
248 | |
249 LOG(WARNING) << "Expected type for " << name << " is " << type | |
250 << " but got " << (*out_value)->GetType() | |
251 << " in store " << store; | |
252 } | |
253 | |
254 *out_value = NULL; | |
255 return false; | |
256 } | |
257 | |
258 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, | |
259 const std::string& key) { | |
260 NotifyPrefChanged(key, type); | |
261 } | |
262 | |
263 void PrefValueStore::OnInitializationCompleted( | |
264 PrefValueStore::PrefStoreType type, bool succeeded) { | |
265 if (initialization_failed_) | |
266 return; | |
267 if (!succeeded) { | |
268 initialization_failed_ = true; | |
269 pref_notifier_->OnInitializationCompleted(false); | |
270 return; | |
271 } | |
272 CheckInitializationCompleted(); | |
273 } | |
274 | |
275 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | |
276 PrefStore* pref_store) { | |
277 pref_stores_[type].Initialize(this, pref_store, type); | |
278 } | |
279 | |
280 void PrefValueStore::CheckInitializationCompleted() { | |
281 if (initialization_failed_) | |
282 return; | |
283 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
284 scoped_refptr<PrefStore> store = | |
285 GetPrefStore(static_cast<PrefStoreType>(i)); | |
286 if (store.get() && !store->IsInitializationComplete()) | |
287 return; | |
288 } | |
289 pref_notifier_->OnInitializationCompleted(true); | |
290 } | |
OLD | NEW |