| 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" | |
| 8 #include "chrome/browser/policy/configuration_policy_pref_store.h" | |
| 9 #include "chrome/browser/prefs/pref_notifier.h" | 7 #include "chrome/browser/prefs/pref_notifier.h" |
| 10 #include "chrome/common/notification_service.h" | |
| 11 | 8 |
| 12 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() | 9 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() |
| 13 : pref_value_store_(NULL), | 10 : pref_value_store_(NULL), |
| 14 type_(PrefValueStore::INVALID_STORE) { | 11 type_(PrefValueStore::INVALID_STORE) { |
| 15 } | 12 } |
| 16 | 13 |
| 17 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { | 14 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { |
| 18 if (pref_store_.get()) | 15 if (pref_store_.get()) |
| 19 pref_store_->RemoveObserver(this); | 16 pref_store_->RemoveObserver(this); |
| 20 } | 17 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 41 pref_value_store_->OnInitializationCompleted(type_); | 38 pref_value_store_->OnInitializationCompleted(type_); |
| 42 } | 39 } |
| 43 | 40 |
| 44 PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, | 41 PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, |
| 45 PrefStore* device_management_prefs, | 42 PrefStore* device_management_prefs, |
| 46 PrefStore* extension_prefs, | 43 PrefStore* extension_prefs, |
| 47 PrefStore* command_line_prefs, | 44 PrefStore* command_line_prefs, |
| 48 PrefStore* user_prefs, | 45 PrefStore* user_prefs, |
| 49 PrefStore* recommended_prefs, | 46 PrefStore* recommended_prefs, |
| 50 PrefStore* default_prefs, | 47 PrefStore* default_prefs, |
| 51 PrefNotifier* pref_notifier, | 48 PrefNotifier* pref_notifier) |
| 52 Profile* profile) | 49 : pref_notifier_(pref_notifier) { |
| 53 : pref_notifier_(pref_notifier), | |
| 54 profile_(profile) { | |
| 55 InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs); | 50 InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs); |
| 56 InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs); | 51 InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs); |
| 57 InitPrefStore(EXTENSION_STORE, extension_prefs); | 52 InitPrefStore(EXTENSION_STORE, extension_prefs); |
| 58 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | 53 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); |
| 59 InitPrefStore(USER_STORE, user_prefs); | 54 InitPrefStore(USER_STORE, user_prefs); |
| 60 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); | 55 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); |
| 61 InitPrefStore(DEFAULT_STORE, default_prefs); | 56 InitPrefStore(DEFAULT_STORE, default_prefs); |
| 62 | 57 |
| 63 // TODO(mnissler): Remove after policy refresh cleanup. | |
| 64 registrar_.Add(this, | |
| 65 NotificationType(NotificationType::POLICY_CHANGED), | |
| 66 NotificationService::AllSources()); | |
| 67 | |
| 68 CheckInitializationCompleted(); | 58 CheckInitializationCompleted(); |
| 69 } | 59 } |
| 70 | 60 |
| 71 PrefValueStore::~PrefValueStore() {} | 61 PrefValueStore::~PrefValueStore() {} |
| 72 | 62 |
| 73 bool PrefValueStore::GetValue(const std::string& name, | 63 bool PrefValueStore::GetValue(const std::string& name, |
| 74 Value** out_value) const { | 64 Value** out_value) const { |
| 75 // Check the |PrefStore|s in order of their priority from highest to lowest | 65 // Check the |PrefStore|s in order of their priority from highest to lowest |
| 76 // to find the value of the preference described by the given preference name. | 66 // to find the value of the preference described by the given preference name. |
| 77 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | 67 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 case PrefStore::READ_NO_VALUE: | 233 case PrefStore::READ_NO_VALUE: |
| 244 break; | 234 break; |
| 245 } | 235 } |
| 246 } | 236 } |
| 247 | 237 |
| 248 // No valid value found for the given preference name: set the return false. | 238 // No valid value found for the given preference name: set the return false. |
| 249 *out_value = NULL; | 239 *out_value = NULL; |
| 250 return false; | 240 return false; |
| 251 } | 241 } |
| 252 | 242 |
| 253 void PrefValueStore::RefreshPolicyPrefsOnFileThread( | |
| 254 BrowserThread::ID calling_thread_id, | |
| 255 policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, | |
| 256 policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, | |
| 257 policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { | |
| 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 259 scoped_ptr<policy::ConfigurationPolicyPrefStore> managed_platform_pref_store( | |
| 260 new_managed_platform_pref_store); | |
| 261 scoped_ptr<policy::ConfigurationPolicyPrefStore> device_management_pref_store( | |
| 262 new_device_management_pref_store); | |
| 263 scoped_ptr<policy::ConfigurationPolicyPrefStore> recommended_pref_store( | |
| 264 new_recommended_pref_store); | |
| 265 | |
| 266 BrowserThread::PostTask( | |
| 267 calling_thread_id, FROM_HERE, | |
| 268 NewRunnableMethod(this, | |
| 269 &PrefValueStore::RefreshPolicyPrefsCompletion, | |
| 270 managed_platform_pref_store.release(), | |
| 271 device_management_pref_store.release(), | |
| 272 recommended_pref_store.release())); | |
| 273 } | |
| 274 | |
| 275 void PrefValueStore::RefreshPolicyPrefs() { | |
| 276 using policy::ConfigurationPolicyPrefStore; | |
| 277 // Because loading of policy information must happen on the FILE | |
| 278 // thread, it's not possible to just replace the contents of the | |
| 279 // managed and recommended stores in place due to possible | |
| 280 // concurrent access from the UI thread. Instead, new stores are | |
| 281 // created and the refreshed policy read into them. The new stores | |
| 282 // are swapped with the old from a Task on the UI thread after the | |
| 283 // load is complete. | |
| 284 ConfigurationPolicyPrefStore* new_managed_platform_pref_store( | |
| 285 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); | |
| 286 ConfigurationPolicyPrefStore* new_device_management_pref_store( | |
| 287 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | |
| 288 profile_)); | |
| 289 ConfigurationPolicyPrefStore* new_recommended_pref_store( | |
| 290 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); | |
| 291 BrowserThread::ID current_thread_id; | |
| 292 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); | |
| 293 BrowserThread::PostTask( | |
| 294 BrowserThread::FILE, FROM_HERE, | |
| 295 NewRunnableMethod(this, | |
| 296 &PrefValueStore::RefreshPolicyPrefsOnFileThread, | |
| 297 current_thread_id, | |
| 298 new_managed_platform_pref_store, | |
| 299 new_device_management_pref_store, | |
| 300 new_recommended_pref_store)); | |
| 301 } | |
| 302 | |
| 303 void PrefValueStore::RefreshPolicyPrefsCompletion( | |
| 304 policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, | |
| 305 policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, | |
| 306 policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { | |
| 307 // Determine the paths of all the changed preferences values in the three | |
| 308 // policy-related stores (managed platform, device management and | |
| 309 // recommended). | |
| 310 DictionaryValue* managed_platform_prefs_before( | |
| 311 static_cast<policy::ConfigurationPolicyPrefStore*>( | |
| 312 GetPrefStore(MANAGED_PLATFORM_STORE))->prefs()); | |
| 313 DictionaryValue* managed_platform_prefs_after( | |
| 314 new_managed_platform_pref_store->prefs()); | |
| 315 DictionaryValue* device_management_prefs_before( | |
| 316 static_cast<policy::ConfigurationPolicyPrefStore*>( | |
| 317 GetPrefStore(DEVICE_MANAGEMENT_STORE))->prefs()); | |
| 318 DictionaryValue* device_management_prefs_after( | |
| 319 new_device_management_pref_store->prefs()); | |
| 320 DictionaryValue* recommended_prefs_before( | |
| 321 static_cast<policy::ConfigurationPolicyPrefStore*>( | |
| 322 GetPrefStore(RECOMMENDED_STORE))->prefs()); | |
| 323 DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); | |
| 324 | |
| 325 std::vector<std::string> changed_managed_platform_paths; | |
| 326 managed_platform_prefs_before->GetDifferingPaths( | |
| 327 managed_platform_prefs_after, | |
| 328 &changed_managed_platform_paths); | |
| 329 | |
| 330 std::vector<std::string> changed_device_management_paths; | |
| 331 device_management_prefs_before->GetDifferingPaths( | |
| 332 device_management_prefs_after, | |
| 333 &changed_device_management_paths); | |
| 334 | |
| 335 std::vector<std::string> changed_recommended_paths; | |
| 336 recommended_prefs_before->GetDifferingPaths( | |
| 337 recommended_prefs_after, | |
| 338 &changed_recommended_paths); | |
| 339 | |
| 340 // Merge all three vectors of changed value paths together, filtering | |
| 341 // duplicates in a post-processing step. | |
| 342 std::vector<std::string> all_changed_managed_platform_paths( | |
| 343 changed_managed_platform_paths.size() + | |
| 344 changed_device_management_paths.size()); | |
| 345 | |
| 346 std::vector<std::string>::iterator last_insert = | |
| 347 std::merge(changed_managed_platform_paths.begin(), | |
| 348 changed_managed_platform_paths.end(), | |
| 349 changed_device_management_paths.begin(), | |
| 350 changed_device_management_paths.end(), | |
| 351 all_changed_managed_platform_paths.begin()); | |
| 352 all_changed_managed_platform_paths.resize( | |
| 353 last_insert - all_changed_managed_platform_paths.begin()); | |
| 354 | |
| 355 std::vector<std::string> changed_paths( | |
| 356 all_changed_managed_platform_paths.size() + | |
| 357 changed_recommended_paths.size()); | |
| 358 last_insert = std::merge(all_changed_managed_platform_paths.begin(), | |
| 359 all_changed_managed_platform_paths.end(), | |
| 360 changed_recommended_paths.begin(), | |
| 361 changed_recommended_paths.end(), | |
| 362 changed_paths.begin()); | |
| 363 changed_paths.resize(last_insert - changed_paths.begin()); | |
| 364 | |
| 365 last_insert = unique(changed_paths.begin(), changed_paths.end()); | |
| 366 changed_paths.resize(last_insert - changed_paths.begin()); | |
| 367 | |
| 368 // Replace the old stores with the new and send notification of the changed | |
| 369 // preferences. | |
| 370 InitPrefStore(MANAGED_PLATFORM_STORE, new_managed_platform_pref_store); | |
| 371 InitPrefStore(DEVICE_MANAGEMENT_STORE, new_device_management_pref_store); | |
| 372 InitPrefStore(RECOMMENDED_STORE, new_recommended_pref_store); | |
| 373 | |
| 374 std::vector<std::string>::const_iterator current; | |
| 375 for (current = changed_paths.begin(); | |
| 376 current != changed_paths.end(); | |
| 377 ++current) { | |
| 378 pref_notifier_->OnPreferenceChanged(current->c_str()); | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 void PrefValueStore::Observe(NotificationType type, | |
| 383 const NotificationSource& source, | |
| 384 const NotificationDetails& details) { | |
| 385 if (type == NotificationType::POLICY_CHANGED) | |
| 386 RefreshPolicyPrefs(); | |
| 387 } | |
| 388 | |
| 389 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, | 243 void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, |
| 390 const std::string& key) { | 244 const std::string& key) { |
| 391 NotifyPrefChanged(key.c_str(), type); | 245 NotifyPrefChanged(key.c_str(), type); |
| 392 } | 246 } |
| 393 | 247 |
| 394 void PrefValueStore::OnInitializationCompleted( | 248 void PrefValueStore::OnInitializationCompleted( |
| 395 PrefValueStore::PrefStoreType type) { | 249 PrefValueStore::PrefStoreType type) { |
| 396 CheckInitializationCompleted(); | 250 CheckInitializationCompleted(); |
| 397 } | 251 } |
| 398 | 252 |
| 399 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | 253 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, |
| 400 PrefStore* pref_store) { | 254 PrefStore* pref_store) { |
| 401 pref_stores_[type].Initialize(this, pref_store, type); | 255 pref_stores_[type].Initialize(this, pref_store, type); |
| 402 } | 256 } |
| 403 | 257 |
| 404 void PrefValueStore::CheckInitializationCompleted() { | 258 void PrefValueStore::CheckInitializationCompleted() { |
| 405 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | 259 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
| 406 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); | 260 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
| 407 if (store && !store->IsInitializationComplete()) | 261 if (store && !store->IsInitializationComplete()) |
| 408 return; | 262 return; |
| 409 } | 263 } |
| 410 pref_notifier_->OnInitializationCompleted(); | 264 pref_notifier_->OnInitializationCompleted(); |
| 411 } | 265 } |
| OLD | NEW |