Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: chrome/browser/prefs/pref_service.cc

Issue 5441002: Clean up pref change notification handling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #include <string> 8 #include <string>
9 9
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/message_loop.h" 15 #include "base/message_loop.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/stl_util-inl.h" 17 #include "base/stl_util-inl.h"
18 #include "base/string_number_conversions.h" 18 #include "base/string_number_conversions.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/sys_string_conversions.h" 20 #include "base/sys_string_conversions.h"
21 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
22 #include "build/build_config.h" 22 #include "build/build_config.h"
23 #include "chrome/browser/browser_thread.h" 23 #include "chrome/browser/browser_thread.h"
24 #include "chrome/browser/extensions/extension_pref_store.h"
25 #include "chrome/browser/policy/configuration_policy_pref_store.h"
26 #include "chrome/browser/prefs/command_line_pref_store.h"
27 #include "chrome/browser/prefs/default_pref_store.h"
24 #include "chrome/browser/prefs/pref_notifier.h" 28 #include "chrome/browser/prefs/pref_notifier.h"
25 #include "chrome/browser/prefs/pref_value_store.h" 29 #include "chrome/browser/prefs/pref_value_store.h"
26 #include "chrome/browser/profile.h" 30 #include "chrome/browser/profile.h"
31 #include "chrome/common/json_pref_store.h"
27 #include "chrome/common/notification_service.h" 32 #include "chrome/common/notification_service.h"
28 #include "grit/chromium_strings.h" 33 #include "grit/chromium_strings.h"
29 #include "grit/generated_resources.h" 34 #include "grit/generated_resources.h"
30 35
31 namespace { 36 namespace {
32 37
33 // A helper function for RegisterLocalized*Pref that creates a Value* based on 38 // A helper function for RegisterLocalized*Pref that creates a Value* based on
34 // the string value in the locale dll. Because we control the values in a 39 // the string value in the locale dll. Because we control the values in a
35 // locale dll, this should always return a Value of the appropriate type. 40 // locale dll, this should always return a Value of the appropriate type.
36 Value* CreateLocaleDefaultValue(Value::ValueType type, int message_id) { 41 Value* CreateLocaleDefaultValue(Value::ValueType type, int message_id) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 Source<PrefService> source(pref); 81 Source<PrefService> source(pref);
77 NotificationService::current()->Notify(NotificationType::PROFILE_ERROR, 82 NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
78 source, Details<int>(&message_id)); 83 source, Details<int>(&message_id));
79 } 84 }
80 85
81 } // namespace 86 } // namespace
82 87
83 // static 88 // static
84 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, 89 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
85 Profile* profile) { 90 Profile* profile) {
91 using policy::ConfigurationPolicyPrefStore;
92
86 #if defined(OS_LINUX) 93 #if defined(OS_LINUX)
87 // We'd like to see what fraction of our users have the preferences 94 // We'd like to see what fraction of our users have the preferences
88 // stored on a network file system, as we've had no end of troubles 95 // stored on a network file system, as we've had no end of troubles
89 // with NFS/AFS. 96 // with NFS/AFS.
90 // TODO(evanm): remove this once we've collected state. 97 // TODO(evanm): remove this once we've collected state.
91 file_util::FileSystemType fstype; 98 file_util::FileSystemType fstype;
92 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) { 99 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
93 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType", 100 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
94 static_cast<int>(fstype), 101 static_cast<int>(fstype),
95 file_util::FILE_SYSTEM_TYPE_COUNT); 102 file_util::FILE_SYSTEM_TYPE_COUNT);
96 } 103 }
97 #endif 104 #endif
98 105
99 return new PrefService( 106 ConfigurationPolicyPrefStore* managed =
100 PrefValueStore::CreatePrefValueStore(pref_filename, profile, false)); 107 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore();
108 ConfigurationPolicyPrefStore* device_management =
109 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
110 profile);
111 ExtensionPrefStore* extension = new ExtensionPrefStore(profile);
112 CommandLinePrefStore* command_line =
113 new CommandLinePrefStore(CommandLine::ForCurrentProcess());
114 JsonPrefStore* user = new JsonPrefStore(
115 pref_filename,
116 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
117 ConfigurationPolicyPrefStore* recommended =
118 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore();
119
120 return new PrefService(managed, device_management, extension, command_line,
121 user, recommended, profile);
101 } 122 }
102 123
103 // static 124 // static
104 PrefService* PrefService::CreateUserPrefService(const FilePath& pref_filename) { 125 PrefService* PrefService::CreateUserPrefService(const FilePath& pref_filename) {
105 return new PrefService( 126 JsonPrefStore* user = new JsonPrefStore(
106 PrefValueStore::CreatePrefValueStore(pref_filename, NULL, true)); 127 pref_filename,
128 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
129
130 return new PrefService(NULL, NULL, NULL, NULL, user, NULL, NULL);
107 } 131 }
108 132
109 PrefService::PrefService(PrefValueStore* pref_value_store) 133 PrefService::PrefService(PrefStore* managed_platform_prefs,
110 : pref_value_store_(pref_value_store) { 134 PrefStore* device_management_prefs,
111 pref_notifier_.reset(new PrefNotifier(this, pref_value_store)); 135 PrefStore* extension_prefs,
136 PrefStore* command_line_prefs,
137 PrefStore* user_prefs,
138 PrefStore* recommended_prefs,
139 Profile* profile) {
140 pref_notifier_.reset(new PrefNotifier(this));
141 default_store_ = new DefaultPrefStore();
142 pref_value_store_ =
143 new PrefValueStore(managed_platform_prefs,
144 device_management_prefs,
145 extension_prefs,
146 command_line_prefs,
147 user_prefs,
148 recommended_prefs,
149 default_store_,
150 pref_notifier_.get(),
151 profile);
112 InitFromStorage(); 152 InitFromStorage();
113 } 153 }
114 154
115 PrefService::~PrefService() { 155 PrefService::~PrefService() {
116 DCHECK(CalledOnValidThread()); 156 DCHECK(CalledOnValidThread());
117 STLDeleteContainerPointers(prefs_.begin(), prefs_.end()); 157 STLDeleteContainerPointers(prefs_.begin(), prefs_.end());
118 prefs_.clear(); 158 prefs_.clear();
119 } 159 }
120 160
121 void PrefService::InitFromStorage() { 161 void PrefService::InitFromStorage() {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 } 352 }
313 353
314 const PrefService::Preference* PrefService::FindPreference( 354 const PrefService::Preference* PrefService::FindPreference(
315 const char* pref_name) const { 355 const char* pref_name) const {
316 DCHECK(CalledOnValidThread()); 356 DCHECK(CalledOnValidThread());
317 Preference p(this, pref_name); 357 Preference p(this, pref_name);
318 PreferenceSet::const_iterator it = prefs_.find(&p); 358 PreferenceSet::const_iterator it = prefs_.find(&p);
319 return it == prefs_.end() ? NULL : *it; 359 return it == prefs_.end() ? NULL : *it;
320 } 360 }
321 361
362 bool PrefService::ReadOnly() const {
363 return pref_value_store_->ReadOnly();
364 }
365
366 PrefNotifier* PrefService::pref_notifier() const {
367 return pref_notifier_.get();
368 }
369
322 bool PrefService::IsManagedPreference(const char* pref_name) const { 370 bool PrefService::IsManagedPreference(const char* pref_name) const {
323 const Preference* pref = FindPreference(pref_name); 371 const Preference* pref = FindPreference(pref_name);
324 if (pref && pref->IsManaged()) { 372 if (pref && pref->IsManaged()) {
325 return true; 373 return true;
326 } 374 }
327 return false; 375 return false;
328 } 376 }
329 377
330 const DictionaryValue* PrefService::GetDictionary(const char* path) const { 378 const DictionaryValue* PrefService::GetDictionary(const char* path) const {
331 DCHECK(CalledOnValidThread()); 379 DCHECK(CalledOnValidThread());
(...skipping 16 matching lines...) Expand all
348 if (!pref) { 396 if (!pref) {
349 NOTREACHED() << "Trying to read an unregistered pref: " << path; 397 NOTREACHED() << "Trying to read an unregistered pref: " << path;
350 return NULL; 398 return NULL;
351 } 399 }
352 const Value* value = pref->GetValue(); 400 const Value* value = pref->GetValue();
353 if (value->GetType() == Value::TYPE_NULL) 401 if (value->GetType() == Value::TYPE_NULL)
354 return NULL; 402 return NULL;
355 return static_cast<const ListValue*>(value); 403 return static_cast<const ListValue*>(value);
356 } 404 }
357 405
358 bool PrefService::ReadOnly() const {
359 return pref_value_store_->ReadOnly();
360 }
361
362 void PrefService::AddPrefObserver(const char* path, 406 void PrefService::AddPrefObserver(const char* path,
363 NotificationObserver* obs) { 407 NotificationObserver* obs) {
364 pref_notifier_->AddPrefObserver(path, obs); 408 pref_notifier_->AddPrefObserver(path, obs);
365 } 409 }
366 410
367 void PrefService::RemovePrefObserver(const char* path, 411 void PrefService::RemovePrefObserver(const char* path,
368 NotificationObserver* obs) { 412 NotificationObserver* obs) {
369 pref_notifier_->RemovePrefObserver(path, obs); 413 pref_notifier_->RemovePrefObserver(path, obs);
370 } 414 }
371 415
372 void PrefService::RegisterPreference(const char* path, Value* default_value) { 416 void PrefService::RegisterPreference(const char* path, Value* default_value) {
373 DCHECK(CalledOnValidThread()); 417 DCHECK(CalledOnValidThread());
374 418
375 // The main code path takes ownership, but most don't. We'll be safe. 419 // The main code path takes ownership, but most don't. We'll be safe.
376 scoped_ptr<Value> scoped_value(default_value); 420 scoped_ptr<Value> scoped_value(default_value);
377 421
378 if (FindPreference(path)) { 422 if (FindPreference(path)) {
379 NOTREACHED() << "Tried to register duplicate pref " << path; 423 NOTREACHED() << "Tried to register duplicate pref " << path;
380 return; 424 return;
381 } 425 }
382 426
383 Value::ValueType orig_type = default_value->GetType(); 427 Value::ValueType orig_type = default_value->GetType();
384 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << 428 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
385 "invalid preference type: " << orig_type; 429 "invalid preference type: " << orig_type;
386 430
387 // We set the default value of dictionaries and lists to be null so it's 431 // We set the default value of dictionaries and lists to be null so it's
388 // easier for callers to check for empty dict/list prefs. The PrefValueStore 432 // easier for callers to check for empty dict/list prefs. The PrefValueStore
389 // accepts ownership of the value (null or default_value). 433 // accepts ownership of the value (null or default_value).
390 if (Value::TYPE_LIST == orig_type || Value::TYPE_DICTIONARY == orig_type) { 434 if (Value::TYPE_LIST == orig_type || Value::TYPE_DICTIONARY == orig_type) {
391 pref_value_store_->SetDefaultPrefValue(path, Value::CreateNullValue()); 435 default_store_->prefs()->Set(path, Value::CreateNullValue());
392 } else { 436 } else {
393 // Hand off ownership. 437 // Hand off ownership.
394 DCHECK(!PrefStore::IsUseDefaultSentinelValue(default_value)); 438 DCHECK(!PrefStore::IsUseDefaultSentinelValue(default_value));
395 pref_value_store_->SetDefaultPrefValue(path, scoped_value.release()); 439 default_store_->prefs()->Set(path, scoped_value.release());
396 } 440 }
397 441
398 pref_value_store_->RegisterPreferenceType(path, orig_type); 442 pref_value_store_->RegisterPreferenceType(path, orig_type);
399 prefs_.insert(new Preference(this, path)); 443 prefs_.insert(new Preference(this, path));
400 } 444 }
401 445
402 void PrefService::ClearPref(const char* path) { 446 void PrefService::ClearPref(const char* path) {
403 DCHECK(CalledOnValidThread()); 447 DCHECK(CalledOnValidThread());
404 448
405 const Preference* pref = FindPreference(path); 449 const Preference* pref = FindPreference(path);
406 if (!pref) { 450 if (!pref) {
407 NOTREACHED() << "Trying to clear an unregistered pref: " << path; 451 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
408 return; 452 return;
409 } 453 }
410 if (pref_value_store_->RemoveUserPrefValue(path)) 454 pref_value_store_->RemoveUserPrefValue(path);
411 pref_notifier_->OnUserPreferenceSet(path);
412 } 455 }
413 456
414 void PrefService::Set(const char* path, const Value& value) { 457 void PrefService::Set(const char* path, const Value& value) {
415 DCHECK(CalledOnValidThread()); 458 DCHECK(CalledOnValidThread());
416 459
417 const Preference* pref = FindPreference(path); 460 const Preference* pref = FindPreference(path);
418 if (!pref) { 461 if (!pref) {
419 NOTREACHED() << "Trying to write an unregistered pref: " << path; 462 NOTREACHED() << "Trying to write an unregistered pref: " << path;
420 return; 463 return;
421 } 464 }
422 465
423 // Allow dictionary and list types to be set to null, which removes their 466 // Allow dictionary and list types to be set to null, which removes their
424 // user values. 467 // user values.
425 bool value_changed = false;
426 if (value.GetType() == Value::TYPE_NULL && 468 if (value.GetType() == Value::TYPE_NULL &&
427 (pref->GetType() == Value::TYPE_DICTIONARY || 469 (pref->GetType() == Value::TYPE_DICTIONARY ||
428 pref->GetType() == Value::TYPE_LIST)) { 470 pref->GetType() == Value::TYPE_LIST)) {
429 value_changed = pref_value_store_->RemoveUserPrefValue(path); 471 pref_value_store_->RemoveUserPrefValue(path);
430 } else if (pref->GetType() != value.GetType()) { 472 } else if (pref->GetType() != value.GetType()) {
431 NOTREACHED() << "Trying to set pref " << path 473 NOTREACHED() << "Trying to set pref " << path
432 << " of type " << pref->GetType() 474 << " of type " << pref->GetType()
433 << " to value of type " << value.GetType(); 475 << " to value of type " << value.GetType();
434 } else { 476 } else {
435 value_changed = pref_value_store_->SetUserPrefValue(path, value.DeepCopy()); 477 pref_value_store_->SetUserPrefValue(path, value.DeepCopy());
436 } 478 }
437
438 if (value_changed)
439 pref_notifier_->OnUserPreferenceSet(path);
440 } 479 }
441 480
442 void PrefService::SetBoolean(const char* path, bool value) { 481 void PrefService::SetBoolean(const char* path, bool value) {
443 SetUserPrefValue(path, Value::CreateBooleanValue(value)); 482 SetUserPrefValue(path, Value::CreateBooleanValue(value));
444 } 483 }
445 484
446 void PrefService::SetInteger(const char* path, int value) { 485 void PrefService::SetInteger(const char* path, int value) {
447 SetUserPrefValue(path, Value::CreateIntegerValue(value)); 486 SetUserPrefValue(path, Value::CreateIntegerValue(value));
448 } 487 }
449 488
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 return NULL; 546 return NULL;
508 } 547 }
509 548
510 DictionaryValue* dict = NULL; 549 DictionaryValue* dict = NULL;
511 Value* tmp_value = NULL; 550 Value* tmp_value = NULL;
512 // Look for an existing preference in the user store. If it doesn't 551 // Look for an existing preference in the user store. If it doesn't
513 // exist or isn't the correct type, create a new user preference. 552 // exist or isn't the correct type, create a new user preference.
514 if (!pref_value_store_->GetUserValue(path, &tmp_value) || 553 if (!pref_value_store_->GetUserValue(path, &tmp_value) ||
515 !tmp_value->IsType(Value::TYPE_DICTIONARY)) { 554 !tmp_value->IsType(Value::TYPE_DICTIONARY)) {
516 dict = new DictionaryValue; 555 dict = new DictionaryValue;
517 pref_value_store_->SetUserPrefValue(path, dict); 556 pref_value_store_->PutUserPrefValue(path, dict);
danno 2010/12/02 10:31:52 Call this SetUserPrefValueWithoutNotification/Sile
Mattias Nissler (ping if slow) 2010/12/02 16:38:24 Done.
518 } else { 557 } else {
519 dict = static_cast<DictionaryValue*>(tmp_value); 558 dict = static_cast<DictionaryValue*>(tmp_value);
520 } 559 }
521 return dict; 560 return dict;
522 } 561 }
523 562
524 ListValue* PrefService::GetMutableList(const char* path) { 563 ListValue* PrefService::GetMutableList(const char* path) {
525 DCHECK(CalledOnValidThread()); 564 DCHECK(CalledOnValidThread());
526 565
527 const Preference* pref = FindPreference(path); 566 const Preference* pref = FindPreference(path);
528 if (!pref) { 567 if (!pref) {
529 NOTREACHED() << "Trying to get an unregistered pref: " << path; 568 NOTREACHED() << "Trying to get an unregistered pref: " << path;
530 return NULL; 569 return NULL;
531 } 570 }
532 if (pref->GetType() != Value::TYPE_LIST) { 571 if (pref->GetType() != Value::TYPE_LIST) {
533 NOTREACHED() << "Wrong type for GetMutableList: " << path; 572 NOTREACHED() << "Wrong type for GetMutableList: " << path;
534 return NULL; 573 return NULL;
535 } 574 }
536 575
537 ListValue* list = NULL; 576 ListValue* list = NULL;
538 Value* tmp_value = NULL; 577 Value* tmp_value = NULL;
539 // Look for an existing preference in the user store. If it doesn't 578 // Look for an existing preference in the user store. If it doesn't
540 // exist or isn't the correct type, create a new user preference. 579 // exist or isn't the correct type, create a new user preference.
541 if (!pref_value_store_->GetUserValue(path, &tmp_value) || 580 if (!pref_value_store_->GetUserValue(path, &tmp_value) ||
542 !tmp_value->IsType(Value::TYPE_LIST)) { 581 !tmp_value->IsType(Value::TYPE_LIST)) {
543 list = new ListValue; 582 list = new ListValue;
544 pref_value_store_->SetUserPrefValue(path, list); 583 pref_value_store_->PutUserPrefValue(path, list);
545 } else { 584 } else {
546 list = static_cast<ListValue*>(tmp_value); 585 list = static_cast<ListValue*>(tmp_value);
547 } 586 }
548 return list; 587 return list;
549 } 588 }
550 589
551 Value* PrefService::GetPrefCopy(const char* path) { 590 Value* PrefService::GetPrefCopy(const char* path) {
552 DCHECK(CalledOnValidThread()); 591 DCHECK(CalledOnValidThread());
553 592
554 const Preference* pref = FindPreference(path); 593 const Preference* pref = FindPreference(path);
(...skipping 13 matching lines...) Expand all
568 NOTREACHED() << "Preference is managed: " << path; 607 NOTREACHED() << "Preference is managed: " << path;
569 return; 608 return;
570 } 609 }
571 if (pref->GetType() != new_value->GetType()) { 610 if (pref->GetType() != new_value->GetType()) {
572 NOTREACHED() << "Trying to set pref " << path 611 NOTREACHED() << "Trying to set pref " << path
573 << " of type " << pref->GetType() 612 << " of type " << pref->GetType()
574 << " to value of type " << new_value->GetType(); 613 << " to value of type " << new_value->GetType();
575 return; 614 return;
576 } 615 }
577 616
578 if (pref_value_store_->SetUserPrefValue(path, new_value)) 617 pref_value_store_->SetUserPrefValue(path, new_value);
579 pref_notifier_->OnUserPreferenceSet(path);
580 } 618 }
581 619
582 /////////////////////////////////////////////////////////////////////////////// 620 ///////////////////////////////////////////////////////////////////////////////
583 // PrefService::Preference 621 // PrefService::Preference
584 622
585 PrefService::Preference::Preference(const PrefService* service, 623 PrefService::Preference::Preference(const PrefService* service,
586 const char* name) 624 const char* name)
587 : name_(name), 625 : name_(name),
588 pref_service_(service) { 626 pref_service_(service) {
589 DCHECK(name); 627 DCHECK(name);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 674
637 bool PrefService::Preference::IsDefaultValue() const { 675 bool PrefService::Preference::IsDefaultValue() const {
638 return pref_service_->pref_value_store_-> 676 return pref_service_->pref_value_store_->
639 PrefValueFromDefaultStore(name_.c_str()); 677 PrefValueFromDefaultStore(name_.c_str());
640 } 678 }
641 679
642 bool PrefService::Preference::IsUserModifiable() const { 680 bool PrefService::Preference::IsUserModifiable() const {
643 return pref_service_->pref_value_store_-> 681 return pref_service_->pref_value_store_->
644 PrefValueUserModifiable(name_.c_str()); 682 PrefValueUserModifiable(name_.c_str());
645 } 683 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698