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

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: Fix extension prefs breakage 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
« no previous file with comments | « chrome/browser/prefs/pref_service.h ('k') | chrome/browser/prefs/pref_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/prefs/pref_notifier.h" 24 #include "chrome/browser/policy/configuration_policy_pref_store.h"
25 #include "chrome/browser/prefs/command_line_pref_store.h"
26 #include "chrome/browser/prefs/in_memory_pref_store.h"
27 #include "chrome/browser/prefs/pref_notifier_impl.h"
25 #include "chrome/browser/prefs/pref_value_store.h" 28 #include "chrome/browser/prefs/pref_value_store.h"
26 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/common/json_pref_store.h"
27 #include "chrome/common/notification_service.h" 31 #include "chrome/common/notification_service.h"
28 #include "grit/chromium_strings.h" 32 #include "grit/chromium_strings.h"
29 #include "grit/generated_resources.h" 33 #include "grit/generated_resources.h"
30 34
31 namespace { 35 namespace {
32 36
33 // A helper function for RegisterLocalized*Pref that creates a Value* based on 37 // 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 38 // 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. 39 // locale dll, this should always return a Value of the appropriate type.
36 Value* CreateLocaleDefaultValue(Value::ValueType type, int message_id) { 40 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); 80 Source<PrefService> source(pref);
77 NotificationService::current()->Notify(NotificationType::PROFILE_ERROR, 81 NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
78 source, Details<int>(&message_id)); 82 source, Details<int>(&message_id));
79 } 83 }
80 84
81 } // namespace 85 } // namespace
82 86
83 // static 87 // static
84 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, 88 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
85 Profile* profile) { 89 Profile* profile) {
90 using policy::ConfigurationPolicyPrefStore;
91
86 #if defined(OS_LINUX) 92 #if defined(OS_LINUX)
87 // We'd like to see what fraction of our users have the preferences 93 // 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 94 // stored on a network file system, as we've had no end of troubles
89 // with NFS/AFS. 95 // with NFS/AFS.
90 // TODO(evanm): remove this once we've collected state. 96 // TODO(evanm): remove this once we've collected state.
91 file_util::FileSystemType fstype; 97 file_util::FileSystemType fstype;
92 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) { 98 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
93 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType", 99 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
94 static_cast<int>(fstype), 100 static_cast<int>(fstype),
95 file_util::FILE_SYSTEM_TYPE_COUNT); 101 file_util::FILE_SYSTEM_TYPE_COUNT);
96 } 102 }
97 #endif 103 #endif
98 104
99 return new PrefService( 105 ConfigurationPolicyPrefStore* managed =
100 PrefValueStore::CreatePrefValueStore(pref_filename, profile, false)); 106 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore();
107 ConfigurationPolicyPrefStore* device_management =
108 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
109 profile);
110 InMemoryPrefStore* extension = new InMemoryPrefStore();
111 CommandLinePrefStore* command_line =
112 new CommandLinePrefStore(CommandLine::ForCurrentProcess());
113 JsonPrefStore* user = new JsonPrefStore(
114 pref_filename,
115 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
116 ConfigurationPolicyPrefStore* recommended =
117 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore();
118
119 return new PrefService(managed, device_management, extension, command_line,
120 user, recommended, profile);
101 } 121 }
102 122
103 // static 123 // static
104 PrefService* PrefService::CreateUserPrefService(const FilePath& pref_filename) { 124 PrefService* PrefService::CreateUserPrefService(const FilePath& pref_filename) {
105 return new PrefService( 125 JsonPrefStore* user = new JsonPrefStore(
106 PrefValueStore::CreatePrefValueStore(pref_filename, NULL, true)); 126 pref_filename,
127 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
128 InMemoryPrefStore* extension = new InMemoryPrefStore();
129
130 return new PrefService(NULL, NULL, extension, 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 PrefNotifierImpl(this));
141 extension_store_ = extension_prefs;
142 default_store_ = new InMemoryPrefStore();
143 pref_value_store_ =
144 new PrefValueStore(managed_platform_prefs,
145 device_management_prefs,
146 extension_store_,
147 command_line_prefs,
148 user_prefs,
149 recommended_prefs,
150 default_store_,
151 pref_notifier_.get(),
152 profile);
112 InitFromStorage(); 153 InitFromStorage();
113 } 154 }
114 155
115 PrefService::~PrefService() { 156 PrefService::~PrefService() {
116 DCHECK(CalledOnValidThread()); 157 DCHECK(CalledOnValidThread());
117 STLDeleteContainerPointers(prefs_.begin(), prefs_.end()); 158 STLDeleteContainerPointers(prefs_.begin(), prefs_.end());
118 prefs_.clear(); 159 prefs_.clear();
119 } 160 }
120 161
121 void PrefService::InitFromStorage() { 162 void PrefService::InitFromStorage() {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 } 353 }
313 354
314 const PrefService::Preference* PrefService::FindPreference( 355 const PrefService::Preference* PrefService::FindPreference(
315 const char* pref_name) const { 356 const char* pref_name) const {
316 DCHECK(CalledOnValidThread()); 357 DCHECK(CalledOnValidThread());
317 Preference p(this, pref_name); 358 Preference p(this, pref_name);
318 PreferenceSet::const_iterator it = prefs_.find(&p); 359 PreferenceSet::const_iterator it = prefs_.find(&p);
319 return it == prefs_.end() ? NULL : *it; 360 return it == prefs_.end() ? NULL : *it;
320 } 361 }
321 362
363 bool PrefService::ReadOnly() const {
364 return pref_value_store_->ReadOnly();
365 }
366
367 PrefNotifier* PrefService::pref_notifier() const {
368 return pref_notifier_.get();
369 }
370
371 PrefStore* PrefService::GetExtensionPrefStore() {
372 return extension_store_;
373 }
374
322 bool PrefService::IsManagedPreference(const char* pref_name) const { 375 bool PrefService::IsManagedPreference(const char* pref_name) const {
323 const Preference* pref = FindPreference(pref_name); 376 const Preference* pref = FindPreference(pref_name);
324 if (pref && pref->IsManaged()) { 377 if (pref && pref->IsManaged()) {
325 return true; 378 return true;
326 } 379 }
327 return false; 380 return false;
328 } 381 }
329 382
330 const DictionaryValue* PrefService::GetDictionary(const char* path) const { 383 const DictionaryValue* PrefService::GetDictionary(const char* path) const {
331 DCHECK(CalledOnValidThread()); 384 DCHECK(CalledOnValidThread());
(...skipping 16 matching lines...) Expand all
348 if (!pref) { 401 if (!pref) {
349 NOTREACHED() << "Trying to read an unregistered pref: " << path; 402 NOTREACHED() << "Trying to read an unregistered pref: " << path;
350 return NULL; 403 return NULL;
351 } 404 }
352 const Value* value = pref->GetValue(); 405 const Value* value = pref->GetValue();
353 if (value->GetType() == Value::TYPE_NULL) 406 if (value->GetType() == Value::TYPE_NULL)
354 return NULL; 407 return NULL;
355 return static_cast<const ListValue*>(value); 408 return static_cast<const ListValue*>(value);
356 } 409 }
357 410
358 bool PrefService::ReadOnly() const {
359 return pref_value_store_->ReadOnly();
360 }
361
362 void PrefService::AddPrefObserver(const char* path, 411 void PrefService::AddPrefObserver(const char* path,
363 NotificationObserver* obs) { 412 NotificationObserver* obs) {
364 pref_notifier_->AddPrefObserver(path, obs); 413 pref_notifier_->AddPrefObserver(path, obs);
365 } 414 }
366 415
367 void PrefService::RemovePrefObserver(const char* path, 416 void PrefService::RemovePrefObserver(const char* path,
368 NotificationObserver* obs) { 417 NotificationObserver* obs) {
369 pref_notifier_->RemovePrefObserver(path, obs); 418 pref_notifier_->RemovePrefObserver(path, obs);
370 } 419 }
371 420
372 void PrefService::RegisterPreference(const char* path, Value* default_value) { 421 void PrefService::RegisterPreference(const char* path, Value* default_value) {
373 DCHECK(CalledOnValidThread()); 422 DCHECK(CalledOnValidThread());
374 423
375 // The main code path takes ownership, but most don't. We'll be safe. 424 // The main code path takes ownership, but most don't. We'll be safe.
376 scoped_ptr<Value> scoped_value(default_value); 425 scoped_ptr<Value> scoped_value(default_value);
377 426
378 if (FindPreference(path)) { 427 if (FindPreference(path)) {
379 NOTREACHED() << "Tried to register duplicate pref " << path; 428 NOTREACHED() << "Tried to register duplicate pref " << path;
380 return; 429 return;
381 } 430 }
382 431
383 Value::ValueType orig_type = default_value->GetType(); 432 Value::ValueType orig_type = default_value->GetType();
384 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << 433 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
385 "invalid preference type: " << orig_type; 434 "invalid preference type: " << orig_type;
386 435
387 // We set the default value of dictionaries and lists to be null so it's 436 // 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 437 // easier for callers to check for empty dict/list prefs. The PrefValueStore
389 // accepts ownership of the value (null or default_value). 438 // accepts ownership of the value (null or default_value).
390 if (Value::TYPE_LIST == orig_type || Value::TYPE_DICTIONARY == orig_type) { 439 if (Value::TYPE_LIST == orig_type || Value::TYPE_DICTIONARY == orig_type) {
391 pref_value_store_->SetDefaultPrefValue(path, Value::CreateNullValue()); 440 default_store_->prefs()->Set(path, Value::CreateNullValue());
392 } else { 441 } else {
393 // Hand off ownership. 442 // Hand off ownership.
394 DCHECK(!PrefStore::IsUseDefaultSentinelValue(default_value)); 443 DCHECK(!PrefStore::IsUseDefaultSentinelValue(default_value));
395 pref_value_store_->SetDefaultPrefValue(path, scoped_value.release()); 444 default_store_->prefs()->Set(path, scoped_value.release());
396 } 445 }
397 446
398 pref_value_store_->RegisterPreferenceType(path, orig_type); 447 pref_value_store_->RegisterPreferenceType(path, orig_type);
399 prefs_.insert(new Preference(this, path)); 448 prefs_.insert(new Preference(this, path));
400 } 449 }
401 450
402 void PrefService::ClearPref(const char* path) { 451 void PrefService::ClearPref(const char* path) {
403 DCHECK(CalledOnValidThread()); 452 DCHECK(CalledOnValidThread());
404 453
405 const Preference* pref = FindPreference(path); 454 const Preference* pref = FindPreference(path);
406 if (!pref) { 455 if (!pref) {
407 NOTREACHED() << "Trying to clear an unregistered pref: " << path; 456 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
408 return; 457 return;
409 } 458 }
410 if (pref_value_store_->RemoveUserPrefValue(path)) 459 pref_value_store_->RemoveUserPrefValue(path);
411 pref_notifier_->OnUserPreferenceSet(path);
412 } 460 }
413 461
414 void PrefService::Set(const char* path, const Value& value) { 462 void PrefService::Set(const char* path, const Value& value) {
415 DCHECK(CalledOnValidThread()); 463 DCHECK(CalledOnValidThread());
416 464
417 const Preference* pref = FindPreference(path); 465 const Preference* pref = FindPreference(path);
418 if (!pref) { 466 if (!pref) {
419 NOTREACHED() << "Trying to write an unregistered pref: " << path; 467 NOTREACHED() << "Trying to write an unregistered pref: " << path;
420 return; 468 return;
421 } 469 }
422 470
423 // Allow dictionary and list types to be set to null, which removes their 471 // Allow dictionary and list types to be set to null, which removes their
424 // user values. 472 // user values.
425 bool value_changed = false;
426 if (value.GetType() == Value::TYPE_NULL && 473 if (value.GetType() == Value::TYPE_NULL &&
427 (pref->GetType() == Value::TYPE_DICTIONARY || 474 (pref->GetType() == Value::TYPE_DICTIONARY ||
428 pref->GetType() == Value::TYPE_LIST)) { 475 pref->GetType() == Value::TYPE_LIST)) {
429 value_changed = pref_value_store_->RemoveUserPrefValue(path); 476 pref_value_store_->RemoveUserPrefValue(path);
430 } else if (pref->GetType() != value.GetType()) { 477 } else if (pref->GetType() != value.GetType()) {
431 NOTREACHED() << "Trying to set pref " << path 478 NOTREACHED() << "Trying to set pref " << path
432 << " of type " << pref->GetType() 479 << " of type " << pref->GetType()
433 << " to value of type " << value.GetType(); 480 << " to value of type " << value.GetType();
434 } else { 481 } else {
435 value_changed = pref_value_store_->SetUserPrefValue(path, value.DeepCopy()); 482 pref_value_store_->SetUserPrefValue(path, value.DeepCopy());
436 } 483 }
437
438 if (value_changed)
439 pref_notifier_->OnUserPreferenceSet(path);
440 } 484 }
441 485
442 void PrefService::SetBoolean(const char* path, bool value) { 486 void PrefService::SetBoolean(const char* path, bool value) {
443 SetUserPrefValue(path, Value::CreateBooleanValue(value)); 487 SetUserPrefValue(path, Value::CreateBooleanValue(value));
444 } 488 }
445 489
446 void PrefService::SetInteger(const char* path, int value) { 490 void PrefService::SetInteger(const char* path, int value) {
447 SetUserPrefValue(path, Value::CreateIntegerValue(value)); 491 SetUserPrefValue(path, Value::CreateIntegerValue(value));
448 } 492 }
449 493
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 return NULL; 551 return NULL;
508 } 552 }
509 553
510 DictionaryValue* dict = NULL; 554 DictionaryValue* dict = NULL;
511 Value* tmp_value = NULL; 555 Value* tmp_value = NULL;
512 // Look for an existing preference in the user store. If it doesn't 556 // 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. 557 // exist or isn't the correct type, create a new user preference.
514 if (!pref_value_store_->GetUserValue(path, &tmp_value) || 558 if (!pref_value_store_->GetUserValue(path, &tmp_value) ||
515 !tmp_value->IsType(Value::TYPE_DICTIONARY)) { 559 !tmp_value->IsType(Value::TYPE_DICTIONARY)) {
516 dict = new DictionaryValue; 560 dict = new DictionaryValue;
517 pref_value_store_->SetUserPrefValue(path, dict); 561 pref_value_store_->SetUserPrefValueSilently(path, dict);
518 } else { 562 } else {
519 dict = static_cast<DictionaryValue*>(tmp_value); 563 dict = static_cast<DictionaryValue*>(tmp_value);
520 } 564 }
521 return dict; 565 return dict;
522 } 566 }
523 567
524 ListValue* PrefService::GetMutableList(const char* path) { 568 ListValue* PrefService::GetMutableList(const char* path) {
525 DCHECK(CalledOnValidThread()); 569 DCHECK(CalledOnValidThread());
526 570
527 const Preference* pref = FindPreference(path); 571 const Preference* pref = FindPreference(path);
528 if (!pref) { 572 if (!pref) {
529 NOTREACHED() << "Trying to get an unregistered pref: " << path; 573 NOTREACHED() << "Trying to get an unregistered pref: " << path;
530 return NULL; 574 return NULL;
531 } 575 }
532 if (pref->GetType() != Value::TYPE_LIST) { 576 if (pref->GetType() != Value::TYPE_LIST) {
533 NOTREACHED() << "Wrong type for GetMutableList: " << path; 577 NOTREACHED() << "Wrong type for GetMutableList: " << path;
534 return NULL; 578 return NULL;
535 } 579 }
536 580
537 ListValue* list = NULL; 581 ListValue* list = NULL;
538 Value* tmp_value = NULL; 582 Value* tmp_value = NULL;
539 // Look for an existing preference in the user store. If it doesn't 583 // 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. 584 // exist or isn't the correct type, create a new user preference.
541 if (!pref_value_store_->GetUserValue(path, &tmp_value) || 585 if (!pref_value_store_->GetUserValue(path, &tmp_value) ||
542 !tmp_value->IsType(Value::TYPE_LIST)) { 586 !tmp_value->IsType(Value::TYPE_LIST)) {
543 list = new ListValue; 587 list = new ListValue;
544 pref_value_store_->SetUserPrefValue(path, list); 588 pref_value_store_->SetUserPrefValueSilently(path, list);
545 } else { 589 } else {
546 list = static_cast<ListValue*>(tmp_value); 590 list = static_cast<ListValue*>(tmp_value);
547 } 591 }
548 return list; 592 return list;
549 } 593 }
550 594
551 Value* PrefService::GetPrefCopy(const char* path) { 595 Value* PrefService::GetPrefCopy(const char* path) {
552 DCHECK(CalledOnValidThread()); 596 DCHECK(CalledOnValidThread());
553 597
554 const Preference* pref = FindPreference(path); 598 const Preference* pref = FindPreference(path);
(...skipping 13 matching lines...) Expand all
568 NOTREACHED() << "Preference is managed: " << path; 612 NOTREACHED() << "Preference is managed: " << path;
569 return; 613 return;
570 } 614 }
571 if (pref->GetType() != new_value->GetType()) { 615 if (pref->GetType() != new_value->GetType()) {
572 NOTREACHED() << "Trying to set pref " << path 616 NOTREACHED() << "Trying to set pref " << path
573 << " of type " << pref->GetType() 617 << " of type " << pref->GetType()
574 << " to value of type " << new_value->GetType(); 618 << " to value of type " << new_value->GetType();
575 return; 619 return;
576 } 620 }
577 621
578 if (pref_value_store_->SetUserPrefValue(path, new_value)) 622 pref_value_store_->SetUserPrefValue(path, new_value);
579 pref_notifier_->OnUserPreferenceSet(path);
580 }
581
582 PrefStore* PrefService::GetExtensionPrefStore() const {
583 return pref_value_store()->GetExtensionPrefStore();
584 } 623 }
585 624
586 /////////////////////////////////////////////////////////////////////////////// 625 ///////////////////////////////////////////////////////////////////////////////
587 // PrefService::Preference 626 // PrefService::Preference
588 627
589 PrefService::Preference::Preference(const PrefService* service, 628 PrefService::Preference::Preference(const PrefService* service,
590 const char* name) 629 const char* name)
591 : name_(name), 630 : name_(name),
592 pref_service_(service) { 631 pref_service_(service) {
593 DCHECK(name); 632 DCHECK(name);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 679
641 bool PrefService::Preference::IsDefaultValue() const { 680 bool PrefService::Preference::IsDefaultValue() const {
642 return pref_service_->pref_value_store_-> 681 return pref_service_->pref_value_store_->
643 PrefValueFromDefaultStore(name_.c_str()); 682 PrefValueFromDefaultStore(name_.c_str());
644 } 683 }
645 684
646 bool PrefService::Preference::IsUserModifiable() const { 685 bool PrefService::Preference::IsUserModifiable() const {
647 return pref_service_->pref_value_store_-> 686 return pref_service_->pref_value_store_->
648 PrefValueUserModifiable(name_.c_str()); 687 PrefValueUserModifiable(name_.c_str());
649 } 688 }
OLDNEW
« no previous file with comments | « chrome/browser/prefs/pref_service.h ('k') | chrome/browser/prefs/pref_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698