OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/prefs/pref_value_store.h" | 5 #include "chrome/browser/prefs/pref_value_store.h" |
6 | 6 |
7 #include "chrome/browser/browser_thread.h" | 7 #include "chrome/browser/browser_thread.h" |
8 #include "chrome/browser/policy/configuration_policy_pref_store.h" | 8 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
9 #include "chrome/browser/prefs/pref_notifier.h" | 9 #include "chrome/browser/prefs/pref_notifier.h" |
10 #include "chrome/common/notification_service.h" | 10 #include "chrome/common/notification_service.h" |
11 | 11 |
12 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() | 12 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() |
13 : pref_value_store_(NULL), | 13 : pref_value_store_(NULL), |
14 type_(PrefValueStore::INVALID_STORE) { | 14 type_(PrefValueStore::INVALID_STORE) { |
15 } | 15 } |
16 | 16 |
17 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { | 17 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { |
18 if (pref_store_.get()) | 18 if (pref_store_.get()) |
19 pref_store_->RemoveObserver(this); | 19 pref_store_->RemoveObserver(this); |
20 } | 20 } |
21 | 21 |
22 void PrefValueStore::PrefStoreKeeper::Initialize( | 22 void PrefValueStore::PrefStoreKeeper::Initialize( |
23 PrefValueStore* store, | 23 PrefValueStore* store, |
24 PrefStore* pref_store, | 24 PrefStore* pref_store, |
25 PrefValueStore::PrefStoreType type) { | 25 PrefValueStore::PrefStoreType type) { |
26 if (pref_store_.get()) | 26 if (pref_store_.get()) |
27 pref_store_->RemoveObserver(this); | 27 pref_store_->RemoveObserver(this); |
28 type_ = type; | 28 type_ = type; |
29 pref_value_store_ = store; | 29 pref_value_store_ = store; |
30 pref_store_.reset(pref_store); | 30 pref_store_ = pref_store; |
31 if (pref_store_.get()) | 31 if (pref_store_.get()) |
32 pref_store_->AddObserver(this); | 32 pref_store_->AddObserver(this); |
33 } | 33 } |
34 | 34 |
35 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( | 35 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( |
36 const std::string& key) { | 36 const std::string& key) { |
37 pref_value_store_->OnPrefValueChanged(type_, key); | 37 pref_value_store_->OnPrefValueChanged(type_, key); |
38 } | 38 } |
39 | 39 |
40 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() { | 40 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() { |
(...skipping 23 matching lines...) Loading... |
64 registrar_.Add(this, | 64 registrar_.Add(this, |
65 NotificationType(NotificationType::POLICY_CHANGED), | 65 NotificationType(NotificationType::POLICY_CHANGED), |
66 NotificationService::AllSources()); | 66 NotificationService::AllSources()); |
67 | 67 |
68 CheckInitializationCompleted(); | 68 CheckInitializationCompleted(); |
69 } | 69 } |
70 | 70 |
71 PrefValueStore::~PrefValueStore() {} | 71 PrefValueStore::~PrefValueStore() {} |
72 | 72 |
73 bool PrefValueStore::GetValue(const std::string& name, | 73 bool PrefValueStore::GetValue(const std::string& name, |
| 74 Value::ValueType type, |
74 Value** out_value) const { | 75 Value** out_value) const { |
| 76 *out_value = NULL; |
75 // Check the |PrefStore|s in order of their priority from highest to lowest | 77 // Check the |PrefStore|s in order of their priority from highest to lowest |
76 // to find the value of the preference described by the given preference name. | 78 // to find the value of the preference described by the given preference name. |
77 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | 79 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
78 if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i), | 80 if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i), |
79 out_value)) | 81 out_value)) { |
| 82 if (!(*out_value)->IsType(type)) { |
| 83 LOG(WARNING) << "Expected type for " << name << " is " << type |
| 84 << " but got " << (*out_value)->GetType() |
| 85 << " in store " << i; |
| 86 continue; |
| 87 } |
80 return true; | 88 return true; |
| 89 } |
81 } | 90 } |
82 return false; | 91 return false; |
83 } | 92 } |
84 | 93 |
85 void PrefValueStore::RegisterPreferenceType(const std::string& name, | |
86 Value::ValueType type) { | |
87 pref_types_[name] = type; | |
88 } | |
89 | |
90 Value::ValueType PrefValueStore::GetRegisteredType( | |
91 const std::string& name) const { | |
92 PrefTypeMap::const_iterator found = pref_types_.find(name); | |
93 if (found == pref_types_.end()) | |
94 return Value::TYPE_NULL; | |
95 return found->second; | |
96 } | |
97 | |
98 bool PrefValueStore::HasPrefPath(const char* path) const { | |
99 Value* tmp_value = NULL; | |
100 const std::string name(path); | |
101 bool rv = GetValue(name, &tmp_value); | |
102 // Merely registering a pref doesn't count as "having" it: we require a | |
103 // non-default value set. | |
104 return rv && !PrefValueFromDefaultStore(path); | |
105 } | |
106 | |
107 void PrefValueStore::NotifyPrefChanged( | 94 void PrefValueStore::NotifyPrefChanged( |
108 const char* path, | 95 const char* path, |
109 PrefValueStore::PrefStoreType new_store) { | 96 PrefValueStore::PrefStoreType new_store) { |
110 DCHECK(new_store != INVALID_STORE); | 97 DCHECK(new_store != INVALID_STORE); |
111 | 98 |
112 // If this pref is not registered, just discard the notification. | |
113 if (!pref_types_.count(path)) | |
114 return; | |
115 | |
116 bool changed = true; | 99 bool changed = true; |
117 // Replying that the pref has changed in case the new store is invalid may | 100 // Replying that the pref has changed in case the new store is invalid may |
118 // cause problems, but it's the safer choice. | 101 // cause problems, but it's the safer choice. |
119 if (new_store != INVALID_STORE) { | 102 if (new_store != INVALID_STORE) { |
120 PrefStoreType controller = ControllingPrefStoreForPref(path); | 103 PrefStoreType controller = ControllingPrefStoreForPref(path); |
121 DCHECK(controller != INVALID_STORE); | 104 DCHECK(controller != INVALID_STORE); |
122 // If the pref is controlled by a higher-priority store, its effective value | 105 // If the pref is controlled by a higher-priority store, its effective value |
123 // cannot have changed. | 106 // cannot have changed. |
124 if (controller != INVALID_STORE && | 107 if (controller != INVALID_STORE && |
125 controller < new_store) { | 108 controller < new_store) { |
(...skipping 32 matching lines...) Loading... |
158 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | 141 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { |
159 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; | 142 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; |
160 } | 143 } |
161 | 144 |
162 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | 145 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { |
163 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | 146 PrefStoreType effective_store = ControllingPrefStoreForPref(name); |
164 return effective_store >= USER_STORE || | 147 return effective_store >= USER_STORE || |
165 effective_store == INVALID_STORE; | 148 effective_store == INVALID_STORE; |
166 } | 149 } |
167 | 150 |
168 // Returns true if the actual value is a valid type for the expected type when | |
169 // found in the given store. | |
170 bool PrefValueStore::IsValidType(Value::ValueType expected, | |
171 Value::ValueType actual, | |
172 PrefValueStore::PrefStoreType store) { | |
173 if (expected == actual) | |
174 return true; | |
175 | |
176 // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only | |
177 // in the default pref store. | |
178 if (store == DEFAULT_STORE && | |
179 actual == Value::TYPE_NULL && | |
180 (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) { | |
181 return true; | |
182 } | |
183 return false; | |
184 } | |
185 | |
186 bool PrefValueStore::PrefValueInStore( | 151 bool PrefValueStore::PrefValueInStore( |
187 const char* name, | 152 const char* name, |
188 PrefValueStore::PrefStoreType store) const { | 153 PrefValueStore::PrefStoreType store) const { |
189 // Declare a temp Value* and call GetValueFromStore, | 154 // Declare a temp Value* and call GetValueFromStore, |
190 // ignoring the output value. | 155 // ignoring the output value. |
191 Value* tmp_value = NULL; | 156 Value* tmp_value = NULL; |
192 return GetValueFromStore(name, store, &tmp_value); | 157 return GetValueFromStore(name, store, &tmp_value); |
193 } | 158 } |
194 | 159 |
195 bool PrefValueStore::PrefValueInStoreRange( | 160 bool PrefValueStore::PrefValueInStoreRange( |
(...skipping 31 matching lines...) Loading... |
227 if (store) { | 192 if (store) { |
228 switch (store->GetValue(name, out_value)) { | 193 switch (store->GetValue(name, out_value)) { |
229 case PrefStore::READ_USE_DEFAULT: | 194 case PrefStore::READ_USE_DEFAULT: |
230 store = GetPrefStore(DEFAULT_STORE); | 195 store = GetPrefStore(DEFAULT_STORE); |
231 if (!store || store->GetValue(name, out_value) != PrefStore::READ_OK) { | 196 if (!store || store->GetValue(name, out_value) != PrefStore::READ_OK) { |
232 *out_value = NULL; | 197 *out_value = NULL; |
233 return false; | 198 return false; |
234 } | 199 } |
235 // Fall through... | 200 // Fall through... |
236 case PrefStore::READ_OK: | 201 case PrefStore::READ_OK: |
237 if (IsValidType(GetRegisteredType(name), | 202 return true; |
238 (*out_value)->GetType(), | |
239 store_type)) { | |
240 return true; | |
241 } | |
242 break; | |
243 case PrefStore::READ_NO_VALUE: | 203 case PrefStore::READ_NO_VALUE: |
244 break; | 204 break; |
245 } | 205 } |
246 } | 206 } |
247 | 207 |
248 // No valid value found for the given preference name: set the return false. | 208 // No valid value found for the given preference name: set the return false. |
249 *out_value = NULL; | 209 *out_value = NULL; |
250 return false; | 210 return false; |
251 } | 211 } |
252 | 212 |
253 void PrefValueStore::RefreshPolicyPrefsOnFileThread( | 213 void PrefValueStore::RefreshPolicyPrefsOnFileThread( |
254 BrowserThread::ID calling_thread_id, | 214 BrowserThread::ID calling_thread_id, |
255 policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, | 215 scoped_refptr<policy::ConfigurationPolicyPrefStore> |
256 policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, | 216 managed_platform_pref_store, |
257 policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { | 217 scoped_refptr<policy::ConfigurationPolicyPrefStore> |
| 218 device_management_pref_store, |
| 219 scoped_refptr<policy::ConfigurationPolicyPrefStore> |
| 220 recommended_pref_store) { |
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
259 scoped_ptr<policy::ConfigurationPolicyPrefStore> managed_platform_pref_store( | |
260 new_managed_platform_pref_store); | |
261 scoped_ptr<policy::ConfigurationPolicyPrefStore> device_management_pref_store( | |
262 new_device_management_pref_store); | |
263 scoped_ptr<policy::ConfigurationPolicyPrefStore> recommended_pref_store( | |
264 new_recommended_pref_store); | |
265 | 222 |
266 BrowserThread::PostTask( | 223 BrowserThread::PostTask( |
267 calling_thread_id, FROM_HERE, | 224 calling_thread_id, FROM_HERE, |
268 NewRunnableMethod(this, | 225 NewRunnableMethod(this, |
269 &PrefValueStore::RefreshPolicyPrefsCompletion, | 226 &PrefValueStore::RefreshPolicyPrefsCompletion, |
270 managed_platform_pref_store.release(), | 227 managed_platform_pref_store, |
271 device_management_pref_store.release(), | 228 device_management_pref_store, |
272 recommended_pref_store.release())); | 229 recommended_pref_store)); |
273 } | 230 } |
274 | 231 |
275 void PrefValueStore::RefreshPolicyPrefs() { | 232 void PrefValueStore::RefreshPolicyPrefs() { |
276 using policy::ConfigurationPolicyPrefStore; | 233 using policy::ConfigurationPolicyPrefStore; |
277 // Because loading of policy information must happen on the FILE | 234 // Because loading of policy information must happen on the FILE |
278 // thread, it's not possible to just replace the contents of the | 235 // thread, it's not possible to just replace the contents of the |
279 // managed and recommended stores in place due to possible | 236 // managed and recommended stores in place due to possible |
280 // concurrent access from the UI thread. Instead, new stores are | 237 // concurrent access from the UI thread. Instead, new stores are |
281 // created and the refreshed policy read into them. The new stores | 238 // created and the refreshed policy read into them. The new stores |
282 // are swapped with the old from a Task on the UI thread after the | 239 // are swapped with the old from a Task on the UI thread after the |
283 // load is complete. | 240 // load is complete. |
284 ConfigurationPolicyPrefStore* new_managed_platform_pref_store( | 241 ConfigurationPolicyPrefStore* new_managed_platform_pref_store( |
285 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); | 242 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); |
286 ConfigurationPolicyPrefStore* new_device_management_pref_store( | 243 ConfigurationPolicyPrefStore* new_device_management_pref_store( |
287 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | 244 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( |
288 profile_)); | 245 profile_)); |
289 ConfigurationPolicyPrefStore* new_recommended_pref_store( | 246 ConfigurationPolicyPrefStore* new_recommended_pref_store( |
290 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); | 247 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); |
291 BrowserThread::ID current_thread_id; | 248 BrowserThread::ID current_thread_id; |
292 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); | 249 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); |
293 BrowserThread::PostTask( | 250 BrowserThread::PostTask( |
294 BrowserThread::FILE, FROM_HERE, | 251 BrowserThread::FILE, FROM_HERE, |
295 NewRunnableMethod(this, | 252 NewRunnableMethod(this, |
296 &PrefValueStore::RefreshPolicyPrefsOnFileThread, | 253 &PrefValueStore::RefreshPolicyPrefsOnFileThread, |
297 current_thread_id, | 254 current_thread_id, |
298 new_managed_platform_pref_store, | 255 make_scoped_refptr(new_managed_platform_pref_store), |
299 new_device_management_pref_store, | 256 make_scoped_refptr(new_device_management_pref_store), |
300 new_recommended_pref_store)); | 257 make_scoped_refptr(new_recommended_pref_store))); |
301 } | 258 } |
302 | 259 |
303 void PrefValueStore::RefreshPolicyPrefsCompletion( | 260 void PrefValueStore::RefreshPolicyPrefsCompletion( |
304 policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, | 261 policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, |
305 policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, | 262 policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, |
306 policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { | 263 policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { |
307 // Determine the paths of all the changed preferences values in the three | 264 // Determine the paths of all the changed preferences values in the three |
308 // policy-related stores (managed platform, device management and | 265 // policy-related stores (managed platform, device management and |
309 // recommended). | 266 // recommended). |
310 DictionaryValue* managed_platform_prefs_before( | 267 DictionaryValue* managed_platform_prefs_before( |
(...skipping 85 matching lines...) Loading... |
396 CheckInitializationCompleted(); | 353 CheckInitializationCompleted(); |
397 } | 354 } |
398 | 355 |
399 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | 356 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, |
400 PrefStore* pref_store) { | 357 PrefStore* pref_store) { |
401 pref_stores_[type].Initialize(this, pref_store, type); | 358 pref_stores_[type].Initialize(this, pref_store, type); |
402 } | 359 } |
403 | 360 |
404 void PrefValueStore::CheckInitializationCompleted() { | 361 void PrefValueStore::CheckInitializationCompleted() { |
405 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | 362 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
406 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); | 363 scoped_refptr<PrefStore> store = |
| 364 GetPrefStore(static_cast<PrefStoreType>(i)); |
407 if (store && !store->IsInitializationComplete()) | 365 if (store && !store->IsInitializationComplete()) |
408 return; | 366 return; |
409 } | 367 } |
410 pref_notifier_->OnInitializationCompleted(); | 368 pref_notifier_->OnInitializationCompleted(); |
411 } | 369 } |
OLD | NEW |