| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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_value_store.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/prefs/pref_notifier.h" | |
| 9 #include "base/prefs/pref_observer.h" | |
| 10 | |
| 11 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() | |
| 12 : pref_value_store_(NULL), | |
| 13 type_(PrefValueStore::INVALID_STORE) { | |
| 14 } | |
| 15 | |
| 16 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { | |
| 17 if (pref_store_.get()) { | |
| 18 pref_store_->RemoveObserver(this); | |
| 19 pref_store_ = NULL; | |
| 20 } | |
| 21 pref_value_store_ = NULL; | |
| 22 } | |
| 23 | |
| 24 void PrefValueStore::PrefStoreKeeper::Initialize( | |
| 25 PrefValueStore* store, | |
| 26 PrefStore* pref_store, | |
| 27 PrefValueStore::PrefStoreType type) { | |
| 28 if (pref_store_.get()) { | |
| 29 pref_store_->RemoveObserver(this); | |
| 30 DCHECK_EQ(0U, pref_store_->NumberOfObservers()); | |
| 31 } | |
| 32 type_ = type; | |
| 33 pref_value_store_ = store; | |
| 34 pref_store_ = pref_store; | |
| 35 if (pref_store_.get()) | |
| 36 pref_store_->AddObserver(this); | |
| 37 } | |
| 38 | |
| 39 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( | |
| 40 const std::string& key) { | |
| 41 pref_value_store_->OnPrefValueChanged(type_, key); | |
| 42 } | |
| 43 | |
| 44 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted( | |
| 45 bool succeeded) { | |
| 46 pref_value_store_->OnInitializationCompleted(type_, succeeded); | |
| 47 } | |
| 48 | |
| 49 PrefValueStore::PrefValueStore(PrefStore* managed_prefs, | |
| 50 PrefStore* extension_prefs, | |
| 51 PrefStore* command_line_prefs, | |
| 52 PrefStore* user_prefs, | |
| 53 PrefStore* recommended_prefs, | |
| 54 PrefStore* default_prefs, | |
| 55 PrefNotifier* pref_notifier) | |
| 56 : pref_notifier_(pref_notifier), | |
| 57 initialization_failed_(false) { | |
| 58 InitPrefStore(MANAGED_STORE, managed_prefs); | |
| 59 InitPrefStore(EXTENSION_STORE, extension_prefs); | |
| 60 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | |
| 61 InitPrefStore(USER_STORE, user_prefs); | |
| 62 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); | |
| 63 InitPrefStore(DEFAULT_STORE, default_prefs); | |
| 64 | |
| 65 CheckInitializationCompleted(); | |
| 66 } | |
| 67 | |
| 68 PrefValueStore::~PrefValueStore() {} | |
| 69 | |
| 70 PrefValueStore* PrefValueStore::CloneAndSpecialize( | |
| 71 PrefStore* managed_prefs, | |
| 72 PrefStore* extension_prefs, | |
| 73 PrefStore* command_line_prefs, | |
| 74 PrefStore* user_prefs, | |
| 75 PrefStore* recommended_prefs, | |
| 76 PrefStore* default_prefs, | |
| 77 PrefNotifier* pref_notifier) { | |
| 78 DCHECK(pref_notifier); | |
| 79 if (!managed_prefs) | |
| 80 managed_prefs = GetPrefStore(MANAGED_STORE); | |
| 81 if (!extension_prefs) | |
| 82 extension_prefs = GetPrefStore(EXTENSION_STORE); | |
| 83 if (!command_line_prefs) | |
| 84 command_line_prefs = GetPrefStore(COMMAND_LINE_STORE); | |
| 85 if (!user_prefs) | |
| 86 user_prefs = GetPrefStore(USER_STORE); | |
| 87 if (!recommended_prefs) | |
| 88 recommended_prefs = GetPrefStore(RECOMMENDED_STORE); | |
| 89 if (!default_prefs) | |
| 90 default_prefs = GetPrefStore(DEFAULT_STORE); | |
| 91 | |
| 92 return new PrefValueStore( | |
| 93 managed_prefs, extension_prefs, command_line_prefs, user_prefs, | |
| 94 recommended_prefs, default_prefs, pref_notifier); | |
| 95 } | |
| 96 | |
| 97 void PrefValueStore::set_callback(const PrefChangedCallback& callback) { | |
| 98 pref_changed_callback_ = callback; | |
| 99 } | |
| 100 | |
| 101 bool PrefValueStore::GetValue(const std::string& name, | |
| 102 base::Value::Type type, | |
| 103 const Value** out_value) const { | |
| 104 // Check the |PrefStore|s in order of their priority from highest to lowest, | |
| 105 // looking for the first preference value with the given |name| and |type|. | |
| 106 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
| 107 if (GetValueFromStoreWithType(name.c_str(), type, | |
| 108 static_cast<PrefStoreType>(i), out_value)) | |
| 109 return true; | |
| 110 } | |
| 111 return false; | |
| 112 } | |
| 113 | |
| 114 bool PrefValueStore::GetRecommendedValue(const std::string& name, | |
| 115 base::Value::Type type, | |
| 116 const Value** out_value) const { | |
| 117 return GetValueFromStoreWithType(name.c_str(), type, RECOMMENDED_STORE, | |
| 118 out_value); | |
| 119 } | |
| 120 | |
| 121 void PrefValueStore::NotifyPrefChanged( | |
| 122 const char* path, | |
| 123 PrefValueStore::PrefStoreType new_store) { | |
| 124 DCHECK(new_store != INVALID_STORE); | |
| 125 // A notification is sent when the pref value in any store changes. If this | |
| 126 // store is currently being overridden by a higher-priority store, the | |
| 127 // effective value of the pref will not have changed. | |
| 128 pref_notifier_->OnPreferenceChanged(path); | |
| 129 if (!pref_changed_callback_.is_null()) | |
| 130 pref_changed_callback_.Run(path); | |
| 131 } | |
| 132 | |
| 133 bool PrefValueStore::PrefValueInManagedStore(const char* name) const { | |
| 134 return PrefValueInStore(name, MANAGED_STORE); | |
| 135 } | |
| 136 | |
| 137 bool PrefValueStore::PrefValueInExtensionStore(const char* name) const { | |
| 138 return PrefValueInStore(name, EXTENSION_STORE); | |
| 139 } | |
| 140 | |
| 141 bool PrefValueStore::PrefValueInUserStore(const char* name) const { | |
| 142 return PrefValueInStore(name, USER_STORE); | |
| 143 } | |
| 144 | |
| 145 bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const { | |
| 146 return ControllingPrefStoreForPref(name) == EXTENSION_STORE; | |
| 147 } | |
| 148 | |
| 149 bool PrefValueStore::PrefValueFromUserStore(const char* name) const { | |
| 150 return ControllingPrefStoreForPref(name) == USER_STORE; | |
| 151 } | |
| 152 | |
| 153 bool PrefValueStore::PrefValueFromRecommendedStore(const char* name) const { | |
| 154 return ControllingPrefStoreForPref(name) == RECOMMENDED_STORE; | |
| 155 } | |
| 156 | |
| 157 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | |
| 158 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; | |
| 159 } | |
| 160 | |
| 161 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | |
| 162 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | |
| 163 return effective_store >= USER_STORE || | |
| 164 effective_store == INVALID_STORE; | |
| 165 } | |
| 166 | |
| 167 bool PrefValueStore::PrefValueExtensionModifiable(const char* name) const { | |
| 168 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | |
| 169 return effective_store >= EXTENSION_STORE || | |
| 170 effective_store == INVALID_STORE; | |
| 171 } | |
| 172 | |
| 173 void PrefValueStore::UpdateCommandLinePrefStore(PrefStore* command_line_prefs) { | |
| 174 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | |
| 175 } | |
| 176 | |
| 177 bool PrefValueStore::PrefValueInStore( | |
| 178 const char* name, | |
| 179 PrefValueStore::PrefStoreType store) const { | |
| 180 // Declare a temp Value* and call GetValueFromStore, | |
| 181 // ignoring the output value. | |
| 182 const Value* tmp_value = NULL; | |
| 183 return GetValueFromStore(name, store, &tmp_value); | |
| 184 } | |
| 185 | |
| 186 bool PrefValueStore::PrefValueInStoreRange( | |
| 187 const char* name, | |
| 188 PrefValueStore::PrefStoreType first_checked_store, | |
| 189 PrefValueStore::PrefStoreType last_checked_store) const { | |
| 190 if (first_checked_store > last_checked_store) { | |
| 191 NOTREACHED(); | |
| 192 return false; | |
| 193 } | |
| 194 | |
| 195 for (size_t i = first_checked_store; | |
| 196 i <= static_cast<size_t>(last_checked_store); ++i) { | |
| 197 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) | |
| 198 return true; | |
| 199 } | |
| 200 return false; | |
| 201 } | |
| 202 | |
| 203 PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( | |
| 204 const char* name) const { | |
| 205 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
| 206 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) | |
| 207 return static_cast<PrefStoreType>(i); | |
| 208 } | |
| 209 return INVALID_STORE; | |
| 210 } | |
| 211 | |
| 212 bool PrefValueStore::GetValueFromStore(const char* name, | |
| 213 PrefValueStore::PrefStoreType store_type, | |
| 214 const Value** out_value) const { | |
| 215 // Only return true if we find a value and it is the correct type, so stale | |
| 216 // values with the incorrect type will be ignored. | |
| 217 const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type)); | |
| 218 if (store && store->GetValue(name, out_value)) | |
| 219 return true; | |
| 220 | |
| 221 // No valid value found for the given preference name: set the return value | |
| 222 // to false. | |
| 223 *out_value = NULL; | |
| 224 return false; | |
| 225 } | |
| 226 | |
| 227 bool PrefValueStore::GetValueFromStoreWithType(const char* name, | |
| 228 base::Value::Type type, | |
| 229 PrefStoreType store, | |
| 230 const Value** out_value) const { | |
| 231 if (GetValueFromStore(name, store, out_value)) { | |
| 232 if ((*out_value)->IsType(type)) | |
| 233 return true; | |
| 234 | |
| 235 LOG(WARNING) << "Expected type for " << name << " is " << type | |
| 236 << " but got " << (*out_value)->GetType() | |
| 237 << " in store " << store; | |
| 238 } | |
| 239 | |
| 240 *out_value = NULL; | |
| 241 return false; | |
| 242 } | |
| 243 | |
| 244 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, | |
| 245 const std::string& key) { | |
| 246 NotifyPrefChanged(key.c_str(), type); | |
| 247 } | |
| 248 | |
| 249 void PrefValueStore::OnInitializationCompleted( | |
| 250 PrefValueStore::PrefStoreType type, bool succeeded) { | |
| 251 if (initialization_failed_) | |
| 252 return; | |
| 253 if (!succeeded) { | |
| 254 initialization_failed_ = true; | |
| 255 pref_notifier_->OnInitializationCompleted(false); | |
| 256 return; | |
| 257 } | |
| 258 CheckInitializationCompleted(); | |
| 259 } | |
| 260 | |
| 261 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | |
| 262 PrefStore* pref_store) { | |
| 263 pref_stores_[type].Initialize(this, pref_store, type); | |
| 264 } | |
| 265 | |
| 266 void PrefValueStore::CheckInitializationCompleted() { | |
| 267 if (initialization_failed_) | |
| 268 return; | |
| 269 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
| 270 scoped_refptr<PrefStore> store = | |
| 271 GetPrefStore(static_cast<PrefStoreType>(i)); | |
| 272 if (store && !store->IsInitializationComplete()) | |
| 273 return; | |
| 274 } | |
| 275 pref_notifier_->OnInitializationCompleted(true); | |
| 276 } | |
| OLD | NEW |