| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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_value_store.h" | 5 #include "chrome/browser/prefs/pref_value_store.h" |
| 6 | 6 |
| 7 #include "chrome/browser/prefs/pref_notifier.h" | 7 #include "chrome/browser/prefs/pref_notifier.h" |
| 8 | 8 |
| 9 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() | 9 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() |
| 10 : pref_value_store_(NULL), | 10 : pref_value_store_(NULL), |
| 11 type_(PrefValueStore::INVALID_STORE) { | 11 type_(PrefValueStore::INVALID_STORE) { |
| 12 } | 12 } |
| 13 | 13 |
| 14 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { | 14 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { |
| 15 if (pref_store_.get()) | 15 if (pref_store_.get()) |
| 16 pref_store_->RemoveObserver(this); | 16 pref_store_->RemoveObserver(this); |
| 17 } | 17 } |
| 18 | 18 |
| 19 void PrefValueStore::PrefStoreKeeper::Initialize( | 19 void PrefValueStore::PrefStoreKeeper::Initialize( |
| 20 PrefValueStore* store, | 20 PrefValueStore* store, |
| 21 PrefStore* pref_store, | 21 PrefStore* pref_store, |
| 22 PrefValueStore::PrefStoreType type) { | 22 PrefValueStore::PrefStoreType type) { |
| 23 if (pref_store_.get()) | 23 if (pref_store_.get()) |
| 24 pref_store_->RemoveObserver(this); | 24 pref_store_->RemoveObserver(this); |
| 25 type_ = type; | 25 type_ = type; |
| 26 pref_value_store_ = store; | 26 pref_value_store_ = store; |
| 27 pref_store_.reset(pref_store); | 27 pref_store_ = pref_store; |
| 28 if (pref_store_.get()) | 28 if (pref_store_.get()) |
| 29 pref_store_->AddObserver(this); | 29 pref_store_->AddObserver(this); |
| 30 } | 30 } |
| 31 | 31 |
| 32 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( | 32 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( |
| 33 const std::string& key) { | 33 const std::string& key) { |
| 34 pref_value_store_->OnPrefValueChanged(type_, key); | 34 pref_value_store_->OnPrefValueChanged(type_, key); |
| 35 } | 35 } |
| 36 | 36 |
| 37 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() { | 37 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 54 InitPrefStore(USER_STORE, user_prefs); | 54 InitPrefStore(USER_STORE, user_prefs); |
| 55 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); | 55 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); |
| 56 InitPrefStore(DEFAULT_STORE, default_prefs); | 56 InitPrefStore(DEFAULT_STORE, default_prefs); |
| 57 | 57 |
| 58 CheckInitializationCompleted(); | 58 CheckInitializationCompleted(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 PrefValueStore::~PrefValueStore() {} | 61 PrefValueStore::~PrefValueStore() {} |
| 62 | 62 |
| 63 bool PrefValueStore::GetValue(const std::string& name, | 63 bool PrefValueStore::GetValue(const std::string& name, |
| 64 Value::ValueType type, |
| 64 Value** out_value) const { | 65 Value** out_value) const { |
| 66 *out_value = NULL; |
| 65 // Check the |PrefStore|s in order of their priority from highest to lowest | 67 // Check the |PrefStore|s in order of their priority from highest to lowest |
| 66 // to find the value of the preference described by the given preference name. | 68 // to find the value of the preference described by the given preference name. |
| 67 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | 69 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 68 if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i), | 70 if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i), |
| 69 out_value)) | 71 out_value)) { |
| 72 if (!(*out_value)->IsType(type)) { |
| 73 LOG(WARNING) << "Expected type for " << name << " is " << type |
| 74 << " but got " << (*out_value)->GetType() |
| 75 << " in store " << i; |
| 76 continue; |
| 77 } |
| 70 return true; | 78 return true; |
| 79 } |
| 71 } | 80 } |
| 72 return false; | 81 return false; |
| 73 } | 82 } |
| 74 | 83 |
| 75 void PrefValueStore::RegisterPreferenceType(const std::string& name, | |
| 76 Value::ValueType type) { | |
| 77 pref_types_[name] = type; | |
| 78 } | |
| 79 | |
| 80 Value::ValueType PrefValueStore::GetRegisteredType( | |
| 81 const std::string& name) const { | |
| 82 PrefTypeMap::const_iterator found = pref_types_.find(name); | |
| 83 if (found == pref_types_.end()) | |
| 84 return Value::TYPE_NULL; | |
| 85 return found->second; | |
| 86 } | |
| 87 | |
| 88 bool PrefValueStore::HasPrefPath(const char* path) const { | |
| 89 Value* tmp_value = NULL; | |
| 90 const std::string name(path); | |
| 91 bool rv = GetValue(name, &tmp_value); | |
| 92 // Merely registering a pref doesn't count as "having" it: we require a | |
| 93 // non-default value set. | |
| 94 return rv && !PrefValueFromDefaultStore(path); | |
| 95 } | |
| 96 | |
| 97 void PrefValueStore::NotifyPrefChanged( | 84 void PrefValueStore::NotifyPrefChanged( |
| 98 const char* path, | 85 const char* path, |
| 99 PrefValueStore::PrefStoreType new_store) { | 86 PrefValueStore::PrefStoreType new_store) { |
| 100 DCHECK(new_store != INVALID_STORE); | 87 DCHECK(new_store != INVALID_STORE); |
| 101 | 88 |
| 102 // If this pref is not registered, just discard the notification. | |
| 103 if (!pref_types_.count(path)) | |
| 104 return; | |
| 105 | |
| 106 bool changed = true; | 89 bool changed = true; |
| 107 // Replying that the pref has changed in case the new store is invalid may | 90 // Replying that the pref has changed in case the new store is invalid may |
| 108 // cause problems, but it's the safer choice. | 91 // cause problems, but it's the safer choice. |
| 109 if (new_store != INVALID_STORE) { | 92 if (new_store != INVALID_STORE) { |
| 110 PrefStoreType controller = ControllingPrefStoreForPref(path); | 93 PrefStoreType controller = ControllingPrefStoreForPref(path); |
| 111 DCHECK(controller != INVALID_STORE); | 94 DCHECK(controller != INVALID_STORE); |
| 112 // If the pref is controlled by a higher-priority store, its effective value | 95 // If the pref is controlled by a higher-priority store, its effective value |
| 113 // cannot have changed. | 96 // cannot have changed. |
| 114 if (controller != INVALID_STORE && | 97 if (controller != INVALID_STORE && |
| 115 controller < new_store) { | 98 controller < new_store) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | 131 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { |
| 149 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; | 132 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; |
| 150 } | 133 } |
| 151 | 134 |
| 152 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | 135 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { |
| 153 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | 136 PrefStoreType effective_store = ControllingPrefStoreForPref(name); |
| 154 return effective_store >= USER_STORE || | 137 return effective_store >= USER_STORE || |
| 155 effective_store == INVALID_STORE; | 138 effective_store == INVALID_STORE; |
| 156 } | 139 } |
| 157 | 140 |
| 158 // Returns true if the actual value is a valid type for the expected type when | |
| 159 // found in the given store. | |
| 160 bool PrefValueStore::IsValidType(Value::ValueType expected, | |
| 161 Value::ValueType actual, | |
| 162 PrefValueStore::PrefStoreType store) { | |
| 163 if (expected == actual) | |
| 164 return true; | |
| 165 | |
| 166 // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only | |
| 167 // in the default pref store. | |
| 168 if (store == DEFAULT_STORE && | |
| 169 actual == Value::TYPE_NULL && | |
| 170 (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) { | |
| 171 return true; | |
| 172 } | |
| 173 return false; | |
| 174 } | |
| 175 | |
| 176 bool PrefValueStore::PrefValueInStore( | 141 bool PrefValueStore::PrefValueInStore( |
| 177 const char* name, | 142 const char* name, |
| 178 PrefValueStore::PrefStoreType store) const { | 143 PrefValueStore::PrefStoreType store) const { |
| 179 // Declare a temp Value* and call GetValueFromStore, | 144 // Declare a temp Value* and call GetValueFromStore, |
| 180 // ignoring the output value. | 145 // ignoring the output value. |
| 181 Value* tmp_value = NULL; | 146 Value* tmp_value = NULL; |
| 182 return GetValueFromStore(name, store, &tmp_value); | 147 return GetValueFromStore(name, store, &tmp_value); |
| 183 } | 148 } |
| 184 | 149 |
| 185 bool PrefValueStore::PrefValueInStoreRange( | 150 bool PrefValueStore::PrefValueInStoreRange( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 if (store) { | 182 if (store) { |
| 218 switch (store->GetValue(name, out_value)) { | 183 switch (store->GetValue(name, out_value)) { |
| 219 case PrefStore::READ_USE_DEFAULT: | 184 case PrefStore::READ_USE_DEFAULT: |
| 220 store = GetPrefStore(DEFAULT_STORE); | 185 store = GetPrefStore(DEFAULT_STORE); |
| 221 if (!store || store->GetValue(name, out_value) != PrefStore::READ_OK) { | 186 if (!store || store->GetValue(name, out_value) != PrefStore::READ_OK) { |
| 222 *out_value = NULL; | 187 *out_value = NULL; |
| 223 return false; | 188 return false; |
| 224 } | 189 } |
| 225 // Fall through... | 190 // Fall through... |
| 226 case PrefStore::READ_OK: | 191 case PrefStore::READ_OK: |
| 227 if (IsValidType(GetRegisteredType(name), | 192 return true; |
| 228 (*out_value)->GetType(), | |
| 229 store_type)) { | |
| 230 return true; | |
| 231 } | |
| 232 break; | |
| 233 case PrefStore::READ_NO_VALUE: | 193 case PrefStore::READ_NO_VALUE: |
| 234 break; | 194 break; |
| 235 } | 195 } |
| 236 } | 196 } |
| 237 | 197 |
| 238 // No valid value found for the given preference name: set the return false. | 198 // No valid value found for the given preference name: set the return false. |
| 239 *out_value = NULL; | 199 *out_value = NULL; |
| 240 return false; | 200 return false; |
| 241 } | 201 } |
| 242 | 202 |
| 243 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, | 203 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, |
| 244 const std::string& key) { | 204 const std::string& key) { |
| 245 NotifyPrefChanged(key.c_str(), type); | 205 NotifyPrefChanged(key.c_str(), type); |
| 246 } | 206 } |
| 247 | 207 |
| 248 void PrefValueStore::OnInitializationCompleted( | 208 void PrefValueStore::OnInitializationCompleted( |
| 249 PrefValueStore::PrefStoreType type) { | 209 PrefValueStore::PrefStoreType type) { |
| 250 CheckInitializationCompleted(); | 210 CheckInitializationCompleted(); |
| 251 } | 211 } |
| 252 | 212 |
| 253 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | 213 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, |
| 254 PrefStore* pref_store) { | 214 PrefStore* pref_store) { |
| 255 pref_stores_[type].Initialize(this, pref_store, type); | 215 pref_stores_[type].Initialize(this, pref_store, type); |
| 256 } | 216 } |
| 257 | 217 |
| 258 void PrefValueStore::CheckInitializationCompleted() { | 218 void PrefValueStore::CheckInitializationCompleted() { |
| 259 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | 219 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 260 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); | 220 scoped_refptr<PrefStore> store = |
| 221 GetPrefStore(static_cast<PrefStoreType>(i)); |
| 261 if (store && !store->IsInitializationComplete()) | 222 if (store && !store->IsInitializationComplete()) |
| 262 return; | 223 return; |
| 263 } | 224 } |
| 264 pref_notifier_->OnInitializationCompleted(); | 225 pref_notifier_->OnInitializationCompleted(); |
| 265 } | 226 } |
| OLD | NEW |