| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/prefs/pref_service.h" | 5 #include "base/prefs/pref_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 base::Callback<void(PersistentPrefStore::PrefReadError)> | 46 base::Callback<void(PersistentPrefStore::PrefReadError)> |
| 47 read_error_callback, | 47 read_error_callback, |
| 48 bool async) | 48 bool async) |
| 49 : pref_notifier_(pref_notifier), | 49 : pref_notifier_(pref_notifier), |
| 50 pref_value_store_(pref_value_store), | 50 pref_value_store_(pref_value_store), |
| 51 pref_registry_(pref_registry), | 51 pref_registry_(pref_registry), |
| 52 user_pref_store_(user_prefs), | 52 user_pref_store_(user_prefs), |
| 53 read_error_callback_(read_error_callback) { | 53 read_error_callback_(read_error_callback) { |
| 54 pref_notifier_->SetPrefService(this); | 54 pref_notifier_->SetPrefService(this); |
| 55 | 55 |
| 56 pref_registry_->SetRegistrationCallback( | |
| 57 base::Bind(&PrefService::AddRegisteredPreference, | |
| 58 base::Unretained(this))); | |
| 59 AddInitialPreferences(); | |
| 60 | |
| 61 InitFromStorage(async); | 56 InitFromStorage(async); |
| 62 } | 57 } |
| 63 | 58 |
| 64 PrefService::~PrefService() { | 59 PrefService::~PrefService() { |
| 65 DCHECK(CalledOnValidThread()); | 60 DCHECK(CalledOnValidThread()); |
| 66 | 61 |
| 67 // Remove our callback, setting a NULL one. | |
| 68 pref_registry_->SetRegistrationCallback(PrefRegistry::RegistrationCallback()); | |
| 69 | |
| 70 // Reset pointers so accesses after destruction reliably crash. | 62 // Reset pointers so accesses after destruction reliably crash. |
| 71 pref_value_store_.reset(); | 63 pref_value_store_.reset(); |
| 72 pref_registry_ = NULL; | 64 pref_registry_ = NULL; |
| 73 user_pref_store_ = NULL; | 65 user_pref_store_ = NULL; |
| 74 pref_notifier_.reset(); | 66 pref_notifier_.reset(); |
| 75 } | 67 } |
| 76 | 68 |
| 77 void PrefService::InitFromStorage(bool async) { | 69 void PrefService::InitFromStorage(bool async) { |
| 78 if (!async) { | 70 if (!async) { |
| 79 read_error_callback_.Run(user_pref_store_->ReadPrefs()); | 71 read_error_callback_.Run(user_pref_store_->ReadPrefs()); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 DCHECK(CalledOnValidThread()); | 282 DCHECK(CalledOnValidThread()); |
| 291 // Lookup the preference in the default store. | 283 // Lookup the preference in the default store. |
| 292 const base::Value* value = NULL; | 284 const base::Value* value = NULL; |
| 293 if (!pref_registry_->defaults()->GetValue(path, &value)) { | 285 if (!pref_registry_->defaults()->GetValue(path, &value)) { |
| 294 NOTREACHED() << "Default value missing for pref: " << path; | 286 NOTREACHED() << "Default value missing for pref: " << path; |
| 295 return NULL; | 287 return NULL; |
| 296 } | 288 } |
| 297 return value; | 289 return value; |
| 298 } | 290 } |
| 299 | 291 |
| 300 void PrefService::MarkUserStoreNeedsEmptyValue(const std::string& key) const { | |
| 301 user_pref_store_->MarkNeedsEmptyValue(key); | |
| 302 } | |
| 303 | |
| 304 const base::ListValue* PrefService::GetList(const char* path) const { | 292 const base::ListValue* PrefService::GetList(const char* path) const { |
| 305 DCHECK(CalledOnValidThread()); | 293 DCHECK(CalledOnValidThread()); |
| 306 | 294 |
| 307 const base::Value* value = GetPreferenceValue(path); | 295 const base::Value* value = GetPreferenceValue(path); |
| 308 if (!value) { | 296 if (!value) { |
| 309 NOTREACHED() << "Trying to read an unregistered pref: " << path; | 297 NOTREACHED() << "Trying to read an unregistered pref: " << path; |
| 310 return NULL; | 298 return NULL; |
| 311 } | 299 } |
| 312 if (value->GetType() != base::Value::TYPE_LIST) { | 300 if (value->GetType() != base::Value::TYPE_LIST) { |
| 313 NOTREACHED(); | 301 NOTREACHED(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 325 } | 313 } |
| 326 | 314 |
| 327 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { | 315 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { |
| 328 pref_notifier_->AddInitObserver(obs); | 316 pref_notifier_->AddInitObserver(obs); |
| 329 } | 317 } |
| 330 | 318 |
| 331 PrefRegistry* PrefService::DeprecatedGetPrefRegistry() { | 319 PrefRegistry* PrefService::DeprecatedGetPrefRegistry() { |
| 332 return pref_registry_.get(); | 320 return pref_registry_.get(); |
| 333 } | 321 } |
| 334 | 322 |
| 335 void PrefService::AddInitialPreferences() { | |
| 336 for (PrefRegistry::const_iterator it = pref_registry_->begin(); | |
| 337 it != pref_registry_->end(); | |
| 338 ++it) { | |
| 339 AddRegisteredPreference(it->first.c_str(), it->second); | |
| 340 } | |
| 341 } | |
| 342 | |
| 343 // TODO(joi): Once MarkNeedsEmptyValue is gone, we can probably | |
| 344 // completely get rid of this method. There will be one difference in | |
| 345 // semantics; currently all registered preferences are stored right | |
| 346 // away in the prefs_map_, if we remove this they would be stored only | |
| 347 // opportunistically. | |
| 348 void PrefService::AddRegisteredPreference(const char* path, | |
| 349 base::Value* default_value) { | |
| 350 DCHECK(CalledOnValidThread()); | |
| 351 | |
| 352 // For ListValue and DictionaryValue with non empty default, empty value | |
| 353 // for |path| needs to be persisted in |user_pref_store_|. So that | |
| 354 // non empty default is not used when user sets an empty ListValue or | |
| 355 // DictionaryValue. | |
| 356 bool needs_empty_value = false; | |
| 357 base::Value::Type orig_type = default_value->GetType(); | |
| 358 if (orig_type == base::Value::TYPE_LIST) { | |
| 359 const base::ListValue* list = NULL; | |
| 360 if (default_value->GetAsList(&list) && !list->empty()) | |
| 361 needs_empty_value = true; | |
| 362 } else if (orig_type == base::Value::TYPE_DICTIONARY) { | |
| 363 const base::DictionaryValue* dict = NULL; | |
| 364 if (default_value->GetAsDictionary(&dict) && !dict->empty()) | |
| 365 needs_empty_value = true; | |
| 366 } | |
| 367 if (needs_empty_value) | |
| 368 user_pref_store_->MarkNeedsEmptyValue(path); | |
| 369 } | |
| 370 | |
| 371 void PrefService::ClearPref(const char* path) { | 323 void PrefService::ClearPref(const char* path) { |
| 372 DCHECK(CalledOnValidThread()); | 324 DCHECK(CalledOnValidThread()); |
| 373 | 325 |
| 374 const Preference* pref = FindPreference(path); | 326 const Preference* pref = FindPreference(path); |
| 375 if (!pref) { | 327 if (!pref) { |
| 376 NOTREACHED() << "Trying to clear an unregistered pref: " << path; | 328 NOTREACHED() << "Trying to clear an unregistered pref: " << path; |
| 377 return; | 329 return; |
| 378 } | 330 } |
| 379 user_pref_store_->RemoveValue(path); | 331 user_pref_store_->RemoveValue(path); |
| 380 } | 332 } |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 DCHECK(found_value->IsType(default_type)); | 546 DCHECK(found_value->IsType(default_type)); |
| 595 return found_value; | 547 return found_value; |
| 596 } else { | 548 } else { |
| 597 // Every registered preference has at least a default value. | 549 // Every registered preference has at least a default value. |
| 598 NOTREACHED() << "no valid value found for registered pref " << path; | 550 NOTREACHED() << "no valid value found for registered pref " << path; |
| 599 } | 551 } |
| 600 } | 552 } |
| 601 | 553 |
| 602 return NULL; | 554 return NULL; |
| 603 } | 555 } |
| OLD | NEW |