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