Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_value_store.h" | 5 #include "chrome/browser/prefs/pref_value_store.h" |
| 6 | 6 |
| 7 #include "chrome/browser/browser_thread.h" | 7 #include "chrome/browser/browser_thread.h" |
| 8 #include "chrome/browser/extensions/extension_pref_store.h" | 8 #include "chrome/browser/prefs/pref_notifier.h" |
|
danno
2010/12/06 09:20:14
alphabetize
Mattias Nissler (ping if slow)
2010/12/06 10:58:12
Done.
| |
| 9 #include "chrome/browser/policy/configuration_policy_pref_store.h" | 9 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
| 10 #include "chrome/browser/prefs/command_line_pref_store.h" | |
| 11 #include "chrome/browser/prefs/default_pref_store.h" | |
| 12 #include "chrome/common/json_pref_store.h" | |
| 13 #include "chrome/common/notification_service.h" | 10 #include "chrome/common/notification_service.h" |
| 14 | 11 |
| 15 namespace { | 12 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() |
| 16 | 13 : pref_value_store_(NULL), |
| 17 // Returns true if the actual value is a valid type for the expected type when | 14 type_(PrefValueStore::INVALID_STORE) { |
| 18 // found in the given store. | |
| 19 bool IsValidType(Value::ValueType expected, Value::ValueType actual, | |
| 20 PrefNotifier::PrefStoreType store) { | |
| 21 if (expected == actual) | |
| 22 return true; | |
| 23 | |
| 24 // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only | |
| 25 // in the default pref store. | |
| 26 if (store == PrefNotifier::DEFAULT_STORE && | |
| 27 actual == Value::TYPE_NULL && | |
| 28 (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) { | |
| 29 return true; | |
| 30 } | |
| 31 return false; | |
| 32 } | 15 } |
| 33 | 16 |
| 34 } // namespace | 17 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { |
| 18 if (pref_store_.get()) | |
| 19 pref_store_->RemoveObserver(this); | |
| 20 } | |
| 35 | 21 |
| 36 // static | 22 void PrefValueStore::PrefStoreKeeper::Initialize( |
| 37 PrefValueStore* PrefValueStore::CreatePrefValueStore( | 23 PrefValueStore* store, |
| 38 const FilePath& pref_filename, | 24 PrefStore* pref_store, |
| 39 Profile* profile, | 25 PrefValueStore::PrefStoreType type) { |
| 40 bool user_only) { | 26 if (pref_store_.get()) |
| 41 using policy::ConfigurationPolicyPrefStore; | 27 pref_store_->RemoveObserver(this); |
| 42 ConfigurationPolicyPrefStore* managed = NULL; | 28 type_ = type; |
| 43 ConfigurationPolicyPrefStore* device_management = NULL; | 29 pref_value_store_ = store; |
| 44 ExtensionPrefStore* extension = NULL; | 30 pref_store_.reset(pref_store); |
| 45 CommandLinePrefStore* command_line = NULL; | 31 if (pref_store_.get()) |
| 46 ConfigurationPolicyPrefStore* recommended = NULL; | 32 pref_store_->AddObserver(this); |
| 33 } | |
| 47 | 34 |
| 48 JsonPrefStore* user = new JsonPrefStore( | 35 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( |
| 49 pref_filename, | 36 const std::string& key) { |
| 50 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); | 37 pref_value_store_->OnPrefValueChanged(type_, key); |
| 51 DefaultPrefStore* default_store = new DefaultPrefStore(); | 38 } |
| 52 | 39 |
| 53 if (!user_only) { | 40 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() { |
| 54 managed = | 41 pref_value_store_->OnInitializationCompleted(type_); |
| 55 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore(); | 42 } |
| 56 device_management = | 43 |
| 57 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | 44 PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, |
| 58 profile); | 45 PrefStore* device_management_prefs, |
| 59 extension = new ExtensionPrefStore(profile, PrefNotifier::EXTENSION_STORE); | 46 PrefStore* extension_prefs, |
| 60 command_line = new CommandLinePrefStore(CommandLine::ForCurrentProcess()); | 47 PrefStore* command_line_prefs, |
| 61 recommended = | 48 PrefStore* user_prefs, |
| 62 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(); | 49 PrefStore* recommended_prefs, |
| 63 } | 50 PrefStore* default_prefs, |
| 64 return new PrefValueStore(managed, device_management, extension, | 51 PrefNotifier* pref_notifier, |
| 65 command_line, user, recommended, default_store, | 52 Profile* profile) |
| 66 profile); | 53 : pref_notifier_(pref_notifier), |
| 54 profile_(profile) { | |
| 55 // NULL default pref store is usually bad, but may be OK for some unit tests. | |
| 56 if (!default_prefs) | |
| 57 LOG(WARNING) << "default pref store is null"; | |
| 58 InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs); | |
| 59 InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs); | |
| 60 InitPrefStore(EXTENSION_STORE, extension_prefs); | |
| 61 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | |
| 62 InitPrefStore(USER_STORE, user_prefs); | |
| 63 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); | |
| 64 InitPrefStore(DEFAULT_STORE, default_prefs); | |
| 65 | |
| 66 // TODO(mnissler): Remove after policy refresh cleanup. | |
| 67 registrar_.Add(this, | |
| 68 NotificationType(NotificationType::POLICY_CHANGED), | |
| 69 NotificationService::AllSources()); | |
| 70 | |
| 71 CheckInitializationCompleted(); | |
| 67 } | 72 } |
| 68 | 73 |
| 69 PrefValueStore::~PrefValueStore() {} | 74 PrefValueStore::~PrefValueStore() {} |
| 70 | 75 |
| 71 bool PrefValueStore::GetValue(const std::string& name, | 76 bool PrefValueStore::GetValue(const std::string& name, |
| 72 Value** out_value) const { | 77 Value** out_value) const { |
| 73 // Check the |PrefStore|s in order of their priority from highest to lowest | 78 // Check the |PrefStore|s in order of their priority from highest to lowest |
| 74 // to find the value of the preference described by the given preference name. | 79 // to find the value of the preference described by the given preference name. |
| 75 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 80 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 76 if (GetValueFromStore(name.c_str(), | 81 if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i), |
| 77 static_cast<PrefNotifier::PrefStoreType>(i), | |
| 78 out_value)) | 82 out_value)) |
| 79 return true; | 83 return true; |
| 80 } | 84 } |
| 81 return false; | 85 return false; |
| 82 } | 86 } |
| 83 | 87 |
| 84 bool PrefValueStore::GetUserValue(const std::string& name, | 88 bool PrefValueStore::GetUserValue(const std::string& name, |
| 85 Value** out_value) const { | 89 Value** out_value) const { |
| 86 return GetValueFromStore(name.c_str(), PrefNotifier::USER_STORE, out_value); | 90 return GetValueFromStore(name.c_str(), USER_STORE, out_value); |
| 87 } | 91 } |
| 88 | 92 |
| 89 void PrefValueStore::RegisterPreferenceType(const std::string& name, | 93 void PrefValueStore::RegisterPreferenceType(const std::string& name, |
| 90 Value::ValueType type) { | 94 Value::ValueType type) { |
| 91 pref_types_[name] = type; | 95 pref_types_[name] = type; |
| 92 } | 96 } |
| 93 | 97 |
| 94 Value::ValueType PrefValueStore::GetRegisteredType( | 98 Value::ValueType PrefValueStore::GetRegisteredType( |
| 95 const std::string& name) const { | 99 const std::string& name) const { |
| 96 PrefTypeMap::const_iterator found = pref_types_.find(name); | 100 PrefTypeMap::const_iterator found = pref_types_.find(name); |
| 97 if (found == pref_types_.end()) | 101 if (found == pref_types_.end()) |
| 98 return Value::TYPE_NULL; | 102 return Value::TYPE_NULL; |
| 99 return found->second; | 103 return found->second; |
| 100 } | 104 } |
| 101 | 105 |
| 102 bool PrefValueStore::WritePrefs() { | 106 bool PrefValueStore::WritePrefs() { |
| 103 bool success = true; | 107 bool success = true; |
| 104 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 108 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 105 if (pref_stores_[i].get()) | 109 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
| 106 success = pref_stores_[i]->WritePrefs() && success; | 110 if (store) |
| 111 success = store->WritePrefs() && success; | |
| 107 } | 112 } |
| 108 return success; | 113 return success; |
| 109 } | 114 } |
| 110 | 115 |
| 111 void PrefValueStore::ScheduleWritePrefs() { | 116 void PrefValueStore::ScheduleWritePrefs() { |
| 112 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 117 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 113 if (pref_stores_[i].get()) | 118 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
| 114 pref_stores_[i]->ScheduleWritePrefs(); | 119 if (store) |
| 120 store->ScheduleWritePrefs(); | |
| 115 } | 121 } |
| 116 } | 122 } |
| 117 | 123 |
| 118 PrefStore::PrefReadError PrefValueStore::ReadPrefs() { | 124 PrefStore::PrefReadError PrefValueStore::ReadPrefs() { |
| 119 PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE; | 125 PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE; |
| 120 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 126 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 121 if (pref_stores_[i].get()) { | 127 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
| 122 PrefStore::PrefReadError this_error = pref_stores_[i]->ReadPrefs(); | 128 if (store) { |
| 129 PrefStore::PrefReadError this_error = store->ReadPrefs(); | |
| 123 if (result == PrefStore::PREF_READ_ERROR_NONE) | 130 if (result == PrefStore::PREF_READ_ERROR_NONE) |
| 124 result = this_error; | 131 result = this_error; |
| 125 } | 132 } |
| 126 } | 133 } |
| 127 | 134 |
| 128 if (HasPolicyConflictingUserProxySettings()) { | 135 if (HasPolicyConflictingUserProxySettings()) { |
| 129 LOG(WARNING) << "user-requested proxy options have been overridden" | 136 LOG(WARNING) << "user-requested proxy options have been overridden" |
| 130 << " by a proxy configuration specified in a centrally" | 137 << " by a proxy configuration specified in a centrally" |
| 131 << " administered policy."; | 138 << " administered policy."; |
| 132 } | 139 } |
| 133 | 140 |
| 134 // TODO(markusheintz): Return a better error status: maybe a struct with | 141 // TODO(markusheintz): Return a better error status: maybe a struct with |
| 135 // the error status of all PrefStores. | 142 // the error status of all PrefStores. |
| 136 return result; | 143 return result; |
| 137 } | 144 } |
| 138 | 145 |
| 139 bool PrefValueStore::HasPrefPath(const char* path) const { | 146 bool PrefValueStore::HasPrefPath(const char* path) const { |
| 140 Value* tmp_value = NULL; | 147 Value* tmp_value = NULL; |
| 141 const std::string name(path); | 148 const std::string name(path); |
| 142 bool rv = GetValue(name, &tmp_value); | 149 bool rv = GetValue(name, &tmp_value); |
| 143 // Merely registering a pref doesn't count as "having" it: we require a | 150 // Merely registering a pref doesn't count as "having" it: we require a |
| 144 // non-default value set. | 151 // non-default value set. |
| 145 return rv && !PrefValueFromDefaultStore(path); | 152 return rv && !PrefValueFromDefaultStore(path); |
| 146 } | 153 } |
| 147 | 154 |
| 148 bool PrefValueStore::PrefHasChanged(const char* path, | 155 void PrefValueStore::NotifyPrefChanged( |
| 149 PrefNotifier::PrefStoreType new_store) { | 156 const char* path, |
| 150 DCHECK(new_store != PrefNotifier::INVALID_STORE); | 157 PrefValueStore::PrefStoreType new_store) { |
| 151 // Replying that the pref has changed may cause problems, but it's the safer | 158 DCHECK(new_store != INVALID_STORE); |
| 152 // choice. | |
| 153 if (new_store == PrefNotifier::INVALID_STORE) | |
| 154 return true; | |
| 155 | 159 |
| 156 PrefNotifier::PrefStoreType controller = ControllingPrefStoreForPref(path); | 160 // If this pref is not registered, just discard the notification. |
| 157 DCHECK(controller != PrefNotifier::INVALID_STORE); | 161 if (!pref_types_.count(path)) |
| 158 if (controller == PrefNotifier::INVALID_STORE) | 162 return; |
| 159 return true; | |
| 160 | 163 |
| 161 // If the pref is controlled by a higher-priority store, its effective value | 164 bool changed = true; |
| 162 // cannot have changed. | 165 // Replying that the pref has changed in case the new store is invalid may |
| 163 if (controller < new_store) | 166 // cause problems, but it's the safer choice. |
| 164 return false; | 167 if (new_store != INVALID_STORE) { |
| 168 PrefStoreType controller = ControllingPrefStoreForPref(path); | |
| 169 DCHECK(controller != INVALID_STORE); | |
| 170 // If the pref is controlled by a higher-priority store, its effective value | |
| 171 // cannot have changed. | |
| 172 if (controller != INVALID_STORE && | |
| 173 controller < new_store) { | |
| 174 changed = false; | |
| 175 } | |
| 176 } | |
| 165 | 177 |
| 166 // Otherwise, we take the pref store's word that something changed. | 178 if (changed) |
| 167 return true; | 179 pref_notifier_->OnPreferenceChanged(path); |
| 168 } | 180 } |
| 169 | 181 |
| 170 // Note the |DictionaryValue| referenced by the |PrefStore| USER_STORE | 182 void PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { |
| 171 // (returned by the method prefs()) takes the ownership of the Value referenced | 183 DCHECK(in_value); |
| 172 // by in_value. | |
| 173 bool PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { | |
| 174 Value* old_value = NULL; | 184 Value* old_value = NULL; |
| 175 pref_stores_[PrefNotifier::USER_STORE]->prefs()->Get(name, &old_value); | 185 GetPrefStore(USER_STORE)->prefs()->Get(name, &old_value); |
| 176 bool value_changed = !(old_value && old_value->Equals(in_value)); | 186 bool value_changed = !old_value || !old_value->Equals(in_value); |
| 187 GetPrefStore(USER_STORE)->prefs()->Set(name, in_value); | |
| 177 | 188 |
| 178 pref_stores_[PrefNotifier::USER_STORE]->prefs()->Set(name, in_value); | 189 if (value_changed) |
| 179 return value_changed; | 190 NotifyPrefChanged(name, USER_STORE); |
| 180 } | 191 } |
| 181 | 192 |
| 182 // Note the |DictionaryValue| referenced by the |PrefStore| DEFAULT_STORE | 193 void PrefValueStore::SetUserPrefValueSilently(const char* name, |
| 183 // (returned by the method prefs()) takes the ownership of the Value referenced | 194 Value* in_value) { |
| 184 // by in_value. | 195 DCHECK(in_value); |
| 185 void PrefValueStore::SetDefaultPrefValue(const char* name, Value* in_value) { | 196 GetPrefStore(USER_STORE)->prefs()->Set(name, in_value); |
| 186 pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Set(name, in_value); | |
| 187 } | 197 } |
| 188 | 198 |
| 189 bool PrefValueStore::ReadOnly() { | 199 bool PrefValueStore::ReadOnly() const { |
| 190 return pref_stores_[PrefNotifier::USER_STORE]->ReadOnly(); | 200 return GetPrefStore(USER_STORE)->ReadOnly(); |
| 191 } | 201 } |
| 192 | 202 |
| 193 bool PrefValueStore::RemoveUserPrefValue(const char* name) { | 203 void PrefValueStore::RemoveUserPrefValue(const char* name) { |
| 194 if (pref_stores_[PrefNotifier::USER_STORE].get()) { | 204 if (GetPrefStore(USER_STORE)) { |
| 195 return pref_stores_[PrefNotifier::USER_STORE]->prefs()->Remove(name, NULL); | 205 if (GetPrefStore(USER_STORE)->prefs()->Remove(name, NULL)) |
| 206 NotifyPrefChanged(name, USER_STORE); | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const { | |
| 211 return PrefValueInStore(name, MANAGED_PLATFORM_STORE); | |
| 212 } | |
| 213 | |
| 214 bool PrefValueStore::PrefValueInDeviceManagementStore(const char* name) const { | |
| 215 return PrefValueInStore(name, DEVICE_MANAGEMENT_STORE); | |
| 216 } | |
| 217 | |
| 218 bool PrefValueStore::PrefValueInExtensionStore(const char* name) const { | |
| 219 return PrefValueInStore(name, EXTENSION_STORE); | |
| 220 } | |
| 221 | |
| 222 bool PrefValueStore::PrefValueInUserStore(const char* name) const { | |
| 223 return PrefValueInStore(name, USER_STORE); | |
| 224 } | |
| 225 | |
| 226 bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const { | |
| 227 return ControllingPrefStoreForPref(name) == EXTENSION_STORE; | |
| 228 } | |
| 229 | |
| 230 bool PrefValueStore::PrefValueFromUserStore(const char* name) const { | |
| 231 return ControllingPrefStoreForPref(name) == USER_STORE; | |
| 232 } | |
| 233 | |
| 234 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | |
| 235 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; | |
| 236 } | |
| 237 | |
| 238 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | |
| 239 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | |
| 240 return effective_store >= USER_STORE || | |
| 241 effective_store == INVALID_STORE; | |
| 242 } | |
| 243 | |
| 244 bool PrefValueStore::HasPolicyConflictingUserProxySettings() const { | |
| 245 using policy::ConfigurationPolicyPrefStore; | |
| 246 ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs; | |
| 247 ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs); | |
| 248 ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i; | |
| 249 for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) { | |
| 250 if ((PrefValueInManagedPlatformStore(*i) || | |
| 251 PrefValueInDeviceManagementStore(*i)) && | |
| 252 PrefValueInStoreRange(*i, | |
| 253 COMMAND_LINE_STORE, | |
| 254 USER_STORE)) | |
| 255 return true; | |
| 196 } | 256 } |
| 197 return false; | 257 return false; |
| 198 } | 258 } |
| 199 | 259 |
| 200 bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const { | 260 // Returns true if the actual value is a valid type for the expected type when |
| 201 return PrefValueInStore(name, PrefNotifier::MANAGED_PLATFORM_STORE); | 261 // found in the given store. |
| 262 bool PrefValueStore::IsValidType(Value::ValueType expected, | |
| 263 Value::ValueType actual, | |
| 264 PrefValueStore::PrefStoreType store) { | |
| 265 if (expected == actual) | |
| 266 return true; | |
| 267 | |
| 268 // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only | |
| 269 // in the default pref store. | |
| 270 if (store == DEFAULT_STORE && | |
| 271 actual == Value::TYPE_NULL && | |
| 272 (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) { | |
| 273 return true; | |
| 274 } | |
| 275 return false; | |
| 202 } | 276 } |
| 203 | 277 |
| 204 bool PrefValueStore::PrefValueInDeviceManagementStore(const char* name) const { | 278 bool PrefValueStore::PrefValueInStore( |
| 205 return PrefValueInStore(name, PrefNotifier::DEVICE_MANAGEMENT_STORE); | 279 const char* name, |
| 206 } | 280 PrefValueStore::PrefStoreType store) const { |
| 207 | 281 // Declare a temp Value* and call GetValueFromStore, |
| 208 bool PrefValueStore::PrefValueInExtensionStore(const char* name) const { | 282 // ignoring the output value. |
| 209 return PrefValueInStore(name, PrefNotifier::EXTENSION_STORE); | 283 Value* tmp_value = NULL; |
| 210 } | 284 return GetValueFromStore(name, store, &tmp_value); |
| 211 | |
| 212 bool PrefValueStore::PrefValueInUserStore(const char* name) const { | |
| 213 return PrefValueInStore(name, PrefNotifier::USER_STORE); | |
| 214 } | 285 } |
| 215 | 286 |
| 216 bool PrefValueStore::PrefValueInStoreRange( | 287 bool PrefValueStore::PrefValueInStoreRange( |
| 217 const char* name, | 288 const char* name, |
| 218 PrefNotifier::PrefStoreType first_checked_store, | 289 PrefValueStore::PrefStoreType first_checked_store, |
| 219 PrefNotifier::PrefStoreType last_checked_store) { | 290 PrefValueStore::PrefStoreType last_checked_store) const { |
| 220 if (first_checked_store > last_checked_store) { | 291 if (first_checked_store > last_checked_store) { |
| 221 NOTREACHED(); | 292 NOTREACHED(); |
| 222 return false; | 293 return false; |
| 223 } | 294 } |
| 224 | 295 |
| 225 for (size_t i = first_checked_store; | 296 for (size_t i = first_checked_store; |
| 226 i <= static_cast<size_t>(last_checked_store); ++i) { | 297 i <= static_cast<size_t>(last_checked_store); ++i) { |
| 227 if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) | 298 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) |
| 228 return true; | 299 return true; |
| 229 } | 300 } |
| 230 return false; | 301 return false; |
| 231 } | 302 } |
| 232 | 303 |
| 233 bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const { | 304 PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( |
| 234 return ControllingPrefStoreForPref(name) == PrefNotifier::EXTENSION_STORE; | 305 const char* name) const { |
| 306 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
| 307 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) | |
| 308 return static_cast<PrefStoreType>(i); | |
| 309 } | |
| 310 return INVALID_STORE; | |
| 235 } | 311 } |
| 236 | 312 |
| 237 bool PrefValueStore::PrefValueFromUserStore(const char* name) const { | 313 bool PrefValueStore::GetValueFromStore(const char* name, |
| 238 return ControllingPrefStoreForPref(name) == PrefNotifier::USER_STORE; | 314 PrefValueStore::PrefStoreType store_type, |
| 239 } | 315 Value** out_value) const { |
| 240 | |
| 241 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | |
| 242 return ControllingPrefStoreForPref(name) == PrefNotifier::DEFAULT_STORE; | |
| 243 } | |
| 244 | |
| 245 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | |
| 246 PrefNotifier::PrefStoreType effective_store = | |
| 247 ControllingPrefStoreForPref(name); | |
| 248 return effective_store >= PrefNotifier::USER_STORE || | |
| 249 effective_store == PrefNotifier::INVALID_STORE; | |
| 250 } | |
| 251 | |
| 252 PrefNotifier::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( | |
| 253 const char* name) const { | |
| 254 for (int i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | |
| 255 if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) | |
| 256 return static_cast<PrefNotifier::PrefStoreType>(i); | |
| 257 } | |
| 258 return PrefNotifier::INVALID_STORE; | |
| 259 } | |
| 260 | |
| 261 bool PrefValueStore::PrefValueInStore( | |
| 262 const char* name, | |
| 263 PrefNotifier::PrefStoreType store) const { | |
| 264 // Declare a temp Value* and call GetValueFromStore, | |
| 265 // ignoring the output value. | |
| 266 Value* tmp_value = NULL; | |
| 267 return GetValueFromStore(name, store, &tmp_value); | |
| 268 } | |
| 269 | |
| 270 bool PrefValueStore::GetValueFromStore( | |
| 271 const char* name, | |
| 272 PrefNotifier::PrefStoreType store, | |
| 273 Value** out_value) const { | |
| 274 // Only return true if we find a value and it is the correct type, so stale | 316 // Only return true if we find a value and it is the correct type, so stale |
| 275 // values with the incorrect type will be ignored. | 317 // values with the incorrect type will be ignored. |
| 276 if (pref_stores_[store].get() && | 318 const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type)); |
| 277 pref_stores_[store]->prefs()->Get(name, out_value)) { | 319 if (store && store->prefs()->Get(name, out_value)) { |
| 278 // If the value is the sentinel that redirects to the default | 320 // If the value is the sentinel that redirects to the default store, |
| 279 // store, re-fetch the value from the default store explicitly. | 321 // re-fetch the value from the default store explicitly. Because the default |
| 280 // Because the default values are not available when creating | 322 // values are not available when creating stores, the default value must be |
| 281 // stores, the default value must be fetched dynamically for every | 323 // fetched dynamically for every redirect. |
| 282 // redirect. | |
| 283 if (PrefStore::IsUseDefaultSentinelValue(*out_value)) { | 324 if (PrefStore::IsUseDefaultSentinelValue(*out_value)) { |
| 284 DCHECK(pref_stores_[PrefNotifier::DEFAULT_STORE].get()); | 325 store = GetPrefStore(DEFAULT_STORE); |
| 285 if (!pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Get(name, | 326 if (!store || !store->prefs()->Get(name, out_value)) { |
| 286 out_value)) { | |
| 287 *out_value = NULL; | 327 *out_value = NULL; |
| 288 return false; | 328 return false; |
| 289 } | 329 } |
| 290 store = PrefNotifier::DEFAULT_STORE; | 330 store_type = DEFAULT_STORE; |
| 291 } | 331 } |
| 292 if (IsValidType(GetRegisteredType(name), (*out_value)->GetType(), store)) | 332 if (IsValidType(GetRegisteredType(name), |
| 333 (*out_value)->GetType(), | |
| 334 store_type)) { | |
| 293 return true; | 335 return true; |
| 336 } | |
| 294 } | 337 } |
| 295 // No valid value found for the given preference name: set the return false. | 338 // No valid value found for the given preference name: set the return false. |
| 296 *out_value = NULL; | 339 *out_value = NULL; |
| 297 return false; | 340 return false; |
| 298 } | 341 } |
| 299 | 342 |
| 300 void PrefValueStore::RefreshPolicyPrefsOnFileThread( | 343 void PrefValueStore::RefreshPolicyPrefsOnFileThread( |
| 301 BrowserThread::ID calling_thread_id, | 344 BrowserThread::ID calling_thread_id, |
| 302 PrefStore* new_managed_platform_pref_store, | 345 PrefStore* new_managed_platform_pref_store, |
| 303 PrefStore* new_device_management_pref_store, | 346 PrefStore* new_device_management_pref_store, |
| 304 PrefStore* new_recommended_pref_store, | 347 PrefStore* new_recommended_pref_store) { |
| 305 AfterRefreshCallback* callback_pointer) { | |
| 306 scoped_ptr<AfterRefreshCallback> callback(callback_pointer); | |
| 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 308 scoped_ptr<PrefStore> managed_platform_pref_store( | 349 scoped_ptr<PrefStore> managed_platform_pref_store( |
| 309 new_managed_platform_pref_store); | 350 new_managed_platform_pref_store); |
| 310 scoped_ptr<PrefStore> device_management_pref_store( | 351 scoped_ptr<PrefStore> device_management_pref_store( |
| 311 new_device_management_pref_store); | 352 new_device_management_pref_store); |
| 312 scoped_ptr<PrefStore> recommended_pref_store(new_recommended_pref_store); | 353 scoped_ptr<PrefStore> recommended_pref_store(new_recommended_pref_store); |
| 313 | 354 |
| 314 PrefStore::PrefReadError read_error = | 355 PrefStore::PrefReadError read_error = |
| 315 new_managed_platform_pref_store->ReadPrefs(); | 356 new_managed_platform_pref_store->ReadPrefs(); |
| 316 if (read_error != PrefStore::PREF_READ_ERROR_NONE) { | 357 if (read_error != PrefStore::PREF_READ_ERROR_NONE) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 332 << read_error; | 373 << read_error; |
| 333 return; | 374 return; |
| 334 } | 375 } |
| 335 | 376 |
| 336 BrowserThread::PostTask( | 377 BrowserThread::PostTask( |
| 337 calling_thread_id, FROM_HERE, | 378 calling_thread_id, FROM_HERE, |
| 338 NewRunnableMethod(this, | 379 NewRunnableMethod(this, |
| 339 &PrefValueStore::RefreshPolicyPrefsCompletion, | 380 &PrefValueStore::RefreshPolicyPrefsCompletion, |
| 340 managed_platform_pref_store.release(), | 381 managed_platform_pref_store.release(), |
| 341 device_management_pref_store.release(), | 382 device_management_pref_store.release(), |
| 342 recommended_pref_store.release(), | 383 recommended_pref_store.release())); |
| 343 callback.release())); | 384 } |
| 385 | |
| 386 void PrefValueStore::RefreshPolicyPrefs() { | |
| 387 using policy::ConfigurationPolicyPrefStore; | |
| 388 // Because loading of policy information must happen on the FILE | |
| 389 // thread, it's not possible to just replace the contents of the | |
| 390 // managed and recommended stores in place due to possible | |
| 391 // concurrent access from the UI thread. Instead, new stores are | |
| 392 // created and the refreshed policy read into them. The new stores | |
| 393 // are swapped with the old from a Task on the UI thread after the | |
| 394 // load is complete. | |
| 395 PrefStore* new_managed_platform_pref_store( | |
| 396 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); | |
| 397 PrefStore* new_device_management_pref_store( | |
| 398 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | |
| 399 profile_)); | |
| 400 PrefStore* new_recommended_pref_store( | |
| 401 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); | |
| 402 BrowserThread::ID current_thread_id; | |
| 403 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); | |
| 404 BrowserThread::PostTask( | |
| 405 BrowserThread::FILE, FROM_HERE, | |
| 406 NewRunnableMethod(this, | |
| 407 &PrefValueStore::RefreshPolicyPrefsOnFileThread, | |
| 408 current_thread_id, | |
| 409 new_managed_platform_pref_store, | |
| 410 new_device_management_pref_store, | |
| 411 new_recommended_pref_store)); | |
| 344 } | 412 } |
| 345 | 413 |
| 346 void PrefValueStore::RefreshPolicyPrefsCompletion( | 414 void PrefValueStore::RefreshPolicyPrefsCompletion( |
| 347 PrefStore* new_managed_platform_pref_store, | 415 PrefStore* new_managed_platform_pref_store, |
| 348 PrefStore* new_device_management_pref_store, | 416 PrefStore* new_device_management_pref_store, |
| 349 PrefStore* new_recommended_pref_store, | 417 PrefStore* new_recommended_pref_store) { |
| 350 AfterRefreshCallback* callback_pointer) { | |
| 351 scoped_ptr<AfterRefreshCallback> callback(callback_pointer); | |
| 352 | |
| 353 // Determine the paths of all the changed preferences values in the three | 418 // Determine the paths of all the changed preferences values in the three |
| 354 // policy-related stores (managed platform, device management and | 419 // policy-related stores (managed platform, device management and |
| 355 // recommended). | 420 // recommended). |
| 356 DictionaryValue* managed_platform_prefs_before( | 421 DictionaryValue* managed_platform_prefs_before( |
| 357 pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE]->prefs()); | 422 GetPrefStore(MANAGED_PLATFORM_STORE)->prefs()); |
| 358 DictionaryValue* managed_platform_prefs_after( | 423 DictionaryValue* managed_platform_prefs_after( |
| 359 new_managed_platform_pref_store->prefs()); | 424 new_managed_platform_pref_store->prefs()); |
| 360 DictionaryValue* device_management_prefs_before( | 425 DictionaryValue* device_management_prefs_before( |
| 361 pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE]->prefs()); | 426 GetPrefStore(DEVICE_MANAGEMENT_STORE)->prefs()); |
| 362 DictionaryValue* device_management_prefs_after( | 427 DictionaryValue* device_management_prefs_after( |
| 363 new_device_management_pref_store->prefs()); | 428 new_device_management_pref_store->prefs()); |
| 364 DictionaryValue* recommended_prefs_before( | 429 DictionaryValue* recommended_prefs_before( |
| 365 pref_stores_[PrefNotifier::RECOMMENDED_STORE]->prefs()); | 430 GetPrefStore(RECOMMENDED_STORE)->prefs()); |
| 366 DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); | 431 DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); |
| 367 | 432 |
| 368 std::vector<std::string> changed_managed_platform_paths; | 433 std::vector<std::string> changed_managed_platform_paths; |
| 369 managed_platform_prefs_before->GetDifferingPaths(managed_platform_prefs_after, | 434 managed_platform_prefs_before->GetDifferingPaths(managed_platform_prefs_after, |
| 370 &changed_managed_platform_paths); | 435 &changed_managed_platform_paths); |
| 371 | 436 |
| 372 std::vector<std::string> changed_device_management_paths; | 437 std::vector<std::string> changed_device_management_paths; |
| 373 device_management_prefs_before->GetDifferingPaths( | 438 device_management_prefs_before->GetDifferingPaths( |
| 374 device_management_prefs_after, | 439 device_management_prefs_after, |
| 375 &changed_device_management_paths); | 440 &changed_device_management_paths); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 401 changed_recommended_paths.begin(), | 466 changed_recommended_paths.begin(), |
| 402 changed_recommended_paths.end(), | 467 changed_recommended_paths.end(), |
| 403 changed_paths.begin()); | 468 changed_paths.begin()); |
| 404 changed_paths.resize(last_insert - changed_paths.begin()); | 469 changed_paths.resize(last_insert - changed_paths.begin()); |
| 405 | 470 |
| 406 last_insert = unique(changed_paths.begin(), changed_paths.end()); | 471 last_insert = unique(changed_paths.begin(), changed_paths.end()); |
| 407 changed_paths.resize(last_insert - changed_paths.begin()); | 472 changed_paths.resize(last_insert - changed_paths.begin()); |
| 408 | 473 |
| 409 // Replace the old stores with the new and send notification of the changed | 474 // Replace the old stores with the new and send notification of the changed |
| 410 // preferences. | 475 // preferences. |
| 411 pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset( | 476 InitPrefStore(MANAGED_PLATFORM_STORE, new_managed_platform_pref_store); |
| 412 new_managed_platform_pref_store); | 477 InitPrefStore(DEVICE_MANAGEMENT_STORE, new_device_management_pref_store); |
| 413 pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset( | 478 InitPrefStore(RECOMMENDED_STORE, new_recommended_pref_store); |
| 414 new_device_management_pref_store); | 479 |
| 415 pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset( | 480 std::vector<std::string>::const_iterator current; |
| 416 new_recommended_pref_store); | 481 for (current = changed_paths.begin(); |
| 417 callback->Run(changed_paths); | 482 current != changed_paths.end(); |
| 483 ++current) { | |
| 484 pref_notifier_->OnPreferenceChanged(current->c_str()); | |
| 485 } | |
| 418 } | 486 } |
| 419 | 487 |
| 420 void PrefValueStore::RefreshPolicyPrefs( | 488 void PrefValueStore::Observe(NotificationType type, |
| 421 AfterRefreshCallback* callback) { | 489 const NotificationSource& source, |
| 422 using policy::ConfigurationPolicyPrefStore; | 490 const NotificationDetails& details) { |
| 423 // Because loading of policy information must happen on the FILE | 491 if (type == NotificationType::POLICY_CHANGED) |
| 424 // thread, it's not possible to just replace the contents of the | 492 RefreshPolicyPrefs(); |
| 425 // managed and recommended stores in place due to possible | |
| 426 // concurrent access from the UI thread. Instead, new stores are | |
| 427 // created and the refreshed policy read into them. The new stores | |
| 428 // are swapped with the old from a Task on the UI thread after the | |
| 429 // load is complete. | |
| 430 PrefStore* new_managed_platform_pref_store( | |
| 431 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); | |
| 432 PrefStore* new_device_management_pref_store( | |
| 433 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | |
| 434 profile_)); | |
| 435 PrefStore* new_recommended_pref_store( | |
| 436 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); | |
| 437 BrowserThread::ID current_thread_id; | |
| 438 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); | |
| 439 BrowserThread::PostTask( | |
| 440 BrowserThread::FILE, FROM_HERE, | |
| 441 NewRunnableMethod(this, | |
| 442 &PrefValueStore::RefreshPolicyPrefsOnFileThread, | |
| 443 current_thread_id, | |
| 444 new_managed_platform_pref_store, | |
| 445 new_device_management_pref_store, | |
| 446 new_recommended_pref_store, | |
| 447 callback)); | |
| 448 } | 493 } |
| 449 | 494 |
| 450 bool PrefValueStore::HasPolicyConflictingUserProxySettings() { | 495 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, |
| 451 using policy::ConfigurationPolicyPrefStore; | 496 const std::string& key) { |
| 452 ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs; | 497 NotifyPrefChanged(key.c_str(), type); |
| 453 ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs); | |
| 454 ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i; | |
| 455 for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) { | |
| 456 if ((PrefValueInManagedPlatformStore(*i) || | |
| 457 PrefValueInDeviceManagementStore(*i)) && | |
| 458 PrefValueInStoreRange(*i, | |
| 459 PrefNotifier::COMMAND_LINE_STORE, | |
| 460 PrefNotifier::USER_STORE)) | |
| 461 return true; | |
| 462 } | |
| 463 return false; | |
| 464 } | 498 } |
| 465 | 499 |
| 466 PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, | 500 void PrefValueStore::OnInitializationCompleted( |
| 467 PrefStore* device_management_prefs, | 501 PrefValueStore::PrefStoreType type) { |
| 468 PrefStore* extension_prefs, | 502 CheckInitializationCompleted(); |
| 469 PrefStore* command_line_prefs, | |
| 470 PrefStore* user_prefs, | |
| 471 PrefStore* recommended_prefs, | |
| 472 PrefStore* default_prefs, | |
| 473 Profile* profile) | |
| 474 : profile_(profile) { | |
| 475 // NULL default pref store is usually bad, but may be OK for some unit tests. | |
| 476 if (!default_prefs) | |
| 477 LOG(WARNING) << "default pref store is null"; | |
| 478 pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset( | |
| 479 managed_platform_prefs); | |
| 480 pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset( | |
| 481 device_management_prefs); | |
| 482 pref_stores_[PrefNotifier::EXTENSION_STORE].reset(extension_prefs); | |
| 483 pref_stores_[PrefNotifier::COMMAND_LINE_STORE].reset(command_line_prefs); | |
| 484 pref_stores_[PrefNotifier::USER_STORE].reset(user_prefs); | |
| 485 pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(recommended_prefs); | |
| 486 pref_stores_[PrefNotifier::DEFAULT_STORE].reset(default_prefs); | |
| 487 } | 503 } |
| 504 | |
| 505 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | |
| 506 PrefStore* pref_store) { | |
| 507 pref_stores_[type].Initialize(this, pref_store, type); | |
| 508 } | |
| 509 | |
| 510 void PrefValueStore::CheckInitializationCompleted() { | |
| 511 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
| 512 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); | |
| 513 if (store && !store->IsInitializationComplete()) | |
| 514 return; | |
| 515 } | |
| 516 pref_notifier_->OnInitializationCompleted(); | |
| 517 } | |
| OLD | NEW |