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