Chromium Code Reviews| 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 "chrome/browser/prefs/pref_service.h" | 5 #include "chrome/browser/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/file_path.h" | 10 #include "base/file_path.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/prefs/default_pref_store.h" | 14 #include "base/prefs/default_pref_store.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/value_conversions.h" | 18 #include "base/value_conversions.h" |
| 19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
| 20 #include "chrome/browser/prefs/pref_notifier_impl.h" | 20 #include "chrome/browser/prefs/pref_notifier_impl.h" |
| 21 #include "chrome/browser/prefs/pref_registry.h" | |
| 21 #include "chrome/browser/prefs/pref_value_store.h" | 22 #include "chrome/browser/prefs/pref_value_store.h" |
| 22 | 23 |
| 23 using content::BrowserContext; | 24 using content::BrowserContext; |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate { | 28 class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate { |
| 28 public: | 29 public: |
| 29 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb) | 30 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb) |
| 30 : callback_(cb) {} | 31 : callback_(cb) {} |
| 31 | 32 |
| 32 virtual void OnError(PersistentPrefStore::PrefReadError error) { | 33 virtual void OnError(PersistentPrefStore::PrefReadError error) { |
| 33 callback_.Run(error); | 34 callback_.Run(error); |
| 34 } | 35 } |
| 35 | 36 |
| 36 private: | 37 private: |
| 37 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_; | 38 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_; |
| 38 }; | 39 }; |
| 39 | 40 |
| 40 } // namespace | 41 } // namespace |
| 41 | 42 |
| 42 PrefService::PrefService( | 43 PrefService::PrefService( |
| 43 PrefNotifierImpl* pref_notifier, | 44 PrefNotifierImpl* pref_notifier, |
| 44 PrefValueStore* pref_value_store, | 45 PrefValueStore* pref_value_store, |
| 45 PersistentPrefStore* user_prefs, | 46 PersistentPrefStore* user_prefs, |
| 46 DefaultPrefStore* default_store, | 47 scoped_ptr<PrefRegistry> pref_registry, |
| 47 base::Callback<void(PersistentPrefStore::PrefReadError)> | 48 base::Callback<void(PersistentPrefStore::PrefReadError)> |
| 48 read_error_callback, | 49 read_error_callback, |
| 49 bool async) | 50 bool async) |
| 50 : pref_notifier_(pref_notifier), | 51 : pref_notifier_(pref_notifier), |
| 51 pref_value_store_(pref_value_store), | 52 pref_value_store_(pref_value_store), |
| 52 user_pref_store_(user_prefs), | 53 user_pref_store_(user_prefs), |
| 53 default_store_(default_store), | 54 read_error_callback_(read_error_callback), |
| 54 read_error_callback_(read_error_callback) { | 55 pref_registry_(pref_registry.Pass()) { |
| 55 pref_notifier_->SetPrefService(this); | 56 pref_notifier_->SetPrefService(this); |
| 57 | |
| 58 pref_registry_->RetrieveDefaults(&default_store_); | |
| 59 pref_registry_->pref_service_ = this; | |
| 60 RegisterInitialPreferences(); | |
| 61 | |
| 56 InitFromStorage(async); | 62 InitFromStorage(async); |
| 57 } | 63 } |
| 58 | 64 |
| 59 PrefService::~PrefService() { | 65 PrefService::~PrefService() { |
| 60 DCHECK(CalledOnValidThread()); | 66 DCHECK(CalledOnValidThread()); |
| 61 | 67 |
| 62 // Reset pointers so accesses after destruction reliably crash. | 68 // Reset pointers so accesses after destruction reliably crash. |
| 63 pref_value_store_.reset(); | 69 pref_value_store_.reset(); |
| 64 user_pref_store_ = NULL; | 70 user_pref_store_ = NULL; |
| 65 default_store_ = NULL; | 71 default_store_ = NULL; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 } | 299 } |
| 294 | 300 |
| 295 void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) { | 301 void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) { |
| 296 pref_notifier_->RemovePrefObserver(path, obs); | 302 pref_notifier_->RemovePrefObserver(path, obs); |
| 297 } | 303 } |
| 298 | 304 |
| 299 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { | 305 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { |
| 300 pref_notifier_->AddInitObserver(obs); | 306 pref_notifier_->AddInitObserver(obs); |
| 301 } | 307 } |
| 302 | 308 |
| 309 PrefRegistry* PrefService::DeprecatedGetPrefRegistry() const { | |
| 310 return pref_registry_.get(); | |
| 311 } | |
| 312 | |
| 313 void PrefService::RegisterInitialPreferences() { | |
| 314 // Invariant: default_store_ is valid and contains the preferences | |
| 315 // registered prior to construction time. | |
| 316 for (DefaultPrefStore::const_iterator it = default_store_->begin(); | |
| 317 it != default_store_->end(); | |
| 318 ++it) { | |
| 319 RegisterPreference(it->first.c_str(), it->second, true); | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 // TODO(joi): Once all registration is done before the PrefService is | |
| 324 // constructed, we can stop exposing a separate RegisterPreference | |
| 325 // method, and we can simplify the registration logic. Possibly at the | |
| 326 // same point we can remove UnregisterPreference. For now, because a | |
| 327 // few remaining places register preferences after PrefService | |
| 328 // construction, it is better to leave this here and have PrefRegistry | |
| 329 // delegate to PrefService::RegisterPreference after that | |
| 330 // point. Otherwise, PrefRegistry would need to control PrefService's | |
| 331 // default_store_ and user_pref_store_ members, as well as the | |
| 332 // pref_map_ member for UnregisterPreference. | |
|
Mattias Nissler (ping if slow)
2013/01/25 14:57:11
The default_store_ it controls already! The user_p
Jói
2013/01/29 16:10:02
Registration is now fully owned by PrefRegistry. P
| |
| 333 // | |
| 334 // We are, however, able to implement the interface we desire in the | |
| 335 // long term on PrefRegistry, and make this relationship an | |
| 336 // implementation detail. | |
| 303 void PrefService::RegisterPreference(const char* path, | 337 void PrefService::RegisterPreference(const char* path, |
| 304 Value* default_value) { | 338 Value* default_value, |
| 339 bool in_default_store) { | |
| 305 DCHECK(CalledOnValidThread()); | 340 DCHECK(CalledOnValidThread()); |
| 306 | 341 |
| 307 // The main code path takes ownership, but most don't. We'll be safe. | 342 // The main code path takes ownership, but most don't. We'll be safe. |
| 308 scoped_ptr<Value> scoped_value(default_value); | 343 scoped_ptr<Value> scoped_value(default_value); |
| 309 | 344 |
| 310 CHECK(!FindPreference(path)) << "Tried to register duplicate pref " << path; | 345 CHECK(!FindPreference(path)) << "Tried to register duplicate pref " << path; |
| 311 | 346 |
| 312 base::Value::Type orig_type = default_value->GetType(); | 347 base::Value::Type orig_type = default_value->GetType(); |
| 313 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << | 348 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << |
| 314 "invalid preference type: " << orig_type; | 349 "invalid preference type: " << orig_type; |
| 315 | 350 |
| 316 // For ListValue and DictionaryValue with non empty default, empty value | 351 // For ListValue and DictionaryValue with non empty default, empty value |
| 317 // for |path| needs to be persisted in |user_pref_store_|. So that | 352 // for |path| needs to be persisted in |user_pref_store_|. So that |
| 318 // non empty default is not used when user sets an empty ListValue or | 353 // non empty default is not used when user sets an empty ListValue or |
| 319 // DictionaryValue. | 354 // DictionaryValue. |
| 320 bool needs_empty_value = false; | 355 bool needs_empty_value = false; |
| 321 if (orig_type == base::Value::TYPE_LIST) { | 356 if (orig_type == base::Value::TYPE_LIST) { |
| 322 const base::ListValue* list = NULL; | 357 const base::ListValue* list = NULL; |
| 323 if (default_value->GetAsList(&list) && !list->empty()) | 358 if (default_value->GetAsList(&list) && !list->empty()) |
| 324 needs_empty_value = true; | 359 needs_empty_value = true; |
| 325 } else if (orig_type == base::Value::TYPE_DICTIONARY) { | 360 } else if (orig_type == base::Value::TYPE_DICTIONARY) { |
| 326 const base::DictionaryValue* dict = NULL; | 361 const base::DictionaryValue* dict = NULL; |
| 327 if (default_value->GetAsDictionary(&dict) && !dict->empty()) | 362 if (default_value->GetAsDictionary(&dict) && !dict->empty()) |
| 328 needs_empty_value = true; | 363 needs_empty_value = true; |
| 329 } | 364 } |
| 330 if (needs_empty_value) | 365 if (needs_empty_value) |
| 331 user_pref_store_->MarkNeedsEmptyValue(path); | 366 user_pref_store_->MarkNeedsEmptyValue(path); |
| 332 | 367 |
| 333 // Hand off ownership. | 368 if (!in_default_store) { |
| 334 default_store_->SetDefaultValue(path, scoped_value.release()); | 369 // Hand off ownership. |
| 370 default_store_->SetDefaultValue(path, scoped_value.release()); | |
| 371 } | |
| 335 } | 372 } |
| 336 | 373 |
| 337 void PrefService::UnregisterPreference(const char* path) { | 374 void PrefService::UnregisterPreference(const char* path) { |
| 338 DCHECK(CalledOnValidThread()); | 375 DCHECK(CalledOnValidThread()); |
| 339 | 376 |
| 340 PreferenceMap::iterator it = prefs_map_.find(path); | 377 PreferenceMap::iterator it = prefs_map_.find(path); |
| 341 CHECK(it != prefs_map_.end()) << "Trying to unregister an unregistered pref: " | 378 CHECK(it != prefs_map_.end()) << "Trying to unregister an unregistered pref: " |
| 342 << path; | 379 << path; |
| 343 | 380 |
| 344 prefs_map_.erase(it); | 381 prefs_map_.erase(it); |
| 345 default_store_->RemoveDefaultValue(path); | 382 default_store_->RemoveDefaultValue(path); |
| 346 } | 383 } |
| 347 | 384 |
| 385 bool PrefService::AllowPrefRegistrarSimple() const { | |
| 386 return true; | |
| 387 } | |
| 388 | |
| 348 void PrefService::ClearPref(const char* path) { | 389 void PrefService::ClearPref(const char* path) { |
| 349 DCHECK(CalledOnValidThread()); | 390 DCHECK(CalledOnValidThread()); |
| 350 | 391 |
| 351 const Preference* pref = FindPreference(path); | 392 const Preference* pref = FindPreference(path); |
| 352 if (!pref) { | 393 if (!pref) { |
| 353 NOTREACHED() << "Trying to clear an unregistered pref: " << path; | 394 NOTREACHED() << "Trying to clear an unregistered pref: " << path; |
| 354 return; | 395 return; |
| 355 } | 396 } |
| 356 user_pref_store_->RemoveValue(path); | 397 user_pref_store_->RemoveValue(path); |
| 357 } | 398 } |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 const Value* found_value = NULL; | 608 const Value* found_value = NULL; |
| 568 if (pref_value_store_->GetValue(path, type, &found_value)) { | 609 if (pref_value_store_->GetValue(path, type, &found_value)) { |
| 569 DCHECK(found_value->IsType(type)); | 610 DCHECK(found_value->IsType(type)); |
| 570 return found_value; | 611 return found_value; |
| 571 } | 612 } |
| 572 | 613 |
| 573 // Every registered preference has at least a default value. | 614 // Every registered preference has at least a default value. |
| 574 NOTREACHED() << "no valid value found for registered pref " << path; | 615 NOTREACHED() << "no valid value found for registered pref " << path; |
| 575 return NULL; | 616 return NULL; |
| 576 } | 617 } |
| OLD | NEW |