Chromium Code Reviews| Index: chrome/browser/prefs/pref_value_store.cc |
| =================================================================== |
| --- chrome/browser/prefs/pref_value_store.cc (revision 59196) |
| +++ chrome/browser/prefs/pref_value_store.cc (working copy) |
| @@ -9,6 +9,7 @@ |
| #include "chrome/browser/extensions/extension_pref_store.h" |
| #include "chrome/browser/policy/configuration_policy_pref_store.h" |
| #include "chrome/browser/prefs/command_line_pref_store.h" |
| +#include "chrome/browser/prefs/default_pref_store.h" |
| #include "chrome/common/json_pref_store.h" |
| #include "chrome/common/notification_service.h" |
| @@ -21,12 +22,12 @@ |
| ConfigurationPolicyPrefStore* managed = NULL; |
| ExtensionPrefStore* extension = NULL; |
| CommandLinePrefStore* command_line = NULL; |
| - JsonPrefStore* user = NULL; |
| ConfigurationPolicyPrefStore* recommended = NULL; |
| - user = new JsonPrefStore( |
| + JsonPrefStore* user = new JsonPrefStore( |
| pref_filename, |
| ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)); |
| + DefaultPrefStore* default_store = new DefaultPrefStore(); |
| if (!user_only) { |
| managed = ConfigurationPolicyPrefStore::CreateManagedPolicyPrefStore(); |
| @@ -36,7 +37,7 @@ |
| ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(); |
| } |
| return new PrefValueStore(managed, extension, command_line, user, |
| - recommended); |
| + recommended, default_store); |
| } |
| PrefValueStore::~PrefValueStore() {} |
| @@ -51,7 +52,7 @@ |
| return true; |
| } |
| } |
| - // No value found for the given preference name, set the return false. |
| + // No value found for the given preference name: set the return false. |
| *out_value = NULL; |
| return false; |
| } |
| @@ -90,82 +91,105 @@ |
| Value* tmp_value = NULL; |
| const std::string name(path); |
| bool rv = GetValue(name, &tmp_value); |
| - return rv; |
| + // Merely registering a pref doesn't count as "having" it: we require a |
| + // non-default value set. |
| + return rv && !PrefValueFromDefaultStore(path); |
|
jeanluc1
2010/09/21 04:16:39
This change modifies the behavior of TemplateURLMo
|
| } |
| bool PrefValueStore::PrefHasChanged(const char* path, |
| - PrefNotifier::PrefStoreType new_store, |
| - const Value* old_value) { |
| + PrefNotifier::PrefStoreType new_store) { |
| DCHECK(new_store != PrefNotifier::INVALID_STORE); |
| - // Replying that the pref has changed may cause extra work, but it should |
| - // not be actively harmful. |
| + // Replying that the pref has changed may cause problems, but it's the safer |
| + // choice. |
| if (new_store == PrefNotifier::INVALID_STORE) |
| return true; |
| - Value* new_value = NULL; |
| - GetValue(path, &new_value); |
| - // Some unit tests have no values for certain prefs. |
| - if (!new_value || !old_value->Equals(new_value)) |
| + PrefNotifier::PrefStoreType controller = ControllingPrefStoreForPref(path); |
| + DCHECK(controller != PrefNotifier::INVALID_STORE); |
| + if (controller == PrefNotifier::INVALID_STORE) |
| return true; |
| - // If there's a value in a store with lower priority than the |new_store|, |
| - // and no value in a store with higher priority, assume the |new_store| just |
| - // took control of the pref. (This assumption is wrong if the new value |
| - // and store are both the same as the old one, but that situation should be |
| - // rare, and reporting a change when none happened should not be harmful.) |
| - if (PrefValueInStoreRange(path, new_store, false) && |
| - !PrefValueInStoreRange(path, new_store, true)) |
| - return true; |
| + // If the pref is controlled by a higher-priority store, its effective value |
| + // cannot have changed. |
| + if (controller < new_store) |
| + return false; |
| - return false; |
| + // Otherwise, we take the pref store's word that something changed. |
| + return true; |
| } |
| -// Note the |DictionaryValue| referenced by the |PrefStore| user_prefs_ |
| +// Note the |DictionaryValue| referenced by the |PrefStore| USER_STORE |
| // (returned by the method prefs()) takes the ownership of the Value referenced |
| // by in_value. |
| -void PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { |
| +bool PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { |
| + Value* old_value = NULL; |
| + pref_stores_[PrefNotifier::USER_STORE]->prefs()->Get(name, &old_value); |
| + bool value_changed = !(old_value && old_value->Equals(in_value)); |
| + |
| pref_stores_[PrefNotifier::USER_STORE]->prefs()->Set(name, in_value); |
| + return value_changed; |
| } |
| +// Note the |DictionaryValue| referenced by the |PrefStore| DEFAULT_STORE |
| +// (returned by the method prefs()) takes the ownership of the Value referenced |
| +// by in_value. |
| +void PrefValueStore::SetDefaultPrefValue(const char* name, Value* in_value) { |
| + pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Set(name, in_value); |
| +} |
| + |
| bool PrefValueStore::ReadOnly() { |
| return pref_stores_[PrefNotifier::USER_STORE]->ReadOnly(); |
| } |
| -void PrefValueStore::RemoveUserPrefValue(const char* name) { |
| +bool PrefValueStore::RemoveUserPrefValue(const char* name) { |
| if (pref_stores_[PrefNotifier::USER_STORE].get()) { |
| - pref_stores_[PrefNotifier::USER_STORE]->prefs()->Remove(name, NULL); |
| + return pref_stores_[PrefNotifier::USER_STORE]->prefs()->Remove(name, NULL); |
| } |
| + return false; |
| } |
| -bool PrefValueStore::PrefValueInManagedStore(const char* name) { |
| +bool PrefValueStore::PrefValueInManagedStore(const char* name) const { |
| return PrefValueInStore(name, PrefNotifier::MANAGED_STORE); |
| } |
| -bool PrefValueStore::PrefValueInExtensionStore(const char* name) { |
| +bool PrefValueStore::PrefValueInExtensionStore(const char* name) const { |
| return PrefValueInStore(name, PrefNotifier::EXTENSION_STORE); |
| } |
| -bool PrefValueStore::PrefValueInUserStore(const char* name) { |
| +bool PrefValueStore::PrefValueInUserStore(const char* name) const { |
| return PrefValueInStore(name, PrefNotifier::USER_STORE); |
| } |
| -bool PrefValueStore::PrefValueFromExtensionStore(const char* name) { |
| +bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const { |
| return ControllingPrefStoreForPref(name) == PrefNotifier::EXTENSION_STORE; |
| } |
| -bool PrefValueStore::PrefValueFromUserStore(const char* name) { |
| +bool PrefValueStore::PrefValueFromUserStore(const char* name) const { |
| return ControllingPrefStoreForPref(name) == PrefNotifier::USER_STORE; |
| } |
| -bool PrefValueStore::PrefValueUserModifiable(const char* name) { |
| +bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { |
| + return ControllingPrefStoreForPref(name) == PrefNotifier::DEFAULT_STORE; |
| +} |
| + |
| +bool PrefValueStore::PrefValueUserModifiable(const char* name) const { |
| PrefNotifier::PrefStoreType effective_store = |
| ControllingPrefStoreForPref(name); |
| return effective_store >= PrefNotifier::USER_STORE || |
| effective_store == PrefNotifier::INVALID_STORE; |
| } |
| +PrefNotifier::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( |
| + const char* name) const { |
| + for (int i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { |
| + if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) |
| + return static_cast<PrefNotifier::PrefStoreType>(i); |
| + } |
| + return PrefNotifier::INVALID_STORE; |
| +} |
| + |
| bool PrefValueStore::PrefValueInStore(const char* name, |
| - PrefNotifier::PrefStoreType type) { |
| + PrefNotifier::PrefStoreType type) const { |
| if (!pref_stores_[type].get()) { |
| // No store of that type set, so this pref can't be in it. |
| return false; |
| @@ -174,32 +198,6 @@ |
| return pref_stores_[type]->prefs()->Get(name, &tmp_value); |
| } |
| -bool PrefValueStore::PrefValueInStoreRange(const char* name, |
| - PrefNotifier::PrefStoreType boundary, |
| - bool higher_priority) { |
| - // Higher priorities are lower PrefStoreType values. The range is |
| - // non-inclusive of the boundary. |
| - int start = higher_priority ? 0 : boundary + 1; |
| - int end = higher_priority ? boundary - 1 : |
| - PrefNotifier::PREF_STORE_TYPE_MAX; |
| - |
| - for (int i = start; i <= end ; ++i) { |
| - if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) |
| - return true; |
| - } |
| - return false; |
| -} |
| - |
| - |
| -PrefNotifier::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( |
| - const char* name) { |
| - for (int i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { |
| - if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) |
| - return static_cast<PrefNotifier::PrefStoreType>(i); |
| - } |
| - return PrefNotifier::INVALID_STORE; |
| -} |
| - |
| void PrefValueStore::RefreshPolicyPrefsCompletion( |
| PrefStore* new_managed_pref_store, |
| PrefStore* new_recommended_pref_store, |
| @@ -289,10 +287,15 @@ |
| PrefStore* extension_prefs, |
| PrefStore* command_line_prefs, |
| PrefStore* user_prefs, |
| - PrefStore* recommended_prefs) { |
| + PrefStore* recommended_prefs, |
| + PrefStore* default_prefs) { |
| + // NULL default pref store is usually bad, but may be OK for some unit tests. |
| + if (!default_prefs) |
| + LOG(WARNING) << "default pref store is null"; |
| pref_stores_[PrefNotifier::MANAGED_STORE].reset(managed_prefs); |
| pref_stores_[PrefNotifier::EXTENSION_STORE].reset(extension_prefs); |
| pref_stores_[PrefNotifier::COMMAND_LINE_STORE].reset(command_line_prefs); |
| pref_stores_[PrefNotifier::USER_STORE].reset(user_prefs); |
| pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(recommended_prefs); |
| + pref_stores_[PrefNotifier::DEFAULT_STORE].reset(default_prefs); |
| } |