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