pref_service.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (c) 2012 The Chromium Authors. All rights reserved. 26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Use of this source code is governed by a BSD-style license that can be 36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// found in the LICENSE file. 46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/prefs/pref_service.h" 66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <algorithm> 86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/bind.h" 106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/files/file_path.h" 116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/logging.h" 126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/message_loop.h" 136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/metrics/histogram.h" 146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/prefs/default_pref_store.h" 156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/prefs/pref_notifier_impl.h" 166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/prefs/pref_registry.h" 176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/prefs/pref_value_store.h" 186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/stl_util.h" 196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/strings/string_number_conversions.h" 206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/strings/string_util.h" 216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "base/value_conversions.h" 226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "build/build_config.h" 236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennnamespace { 256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate { 276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn public: 286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb) 296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn : callback_(cb) {} 306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn virtual void OnError(PersistentPrefStore::PrefReadError error) OVERRIDE { 326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn callback_.Run(error); 336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn private: 366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Callback<void(PersistentPrefStore::PrefReadError)> callback_; 376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}; 386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // namespace 406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennPrefService::PrefService( 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PrefNotifierImpl* pref_notifier, 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PrefValueStore* pref_value_store, 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PersistentPrefStore* user_prefs, 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PrefRegistry* pref_registry, 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Callback<void(PersistentPrefStore::PrefReadError)> 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn read_error_callback, 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool async) 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn : pref_notifier_(pref_notifier), 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_value_store_(pref_value_store), 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_registry_(pref_registry), 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn user_pref_store_(user_prefs), 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn read_error_callback_(read_error_callback) { 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_notifier_->SetPrefService(this); 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_registry_->SetRegistrationCallback( 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Bind(&PrefService::AddRegisteredPreference, 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Unretained(this))); 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn AddInitialPreferences(); 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn InitFromStorage(async); 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennPrefService::~PrefService() { 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Remove our callback, setting a NULL one. 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_registry_->SetRegistrationCallback(PrefRegistry::RegistrationCallback()); 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Reset pointers so accesses after destruction reliably crash. 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_value_store_.reset(); 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_registry_ = NULL; 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn user_pref_store_ = NULL; 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_notifier_.reset(); 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::InitFromStorage(bool async) { 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!async) { 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn read_error_callback_.Run(user_pref_store_->ReadPrefs()); 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } else { 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Guarantee that initialization happens after this function returned. 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::MessageLoop::current()->PostTask( 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FROM_HERE, 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Bind(&PersistentPrefStore::ReadPrefsAsync, 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn user_pref_store_.get(), 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn new ReadErrorHandler(read_error_callback_))); 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool PrefService::ReloadPersistentPrefs() { 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return user_pref_store_->ReadPrefs() == 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PersistentPrefStore::PREF_READ_ERROR_NONE; 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::CommitPendingWrite() { 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn user_pref_store_->CommitPendingWrite(); 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool PrefService::GetBoolean(const char* path) const { 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool result = false; 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool rv = value->GetAsBoolean(&result); 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(rv); 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint PrefService::GetInteger(const char* path) const { 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int result = 0; 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool rv = value->GetAsInteger(&result); 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(rv); 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renndouble PrefService::GetDouble(const char* path) const { 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double result = 0.0; 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool rv = value->GetAsDouble(&result); 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(rv); 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstd::string PrefService::GetString(const char* path) const { 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn std::string result; 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool rv = value->GetAsString(&result); 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(rv); 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbase::FilePath PrefService::GetFilePath(const char* path) const { 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::FilePath result; 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return base::FilePath(result); 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool rv = base::GetValueAsFilePath(*value, &result); 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(rv); 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool PrefService::HasPrefPath(const char* path) const { 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Preference* pref = FindPreference(path); 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return pref && !pref->IsDefaultValue(); 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbase::DictionaryValue* PrefService::GetPreferenceValues() const { 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::DictionaryValue* out = new base::DictionaryValue; 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PrefRegistry::const_iterator i = pref_registry_->begin(); 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (; i != pref_registry_->end(); ++i) { 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(i->first); 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(value); 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out->Set(i->first, value->DeepCopy()); 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return out; 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst PrefService::Preference* PrefService::FindPreference( 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const char* pref_name) const { 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PreferenceMap::iterator it = prefs_map_.find(pref_name); 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (it != prefs_map_.end()) 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return &(it->second); 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* default_value = NULL; 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!pref_registry_->defaults()->GetValue(pref_name, &default_value)) 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn it = prefs_map_.insert( 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn std::make_pair(pref_name, Preference( 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn this, pref_name, default_value->GetType()))).first; 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return &(it->second); 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool PrefService::ReadOnly() const { 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return user_pref_store_->ReadOnly(); 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennPrefService::PrefInitializationStatus PrefService::GetInitializationStatus() 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const { 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!user_pref_store_->IsInitializationComplete()) 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return INITIALIZATION_STATUS_WAITING; 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch (user_pref_store_->GetReadError()) { 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case PersistentPrefStore::PREF_READ_ERROR_NONE: 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return INITIALIZATION_STATUS_SUCCESS; 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case PersistentPrefStore::PREF_READ_ERROR_NO_FILE: 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE; 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default: 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return INITIALIZATION_STATUS_ERROR; 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool PrefService::IsManagedPreference(const char* pref_name) const { 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Preference* pref = FindPreference(pref_name); 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return pref && pref->IsManaged(); 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool PrefService::IsUserModifiablePreference(const char* pref_name) const { 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Preference* pref = FindPreference(pref_name); 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return pref && pref->IsUserModifiable(); 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst base::DictionaryValue* PrefService::GetDictionary( 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const char* path) const { 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (value->GetType() != base::Value::TYPE_DICTIONARY) { 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED(); 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return static_cast<const base::DictionaryValue*>(value); 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst base::Value* PrefService::GetUserPrefValue(const char* path) const { 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Preference* pref = FindPreference(path); 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!pref) { 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to get an unregistered pref: " << path; 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Look for an existing preference in the user store. If it doesn't 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // exist, return NULL. 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Value* value = NULL; 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!user_pref_store_->GetMutableValue(path, &value)) 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value->IsType(pref->GetType())) { 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Pref value type doesn't match registered type."; 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return value; 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::SetDefaultPrefValue(const char* path, 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Value* value) { 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_registry_->SetDefaultPrefValue(path, value); 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst base::Value* PrefService::GetDefaultPrefValue(const char* path) const { 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Lookup the preference in the default store. 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = NULL; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!pref_registry_->defaults()->GetValue(path, &value)) { 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Default value missing for pref: " << path; 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return value; 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst base::ListValue* PrefService::GetList(const char* path) const { 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::Value* value = GetPreferenceValue(path); 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!value) { 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to read an unregistered pref: " << path; 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (value->GetType() != base::Value::TYPE_LIST) { 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED(); 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return NULL; 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return static_cast<const base::ListValue*>(value); 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::AddPrefObserver(const char* path, PrefObserver* obs) { 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_notifier_->AddPrefObserver(path, obs); 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) { 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_notifier_->RemovePrefObserver(path, obs); 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pref_notifier_->AddInitObserver(obs); 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennPrefRegistry* PrefService::DeprecatedGetPrefRegistry() { 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return pref_registry_.get(); 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::AddInitialPreferences() { 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (PrefRegistry::const_iterator it = pref_registry_->begin(); 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn it != pref_registry_->end(); 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ++it) { 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn AddRegisteredPreference(it->first.c_str(), it->second); 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// TODO(joi): Once MarkNeedsEmptyValue is gone, we can probably 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// completely get rid of this method. There will be one difference in 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// semantics; currently all registered preferences are stored right 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// away in the prefs_map_, if we remove this they would be stored only 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// opportunistically. 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::AddRegisteredPreference(const char* path, 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Value* default_value) { 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // For ListValue and DictionaryValue with non empty default, empty value 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // for |path| needs to be persisted in |user_pref_store_|. So that 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // non empty default is not used when user sets an empty ListValue or 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // DictionaryValue. 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool needs_empty_value = false; 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base::Value::Type orig_type = default_value->GetType(); 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (orig_type == base::Value::TYPE_LIST) { 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::ListValue* list = NULL; 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (default_value->GetAsList(&list) && !list->empty()) 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn needs_empty_value = true; 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } else if (orig_type == base::Value::TYPE_DICTIONARY) { 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const base::DictionaryValue* dict = NULL; 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (default_value->GetAsDictionary(&dict) && !dict->empty()) 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn needs_empty_value = true; 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (needs_empty_value) 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn user_pref_store_->MarkNeedsEmptyValue(path); 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::ClearPref(const char* path) { 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DCHECK(CalledOnValidThread()); 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Preference* pref = FindPreference(path); 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!pref) { 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NOTREACHED() << "Trying to clear an unregistered pref: " << path; 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return; 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn user_pref_store_->RemoveValue(path); 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid PrefService::Set(const char* path, const base::Value& value) { 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn SetUserPrefValue(path, value.DeepCopy()); 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 374void PrefService::SetBoolean(const char* path, bool value) { 375 SetUserPrefValue(path, base::Value::CreateBooleanValue(value)); 376} 377 378void PrefService::SetInteger(const char* path, int value) { 379 SetUserPrefValue(path, base::Value::CreateIntegerValue(value)); 380} 381 382void PrefService::SetDouble(const char* path, double value) { 383 SetUserPrefValue(path, base::Value::CreateDoubleValue(value)); 384} 385 386void PrefService::SetString(const char* path, const std::string& value) { 387 SetUserPrefValue(path, base::Value::CreateStringValue(value)); 388} 389 390void PrefService::SetFilePath(const char* path, const base::FilePath& value) { 391 SetUserPrefValue(path, base::CreateFilePathValue(value)); 392} 393 394void PrefService::SetInt64(const char* path, int64 value) { 395 SetUserPrefValue(path, 396 base::Value::CreateStringValue(base::Int64ToString(value))); 397} 398 399int64 PrefService::GetInt64(const char* path) const { 400 DCHECK(CalledOnValidThread()); 401 402 const base::Value* value = GetPreferenceValue(path); 403 if (!value) { 404 NOTREACHED() << "Trying to read an unregistered pref: " << path; 405 return 0; 406 } 407 std::string result("0"); 408 bool rv = value->GetAsString(&result); 409 DCHECK(rv); 410 411 int64 val; 412 base::StringToInt64(result, &val); 413 return val; 414} 415 416void PrefService::SetUint64(const char* path, uint64 value) { 417 SetUserPrefValue(path, 418 base::Value::CreateStringValue(base::Uint64ToString(value))); 419} 420 421uint64 PrefService::GetUint64(const char* path) const { 422 DCHECK(CalledOnValidThread()); 423 424 const base::Value* value = GetPreferenceValue(path); 425 if (!value) { 426 NOTREACHED() << "Trying to read an unregistered pref: " << path; 427 return 0; 428 } 429 std::string result("0"); 430 bool rv = value->GetAsString(&result); 431 DCHECK(rv); 432 433 uint64 val; 434 base::StringToUint64(result, &val); 435 return val; 436} 437 438base::Value* PrefService::GetMutableUserPref(const char* path, 439 base::Value::Type type) { 440 CHECK(type == base::Value::TYPE_DICTIONARY || type == base::Value::TYPE_LIST); 441 DCHECK(CalledOnValidThread()); 442 443 const Preference* pref = FindPreference(path); 444 if (!pref) { 445 NOTREACHED() << "Trying to get an unregistered pref: " << path; 446 return NULL; 447 } 448 if (pref->GetType() != type) { 449 NOTREACHED() << "Wrong type for GetMutableValue: " << path; 450 return NULL; 451 } 452 453 // Look for an existing preference in the user store. If it doesn't 454 // exist or isn't the correct type, create a new user preference. 455 base::Value* value = NULL; 456 if (!user_pref_store_->GetMutableValue(path, &value) || 457 !value->IsType(type)) { 458 if (type == base::Value::TYPE_DICTIONARY) { 459 value = new base::DictionaryValue; 460 } else if (type == base::Value::TYPE_LIST) { 461 value = new base::ListValue; 462 } else { 463 NOTREACHED(); 464 } 465 user_pref_store_->SetValueSilently(path, value); 466 } 467 return value; 468} 469 470void PrefService::ReportUserPrefChanged(const std::string& key) { 471 user_pref_store_->ReportValueChanged(key); 472} 473 474void PrefService::SetUserPrefValue(const char* path, base::Value* new_value) { 475 scoped_ptr<base::Value> owned_value(new_value); 476 DCHECK(CalledOnValidThread()); 477 478 const Preference* pref = FindPreference(path); 479 if (!pref) { 480 NOTREACHED() << "Trying to write an unregistered pref: " << path; 481 return; 482 } 483 if (pref->GetType() != new_value->GetType()) { 484 NOTREACHED() << "Trying to set pref " << path 485 << " of type " << pref->GetType() 486 << " to value of type " << new_value->GetType(); 487 return; 488 } 489 490 user_pref_store_->SetValue(path, owned_value.release()); 491} 492 493void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) { 494 pref_value_store_->UpdateCommandLinePrefStore(command_line_store); 495} 496 497/////////////////////////////////////////////////////////////////////////////// 498// PrefService::Preference 499 500PrefService::Preference::Preference(const PrefService* service, 501 const char* name, 502 base::Value::Type type) 503 : name_(name), 504 type_(type), 505 pref_service_(service) { 506 DCHECK(name); 507 DCHECK(service); 508} 509 510const std::string PrefService::Preference::name() const { 511 return name_; 512} 513 514base::Value::Type PrefService::Preference::GetType() const { 515 return type_; 516} 517 518const base::Value* PrefService::Preference::GetValue() const { 519 const base::Value* result= pref_service_->GetPreferenceValue(name_); 520 DCHECK(result) << "Must register pref before getting its value"; 521 return result; 522} 523 524const base::Value* PrefService::Preference::GetRecommendedValue() const { 525 DCHECK(pref_service_->FindPreference(name_.c_str())) << 526 "Must register pref before getting its value"; 527 528 const base::Value* found_value = NULL; 529 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) { 530 DCHECK(found_value->IsType(type_)); 531 return found_value; 532 } 533 534 // The pref has no recommended value. 535 return NULL; 536} 537 538bool PrefService::Preference::IsManaged() const { 539 return pref_value_store()->PrefValueInManagedStore(name_.c_str()); 540} 541 542bool PrefService::Preference::IsRecommended() const { 543 return pref_value_store()->PrefValueFromRecommendedStore(name_.c_str()); 544} 545 546bool PrefService::Preference::HasExtensionSetting() const { 547 return pref_value_store()->PrefValueInExtensionStore(name_.c_str()); 548} 549 550bool PrefService::Preference::HasUserSetting() const { 551 return pref_value_store()->PrefValueInUserStore(name_.c_str()); 552} 553 554bool PrefService::Preference::IsExtensionControlled() const { 555 return pref_value_store()->PrefValueFromExtensionStore(name_.c_str()); 556} 557 558bool PrefService::Preference::IsUserControlled() const { 559 return pref_value_store()->PrefValueFromUserStore(name_.c_str()); 560} 561 562bool PrefService::Preference::IsDefaultValue() const { 563 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str()); 564} 565 566bool PrefService::Preference::IsUserModifiable() const { 567 return pref_value_store()->PrefValueUserModifiable(name_.c_str()); 568} 569 570bool PrefService::Preference::IsExtensionModifiable() const { 571 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str()); 572} 573 574const base::Value* PrefService::GetPreferenceValue( 575 const std::string& path) const { 576 DCHECK(CalledOnValidThread()); 577 const base::Value* default_value = NULL; 578 if (pref_registry_->defaults()->GetValue(path, &default_value)) { 579 const base::Value* found_value = NULL; 580 base::Value::Type default_type = default_value->GetType(); 581 if (pref_value_store_->GetValue(path, default_type, &found_value)) { 582 DCHECK(found_value->IsType(default_type)); 583 return found_value; 584 } else { 585 // Every registered preference has at least a default value. 586 NOTREACHED() << "no valid value found for registered pref " << path; 587 } 588 } 589 590 return NULL; 591} 592