pref_service.cc revision deac0c43a7683ce292e438d19a649b9772c88834
1// Copyright (c) 2011 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_service.h" 6 7#include <algorithm> 8#include <string> 9 10#ifndef ANDROID 11#include "base/command_line.h" 12#endif 13#include "base/file_path.h" 14#include "base/file_util.h" 15#include "base/logging.h" 16#include "base/message_loop.h" 17#include "base/metrics/histogram.h" 18#include "base/stl_util-inl.h" 19#include "base/string_number_conversions.h" 20#include "base/string_util.h" 21#include "base/sys_string_conversions.h" 22#include "base/utf_string_conversions.h" 23#include "build/build_config.h" 24#include "chrome/browser/browser_thread.h" 25#include "chrome/browser/extensions/extension_pref_store.h" 26#ifndef ANDROID 27#include "chrome/browser/policy/configuration_policy_pref_store.h" 28#endif 29#include "chrome/browser/prefs/command_line_pref_store.h" 30#include "chrome/browser/prefs/default_pref_store.h" 31#include "chrome/browser/prefs/overlay_persistent_pref_store.h" 32#include "chrome/browser/prefs/pref_notifier_impl.h" 33#include "chrome/browser/prefs/pref_value_store.h" 34#include "chrome/common/json_pref_store.h" 35#ifndef ANDROID 36// Notifications do not compile on Android and are the cause 37// of most of the ANDROID guards in this file. 38#include "chrome/common/notification_service.h" 39#include "grit/chromium_strings.h" 40#include "grit/generated_resources.h" 41#endif 42#include "ui/base/l10n/l10n_util.h" 43 44namespace { 45 46// A helper function for RegisterLocalized*Pref that creates a Value* based on 47// the string value in the locale dll. Because we control the values in a 48// locale dll, this should always return a Value of the appropriate type. 49Value* CreateLocaleDefaultValue(Value::ValueType type, int message_id) { 50#ifndef ANDROID 51 std::string resource_string = l10n_util::GetStringUTF8(message_id); 52 DCHECK(!resource_string.empty()); 53 switch (type) { 54 case Value::TYPE_BOOLEAN: { 55 if ("true" == resource_string) 56 return Value::CreateBooleanValue(true); 57 if ("false" == resource_string) 58 return Value::CreateBooleanValue(false); 59 break; 60 } 61 62 case Value::TYPE_INTEGER: { 63 int val; 64 base::StringToInt(resource_string, &val); 65 return Value::CreateIntegerValue(val); 66 } 67 68 case Value::TYPE_DOUBLE: { 69 double val; 70 base::StringToDouble(resource_string, &val); 71 return Value::CreateDoubleValue(val); 72 } 73 74 case Value::TYPE_STRING: { 75 return Value::CreateStringValue(resource_string); 76 } 77 78 default: { 79 NOTREACHED() << 80 "list and dictionary types cannot have default locale values"; 81 } 82 } 83#endif 84 NOTREACHED(); 85 return Value::CreateNullValue(); 86} 87 88// Forwards a notification after a PostMessage so that we can wait for the 89// MessageLoop to run. 90void NotifyReadError(PrefService* pref, int message_id) { 91#ifndef ANDROID 92 Source<PrefService> source(pref); 93 NotificationService::current()->Notify(NotificationType::PROFILE_ERROR, 94 source, Details<int>(&message_id)); 95#endif 96} 97 98} // namespace 99 100// static 101PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, 102 PrefStore* extension_prefs, 103 Profile* profile) { 104#ifndef ANDROID 105 using policy::ConfigurationPolicyPrefStore; 106#endif 107 108#if defined(OS_LINUX) && !defined(ANDROID) 109 // We'd like to see what fraction of our users have the preferences 110 // stored on a network file system, as we've had no end of troubles 111 // with NFS/AFS. 112 // TODO(evanm): remove this once we've collected state. 113 file_util::FileSystemType fstype; 114 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) { 115 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType", 116 static_cast<int>(fstype), 117 file_util::FILE_SYSTEM_TYPE_COUNT); 118 } 119#endif 120 121#ifdef ANDROID 122 return new PrefService(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 123#else 124 ConfigurationPolicyPrefStore* managed_platform = 125 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore(); 126 ConfigurationPolicyPrefStore* managed_cloud = 127 ConfigurationPolicyPrefStore::CreateManagedCloudPolicyPrefStore(profile); 128 CommandLinePrefStore* command_line = 129 new CommandLinePrefStore(CommandLine::ForCurrentProcess()); 130 JsonPrefStore* user = new JsonPrefStore( 131 pref_filename, 132 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 133 ConfigurationPolicyPrefStore* recommended_platform = 134 ConfigurationPolicyPrefStore::CreateRecommendedPlatformPolicyPrefStore(); 135 ConfigurationPolicyPrefStore* recommended_cloud = 136 ConfigurationPolicyPrefStore::CreateRecommendedCloudPolicyPrefStore( 137 profile); 138 DefaultPrefStore* default_pref_store = new DefaultPrefStore(); 139 140 return new PrefService(managed_platform, managed_cloud, extension_prefs, 141 command_line, user, recommended_platform, 142 recommended_cloud, default_pref_store); 143#endif 144} 145 146PrefService* PrefService::CreateIncognitoPrefService( 147 PrefStore* incognito_extension_prefs) { 148 return new PrefService(*this, incognito_extension_prefs); 149} 150 151PrefService::PrefService(PrefStore* managed_platform_prefs, 152 PrefStore* managed_cloud_prefs, 153 PrefStore* extension_prefs, 154 PrefStore* command_line_prefs, 155 PersistentPrefStore* user_prefs, 156 PrefStore* recommended_platform_prefs, 157 PrefStore* recommended_cloud_prefs, 158 DefaultPrefStore* default_store) 159 : user_pref_store_(user_prefs), 160 default_store_(default_store) { 161#ifndef ANDROID 162 pref_notifier_.reset(new PrefNotifierImpl(this)); 163#endif 164 pref_value_store_.reset( 165 new PrefValueStore(managed_platform_prefs, 166 managed_cloud_prefs, 167 extension_prefs, 168 command_line_prefs, 169 user_pref_store_, 170 recommended_platform_prefs, 171 recommended_cloud_prefs, 172 default_store, 173#ifdef ANDROID 174 NULL)); 175#else 176 pref_notifier_.get())); 177#endif 178 InitFromStorage(); 179} 180 181PrefService::PrefService(const PrefService& original, 182 PrefStore* incognito_extension_prefs) 183 : user_pref_store_( 184 new OverlayPersistentPrefStore(original.user_pref_store_.get())), 185 default_store_(original.default_store_.get()){ 186#ifndef ANDROID 187 pref_notifier_.reset(new PrefNotifierImpl(this)); 188#endif 189 pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize( 190 NULL, // managed_platform_prefs 191 NULL, // managed_cloud_prefs 192 incognito_extension_prefs, 193 NULL, // command_line_prefs 194 user_pref_store_.get(), 195 NULL, // recommended_platform_prefs 196 NULL, // recommended_cloud_prefs 197 default_store_.get(), 198#ifdef ANDROID 199 NULL)); 200#else 201 pref_notifier_.get())); 202#endif 203 InitFromStorage(); 204} 205 206PrefService::~PrefService() { 207 DCHECK(CalledOnValidThread()); 208 STLDeleteContainerPointers(prefs_.begin(), prefs_.end()); 209 prefs_.clear(); 210 211 // Reset pointers so accesses after destruction reliably crash. 212 pref_value_store_.reset(); 213 user_pref_store_ = NULL; 214 default_store_ = NULL; 215} 216 217void PrefService::InitFromStorage() { 218#ifndef ANDROID 219 const PersistentPrefStore::PrefReadError error = 220 user_pref_store_->ReadPrefs(); 221 if (error == PersistentPrefStore::PREF_READ_ERROR_NONE) 222 return; 223 224 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for 225 // an example problem that this can cause. 226 // Do some diagnosis and try to avoid losing data. 227 int message_id = 0; 228 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) { 229 message_id = IDS_PREFERENCES_CORRUPT_ERROR; 230 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) { 231 message_id = IDS_PREFERENCES_UNREADABLE_ERROR; 232 } 233 234 if (message_id) { 235 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 236 NewRunnableFunction(&NotifyReadError, this, message_id)); 237 } 238 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20); 239#endif 240} 241 242bool PrefService::ReloadPersistentPrefs() { 243 return user_pref_store_->ReadPrefs() == 244 PersistentPrefStore::PREF_READ_ERROR_NONE; 245} 246 247bool PrefService::SavePersistentPrefs() { 248 DCHECK(CalledOnValidThread()); 249 250 return user_pref_store_->WritePrefs(); 251} 252 253void PrefService::ScheduleSavePersistentPrefs() { 254 DCHECK(CalledOnValidThread()); 255 256 user_pref_store_->ScheduleWritePrefs(); 257} 258 259void PrefService::RegisterBooleanPref(const char* path, 260 bool default_value) { 261 RegisterPreference(path, Value::CreateBooleanValue(default_value)); 262} 263 264void PrefService::RegisterIntegerPref(const char* path, int default_value) { 265 RegisterPreference(path, Value::CreateIntegerValue(default_value)); 266} 267 268void PrefService::RegisterDoublePref(const char* path, double default_value) { 269 RegisterPreference(path, Value::CreateDoubleValue(default_value)); 270} 271 272void PrefService::RegisterStringPref(const char* path, 273 const std::string& default_value) { 274 RegisterPreference(path, Value::CreateStringValue(default_value)); 275} 276 277void PrefService::RegisterFilePathPref(const char* path, 278 const FilePath& default_value) { 279 RegisterPreference(path, Value::CreateStringValue(default_value.value())); 280} 281 282void PrefService::RegisterListPref(const char* path) { 283 RegisterPreference(path, new ListValue()); 284} 285 286void PrefService::RegisterListPref(const char* path, ListValue* default_value) { 287 RegisterPreference(path, default_value); 288} 289 290void PrefService::RegisterDictionaryPref(const char* path) { 291 RegisterPreference(path, new DictionaryValue()); 292} 293 294void PrefService::RegisterDictionaryPref(const char* path, 295 DictionaryValue* default_value) { 296 RegisterPreference(path, default_value); 297} 298 299void PrefService::RegisterLocalizedBooleanPref(const char* path, 300 int locale_default_message_id) { 301 RegisterPreference( 302 path, 303 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id)); 304} 305 306void PrefService::RegisterLocalizedIntegerPref(const char* path, 307 int locale_default_message_id) { 308 RegisterPreference( 309 path, 310 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id)); 311} 312 313void PrefService::RegisterLocalizedDoublePref(const char* path, 314 int locale_default_message_id) { 315 RegisterPreference( 316 path, 317 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id)); 318} 319 320void PrefService::RegisterLocalizedStringPref(const char* path, 321 int locale_default_message_id) { 322 RegisterPreference( 323 path, 324 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id)); 325} 326 327bool PrefService::GetBoolean(const char* path) const { 328 DCHECK(CalledOnValidThread()); 329 330 bool result = false; 331 332 const Preference* pref = FindPreference(path); 333 if (!pref) { 334 NOTREACHED() << "Trying to read an unregistered pref: " << path; 335 return result; 336 } 337 bool rv = pref->GetValue()->GetAsBoolean(&result); 338 DCHECK(rv); 339 return result; 340} 341 342int PrefService::GetInteger(const char* path) const { 343 DCHECK(CalledOnValidThread()); 344 345 int result = 0; 346 347 const Preference* pref = FindPreference(path); 348 if (!pref) { 349 NOTREACHED() << "Trying to read an unregistered pref: " << path; 350 return result; 351 } 352 bool rv = pref->GetValue()->GetAsInteger(&result); 353 DCHECK(rv); 354 return result; 355} 356 357double PrefService::GetDouble(const char* path) const { 358 DCHECK(CalledOnValidThread()); 359 360 double result = 0.0; 361 362 const Preference* pref = FindPreference(path); 363 if (!pref) { 364 NOTREACHED() << "Trying to read an unregistered pref: " << path; 365 return result; 366 } 367 bool rv = pref->GetValue()->GetAsDouble(&result); 368 DCHECK(rv); 369 return result; 370} 371 372std::string PrefService::GetString(const char* path) const { 373 DCHECK(CalledOnValidThread()); 374 375 std::string result; 376 377 const Preference* pref = FindPreference(path); 378 if (!pref) { 379 NOTREACHED() << "Trying to read an unregistered pref: " << path; 380 return result; 381 } 382 bool rv = pref->GetValue()->GetAsString(&result); 383 DCHECK(rv); 384 return result; 385} 386 387FilePath PrefService::GetFilePath(const char* path) const { 388 DCHECK(CalledOnValidThread()); 389 390 FilePath::StringType result; 391 392 const Preference* pref = FindPreference(path); 393 if (!pref) { 394 NOTREACHED() << "Trying to read an unregistered pref: " << path; 395 return FilePath(result); 396 } 397 bool rv = pref->GetValue()->GetAsString(&result); 398 DCHECK(rv); 399#if defined(OS_POSIX) 400 // We store filepaths as UTF8, so convert it back to the system type. 401 result = base::SysWideToNativeMB(UTF8ToWide(result)); 402#endif 403 return FilePath(result); 404} 405 406bool PrefService::HasPrefPath(const char* path) const { 407 const Preference* pref = FindPreference(path); 408 return pref && !pref->IsDefaultValue(); 409} 410 411DictionaryValue* PrefService::GetPreferenceValues() const { 412 DCHECK(CalledOnValidThread()); 413 DictionaryValue* out = new DictionaryValue; 414 DefaultPrefStore::const_iterator i = default_store_->begin(); 415 for (; i != default_store_->end(); ++i) { 416 const Value* value = FindPreference(i->first.c_str())->GetValue(); 417 out->Set(i->first, value->DeepCopy()); 418 } 419 return out; 420} 421 422const PrefService::Preference* PrefService::FindPreference( 423 const char* pref_name) const { 424 DCHECK(CalledOnValidThread()); 425 Preference p(this, pref_name, Value::TYPE_NULL); 426 PreferenceSet::const_iterator it = prefs_.find(&p); 427 if (it != prefs_.end()) 428 return *it; 429 const Value::ValueType type = default_store_->GetType(pref_name); 430 if (type == Value::TYPE_NULL) 431 return NULL; 432 Preference* new_pref = new Preference(this, pref_name, type); 433 prefs_.insert(new_pref); 434 return new_pref; 435} 436 437bool PrefService::ReadOnly() const { 438 return user_pref_store_->ReadOnly(); 439} 440 441PrefNotifier* PrefService::pref_notifier() const { 442#ifdef ANDROID 443 return NULL; 444#else 445 return pref_notifier_.get(); 446#endif 447} 448 449bool PrefService::IsManagedPreference(const char* pref_name) const { 450 const Preference* pref = FindPreference(pref_name); 451 return pref && pref->IsManaged(); 452} 453 454const DictionaryValue* PrefService::GetDictionary(const char* path) const { 455 DCHECK(CalledOnValidThread()); 456 457 const Preference* pref = FindPreference(path); 458 if (!pref) { 459 NOTREACHED() << "Trying to read an unregistered pref: " << path; 460 return NULL; 461 } 462 const Value* value = pref->GetValue(); 463 if (value->GetType() != Value::TYPE_DICTIONARY) { 464 NOTREACHED(); 465 return NULL; 466 } 467 return static_cast<const DictionaryValue*>(value); 468} 469 470const ListValue* PrefService::GetList(const char* path) const { 471 DCHECK(CalledOnValidThread()); 472 473 const Preference* pref = FindPreference(path); 474 if (!pref) { 475 NOTREACHED() << "Trying to read an unregistered pref: " << path; 476 return NULL; 477 } 478 const Value* value = pref->GetValue(); 479 if (value->GetType() != Value::TYPE_LIST) { 480 NOTREACHED(); 481 return NULL; 482 } 483 return static_cast<const ListValue*>(value); 484} 485 486#ifndef ANDROID 487void PrefService::AddPrefObserver(const char* path, 488 NotificationObserver* obs) { 489 pref_notifier_->AddPrefObserver(path, obs); 490} 491 492void PrefService::RemovePrefObserver(const char* path, 493 NotificationObserver* obs) { 494 pref_notifier_->RemovePrefObserver(path, obs); 495} 496#endif 497 498void PrefService::RegisterPreference(const char* path, Value* default_value) { 499 DCHECK(CalledOnValidThread()); 500 501 // The main code path takes ownership, but most don't. We'll be safe. 502 scoped_ptr<Value> scoped_value(default_value); 503 504 if (FindPreference(path)) { 505 NOTREACHED() << "Tried to register duplicate pref " << path; 506 return; 507 } 508 509 Value::ValueType orig_type = default_value->GetType(); 510 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << 511 "invalid preference type: " << orig_type; 512 513 // Hand off ownership. 514 default_store_->SetDefaultValue(path, scoped_value.release()); 515} 516 517void PrefService::ClearPref(const char* path) { 518 DCHECK(CalledOnValidThread()); 519 520 const Preference* pref = FindPreference(path); 521 if (!pref) { 522 NOTREACHED() << "Trying to clear an unregistered pref: " << path; 523 return; 524 } 525#ifndef ANDROID 526 user_pref_store_->RemoveValue(path); 527#endif 528} 529 530void PrefService::Set(const char* path, const Value& value) { 531 DCHECK(CalledOnValidThread()); 532 533 const Preference* pref = FindPreference(path); 534 if (!pref) { 535 NOTREACHED() << "Trying to write an unregistered pref: " << path; 536 return; 537 } 538 539 if (pref->GetType() != value.GetType()) { 540 NOTREACHED() << "Trying to set pref " << path 541 << " of type " << pref->GetType() 542 << " to value of type " << value.GetType(); 543 } else { 544 user_pref_store_->SetValue(path, value.DeepCopy()); 545 } 546} 547 548void PrefService::SetBoolean(const char* path, bool value) { 549 SetUserPrefValue(path, Value::CreateBooleanValue(value)); 550} 551 552void PrefService::SetInteger(const char* path, int value) { 553 SetUserPrefValue(path, Value::CreateIntegerValue(value)); 554} 555 556void PrefService::SetDouble(const char* path, double value) { 557 SetUserPrefValue(path, Value::CreateDoubleValue(value)); 558} 559 560void PrefService::SetString(const char* path, const std::string& value) { 561 SetUserPrefValue(path, Value::CreateStringValue(value)); 562} 563 564void PrefService::SetFilePath(const char* path, const FilePath& value) { 565#if defined(OS_POSIX) 566 // Value::SetString only knows about UTF8 strings, so convert the path from 567 // the system native value to UTF8. 568 std::string path_utf8 = WideToUTF8(base::SysNativeMBToWide(value.value())); 569 Value* new_value = Value::CreateStringValue(path_utf8); 570#else 571 Value* new_value = Value::CreateStringValue(value.value()); 572#endif 573 574 SetUserPrefValue(path, new_value); 575} 576 577void PrefService::SetInt64(const char* path, int64 value) { 578 SetUserPrefValue(path, Value::CreateStringValue(base::Int64ToString(value))); 579} 580 581int64 PrefService::GetInt64(const char* path) const { 582 DCHECK(CalledOnValidThread()); 583 584 const Preference* pref = FindPreference(path); 585 if (!pref) { 586 NOTREACHED() << "Trying to read an unregistered pref: " << path; 587 return 0; 588 } 589 std::string result("0"); 590 bool rv = pref->GetValue()->GetAsString(&result); 591 DCHECK(rv); 592 593 int64 val; 594 base::StringToInt64(result, &val); 595 return val; 596} 597 598void PrefService::RegisterInt64Pref(const char* path, int64 default_value) { 599 RegisterPreference( 600 path, Value::CreateStringValue(base::Int64ToString(default_value))); 601} 602 603DictionaryValue* PrefService::GetMutableDictionary(const char* path) { 604 DCHECK(CalledOnValidThread()); 605 DLOG_IF(WARNING, IsManagedPreference(path)) << 606 "Attempt to change managed preference " << path; 607 608 const Preference* pref = FindPreference(path); 609 if (!pref) { 610 NOTREACHED() << "Trying to get an unregistered pref: " << path; 611 return NULL; 612 } 613 if (pref->GetType() != Value::TYPE_DICTIONARY) { 614 NOTREACHED() << "Wrong type for GetMutableDictionary: " << path; 615 return NULL; 616 } 617 618 DictionaryValue* dict = NULL; 619 Value* tmp_value = NULL; 620 // Look for an existing preference in the user store. If it doesn't 621 // exist or isn't the correct type, create a new user preference. 622 if (user_pref_store_->GetValue(path, &tmp_value) 623 != PersistentPrefStore::READ_OK || 624 !tmp_value->IsType(Value::TYPE_DICTIONARY)) { 625 dict = new DictionaryValue; 626 user_pref_store_->SetValueSilently(path, dict); 627 } else { 628 dict = static_cast<DictionaryValue*>(tmp_value); 629 } 630 return dict; 631} 632 633ListValue* PrefService::GetMutableList(const char* path) { 634 DCHECK(CalledOnValidThread()); 635 DLOG_IF(WARNING, IsManagedPreference(path)) << 636 "Attempt to change managed preference " << path; 637 638 const Preference* pref = FindPreference(path); 639 if (!pref) { 640 NOTREACHED() << "Trying to get an unregistered pref: " << path; 641 return NULL; 642 } 643 if (pref->GetType() != Value::TYPE_LIST) { 644 NOTREACHED() << "Wrong type for GetMutableList: " << path; 645 return NULL; 646 } 647 648 ListValue* list = NULL; 649 Value* tmp_value = NULL; 650 // Look for an existing preference in the user store. If it doesn't 651 // exist or isn't the correct type, create a new user preference. 652 if (user_pref_store_->GetValue(path, &tmp_value) 653 != PersistentPrefStore::READ_OK || 654 !tmp_value->IsType(Value::TYPE_LIST)) { 655 list = new ListValue; 656 user_pref_store_->SetValueSilently(path, list); 657 } else { 658 list = static_cast<ListValue*>(tmp_value); 659 } 660 return list; 661} 662 663void PrefService::SetUserPrefValue(const char* path, Value* new_value) { 664 DCHECK(CalledOnValidThread()); 665 DLOG_IF(WARNING, IsManagedPreference(path)) << 666 "Attempt to change managed preference " << path; 667 668 const Preference* pref = FindPreference(path); 669 if (!pref) { 670 NOTREACHED() << "Trying to write an unregistered pref: " << path; 671 return; 672 } 673 if (pref->GetType() != new_value->GetType()) { 674 NOTREACHED() << "Trying to set pref " << path 675 << " of type " << pref->GetType() 676 << " to value of type " << new_value->GetType(); 677 return; 678 } 679 680#ifndef ANDROID 681 user_pref_store_->SetValue(path, new_value); 682#endif 683} 684 685/////////////////////////////////////////////////////////////////////////////// 686// PrefService::Preference 687 688PrefService::Preference::Preference(const PrefService* service, 689 const char* name, 690 Value::ValueType type) 691 : name_(name), 692 type_(type), 693 pref_service_(service) { 694 DCHECK(name); 695 DCHECK(service); 696} 697 698Value::ValueType PrefService::Preference::GetType() const { 699 return type_; 700} 701 702const Value* PrefService::Preference::GetValue() const { 703 DCHECK(pref_service_->FindPreference(name_.c_str())) << 704 "Must register pref before getting its value"; 705 706 Value* found_value = NULL; 707 if (pref_value_store()->GetValue(name_, type_, &found_value)) { 708 DCHECK(found_value->IsType(type_)); 709 return found_value; 710 } 711 712 // Every registered preference has at least a default value. 713 NOTREACHED() << "no valid value found for registered pref " << name_; 714 return NULL; 715} 716 717bool PrefService::Preference::IsManaged() const { 718 return pref_value_store()->PrefValueInManagedStore(name_.c_str()); 719} 720 721bool PrefService::Preference::HasExtensionSetting() const { 722 return pref_value_store()->PrefValueInExtensionStore(name_.c_str()); 723} 724 725bool PrefService::Preference::HasUserSetting() const { 726 return pref_value_store()->PrefValueInUserStore(name_.c_str()); 727} 728 729bool PrefService::Preference::IsExtensionControlled() const { 730 return pref_value_store()->PrefValueFromExtensionStore(name_.c_str()); 731} 732 733bool PrefService::Preference::IsUserControlled() const { 734 return pref_value_store()->PrefValueFromUserStore(name_.c_str()); 735} 736 737bool PrefService::Preference::IsDefaultValue() const { 738 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str()); 739} 740 741bool PrefService::Preference::IsUserModifiable() const { 742 return pref_value_store()->PrefValueUserModifiable(name_.c_str()); 743} 744