| Index: chrome/browser/prefs/pref_value_store.cc
|
| diff --git a/chrome/browser/prefs/pref_value_store.cc b/chrome/browser/prefs/pref_value_store.cc
|
| index b327e33dcc9e77e505b297a33c38e262f50db810..3dcc813a666a66a036220bcd61705ca314372668 100644
|
| --- a/chrome/browser/prefs/pref_value_store.cc
|
| +++ b/chrome/browser/prefs/pref_value_store.cc
|
| @@ -6,62 +6,69 @@
|
|
|
| #include "chrome/browser/browser_thread.h"
|
| #include "chrome/browser/policy/configuration_policy_pref_store.h"
|
| -#include "chrome/browser/prefs/command_line_pref_store.h"
|
| -#include "chrome/browser/prefs/in_memory_pref_store.h"
|
| -#include "chrome/common/json_pref_store.h"
|
| +#include "chrome/browser/prefs/pref_notifier.h"
|
| #include "chrome/common/notification_service.h"
|
|
|
| -namespace {
|
| +PrefValueStore::PrefStoreKeeper::PrefStoreKeeper()
|
| + : pref_value_store_(NULL),
|
| + type_(PrefValueStore::INVALID_STORE) {
|
| +}
|
|
|
| -// Returns true if the actual value is a valid type for the expected type when
|
| -// found in the given store.
|
| -bool IsValidType(Value::ValueType expected, Value::ValueType actual,
|
| - PrefNotifier::PrefStoreType store) {
|
| - if (expected == actual)
|
| - return true;
|
| +PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() {
|
| + if (pref_store_.get())
|
| + pref_store_->RemoveObserver(this);
|
| +}
|
|
|
| - // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only
|
| - // in the default pref store.
|
| - if (store == PrefNotifier::DEFAULT_STORE &&
|
| - actual == Value::TYPE_NULL &&
|
| - (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) {
|
| - return true;
|
| - }
|
| - return false;
|
| +void PrefValueStore::PrefStoreKeeper::Initialize(
|
| + PrefValueStore* store,
|
| + PrefStore* pref_store,
|
| + PrefValueStore::PrefStoreType type) {
|
| + if (pref_store_.get())
|
| + pref_store_->RemoveObserver(this);
|
| + type_ = type;
|
| + pref_value_store_ = store;
|
| + pref_store_.reset(pref_store);
|
| + if (pref_store_.get())
|
| + pref_store_->AddObserver(this);
|
| }
|
|
|
| -} // namespace
|
| +void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged(
|
| + const std::string& key) {
|
| + pref_value_store_->OnPrefValueChanged(type_, key);
|
| +}
|
|
|
| -// static
|
| -PrefValueStore* PrefValueStore::CreatePrefValueStore(
|
| - const FilePath& pref_filename,
|
| - Profile* profile,
|
| - bool user_only) {
|
| - using policy::ConfigurationPolicyPrefStore;
|
| - ConfigurationPolicyPrefStore* managed = NULL;
|
| - ConfigurationPolicyPrefStore* device_management = NULL;
|
| - CommandLinePrefStore* command_line = NULL;
|
| - ConfigurationPolicyPrefStore* recommended = NULL;
|
| -
|
| - JsonPrefStore* user = new JsonPrefStore(
|
| - pref_filename,
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
|
| - InMemoryPrefStore* extension = new InMemoryPrefStore();
|
| - InMemoryPrefStore* default_store = new InMemoryPrefStore();
|
| -
|
| - if (!user_only) {
|
| - managed =
|
| - ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore();
|
| - device_management =
|
| - ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
|
| - profile);
|
| - command_line = new CommandLinePrefStore(CommandLine::ForCurrentProcess());
|
| - recommended =
|
| - ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore();
|
| - }
|
| - return new PrefValueStore(managed, device_management, extension,
|
| - command_line, user, recommended, default_store,
|
| - profile);
|
| +void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() {
|
| + pref_value_store_->OnInitializationCompleted(type_);
|
| +}
|
| +
|
| +PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs,
|
| + PrefStore* device_management_prefs,
|
| + PrefStore* extension_prefs,
|
| + PrefStore* command_line_prefs,
|
| + PrefStore* user_prefs,
|
| + PrefStore* recommended_prefs,
|
| + PrefStore* default_prefs,
|
| + PrefNotifier* pref_notifier,
|
| + Profile* profile)
|
| + : pref_notifier_(pref_notifier),
|
| + profile_(profile) {
|
| + // NULL default pref store is usually bad, but may be OK for some unit tests.
|
| + if (!default_prefs)
|
| + LOG(WARNING) << "default pref store is null";
|
| + InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs);
|
| + InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs);
|
| + InitPrefStore(EXTENSION_STORE, extension_prefs);
|
| + InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
|
| + InitPrefStore(USER_STORE, user_prefs);
|
| + InitPrefStore(RECOMMENDED_STORE, recommended_prefs);
|
| + InitPrefStore(DEFAULT_STORE, default_prefs);
|
| +
|
| + // TODO(mnissler): Remove after policy refresh cleanup.
|
| + registrar_.Add(this,
|
| + NotificationType(NotificationType::POLICY_CHANGED),
|
| + NotificationService::AllSources());
|
| +
|
| + CheckInitializationCompleted();
|
| }
|
|
|
| PrefValueStore::~PrefValueStore() {}
|
| @@ -70,9 +77,8 @@ bool PrefValueStore::GetValue(const std::string& name,
|
| Value** out_value) const {
|
| // Check the |PrefStore|s in order of their priority from highest to lowest
|
| // to find the value of the preference described by the given preference name.
|
| - for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
|
| - if (GetValueFromStore(name.c_str(),
|
| - static_cast<PrefNotifier::PrefStoreType>(i),
|
| + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
|
| + if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i),
|
| out_value))
|
| return true;
|
| }
|
| @@ -81,7 +87,7 @@ bool PrefValueStore::GetValue(const std::string& name,
|
|
|
| bool PrefValueStore::GetUserValue(const std::string& name,
|
| Value** out_value) const {
|
| - return GetValueFromStore(name.c_str(), PrefNotifier::USER_STORE, out_value);
|
| + return GetValueFromStore(name.c_str(), USER_STORE, out_value);
|
| }
|
|
|
| void PrefValueStore::RegisterPreferenceType(const std::string& name,
|
| @@ -99,25 +105,28 @@ Value::ValueType PrefValueStore::GetRegisteredType(
|
|
|
| bool PrefValueStore::WritePrefs() {
|
| bool success = true;
|
| - for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
|
| - if (pref_stores_[i].get())
|
| - success = pref_stores_[i]->WritePrefs() && success;
|
| + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
|
| + PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i));
|
| + if (store)
|
| + success = store->WritePrefs() && success;
|
| }
|
| return success;
|
| }
|
|
|
| void PrefValueStore::ScheduleWritePrefs() {
|
| - for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
|
| - if (pref_stores_[i].get())
|
| - pref_stores_[i]->ScheduleWritePrefs();
|
| + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
|
| + PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i));
|
| + if (store)
|
| + store->ScheduleWritePrefs();
|
| }
|
| }
|
|
|
| PrefStore::PrefReadError PrefValueStore::ReadPrefs() {
|
| PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE;
|
| - for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
|
| - if (pref_stores_[i].get()) {
|
| - PrefStore::PrefReadError this_error = pref_stores_[i]->ReadPrefs();
|
| + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
|
| + PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i));
|
| + if (store) {
|
| + PrefStore::PrefReadError this_error = store->ReadPrefs();
|
| if (result == PrefStore::PREF_READ_ERROR_NONE)
|
| result = this_error;
|
| }
|
| @@ -143,158 +152,188 @@ bool PrefValueStore::HasPrefPath(const char* path) const {
|
| return rv && !PrefValueFromDefaultStore(path);
|
| }
|
|
|
| -bool PrefValueStore::PrefHasChanged(const char* path,
|
| - PrefNotifier::PrefStoreType new_store) {
|
| - DCHECK(new_store != PrefNotifier::INVALID_STORE);
|
| - // If we get a change notification about an unregistered preference,
|
| - // discard it silently because there cannot be any listeners.
|
| - if (pref_types_.find(path) == pref_types_.end())
|
| - return false;
|
| -
|
| - // Replying that the pref has changed may cause problems, but it's the safer
|
| - // choice.
|
| - if (new_store == PrefNotifier::INVALID_STORE)
|
| - return true;
|
| +void PrefValueStore::NotifyPrefChanged(
|
| + const char* path,
|
| + PrefValueStore::PrefStoreType new_store) {
|
| + DCHECK(new_store != INVALID_STORE);
|
|
|
| - PrefNotifier::PrefStoreType controller = ControllingPrefStoreForPref(path);
|
| - DCHECK(controller != PrefNotifier::INVALID_STORE)
|
| - << "Invalid controller for path " << path;
|
| - if (controller == PrefNotifier::INVALID_STORE)
|
| - return true;
|
| + // If this pref is not registered, just discard the notification.
|
| + if (!pref_types_.count(path))
|
| + return;
|
|
|
| - // If the pref is controlled by a higher-priority store, its effective value
|
| - // cannot have changed.
|
| - if (controller < new_store)
|
| - return false;
|
| + bool changed = true;
|
| + // Replying that the pref has changed in case the new store is invalid may
|
| + // cause problems, but it's the safer choice.
|
| + if (new_store != INVALID_STORE) {
|
| + PrefStoreType controller = ControllingPrefStoreForPref(path);
|
| + DCHECK(controller != INVALID_STORE);
|
| + // If the pref is controlled by a higher-priority store, its effective value
|
| + // cannot have changed.
|
| + if (controller != INVALID_STORE &&
|
| + controller < new_store) {
|
| + changed = false;
|
| + }
|
| + }
|
|
|
| - // Otherwise, we take the pref store's word that something changed.
|
| - return true;
|
| + if (changed)
|
| + pref_notifier_->OnPreferenceChanged(path);
|
| }
|
|
|
| -// Note the |DictionaryValue| referenced by the |PrefStore| USER_STORE
|
| -// (returned by the method prefs()) takes the ownership of the Value referenced
|
| -// by in_value.
|
| -bool PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) {
|
| +void PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) {
|
| + DCHECK(in_value);
|
| Value* old_value = NULL;
|
| - pref_stores_[PrefNotifier::USER_STORE]->prefs()->Get(name, &old_value);
|
| - bool value_changed = !(old_value && old_value->Equals(in_value));
|
| + GetPrefStore(USER_STORE)->prefs()->Get(name, &old_value);
|
| + bool value_changed = !old_value || !old_value->Equals(in_value);
|
| + GetPrefStore(USER_STORE)->prefs()->Set(name, in_value);
|
|
|
| - pref_stores_[PrefNotifier::USER_STORE]->prefs()->Set(name, in_value);
|
| - return value_changed;
|
| + if (value_changed)
|
| + NotifyPrefChanged(name, USER_STORE);
|
| }
|
|
|
| -// Note the |DictionaryValue| referenced by the |PrefStore| DEFAULT_STORE
|
| -// (returned by the method prefs()) takes the ownership of the Value referenced
|
| -// by in_value.
|
| -void PrefValueStore::SetDefaultPrefValue(const char* name, Value* in_value) {
|
| - pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Set(name, in_value);
|
| +void PrefValueStore::SetUserPrefValueSilently(const char* name,
|
| + Value* in_value) {
|
| + DCHECK(in_value);
|
| + GetPrefStore(USER_STORE)->prefs()->Set(name, in_value);
|
| }
|
|
|
| -bool PrefValueStore::ReadOnly() {
|
| - return pref_stores_[PrefNotifier::USER_STORE]->ReadOnly();
|
| +bool PrefValueStore::ReadOnly() const {
|
| + return GetPrefStore(USER_STORE)->ReadOnly();
|
| }
|
|
|
| -bool PrefValueStore::RemoveUserPrefValue(const char* name) {
|
| - if (pref_stores_[PrefNotifier::USER_STORE].get()) {
|
| - return pref_stores_[PrefNotifier::USER_STORE]->prefs()->Remove(name, NULL);
|
| +void PrefValueStore::RemoveUserPrefValue(const char* name) {
|
| + if (GetPrefStore(USER_STORE)) {
|
| + if (GetPrefStore(USER_STORE)->prefs()->Remove(name, NULL))
|
| + NotifyPrefChanged(name, USER_STORE);
|
| }
|
| - return false;
|
| }
|
|
|
| bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const {
|
| - return PrefValueInStore(name, PrefNotifier::MANAGED_PLATFORM_STORE);
|
| + return PrefValueInStore(name, MANAGED_PLATFORM_STORE);
|
| }
|
|
|
| bool PrefValueStore::PrefValueInDeviceManagementStore(const char* name) const {
|
| - return PrefValueInStore(name, PrefNotifier::DEVICE_MANAGEMENT_STORE);
|
| + return PrefValueInStore(name, DEVICE_MANAGEMENT_STORE);
|
| }
|
|
|
| bool PrefValueStore::PrefValueInExtensionStore(const char* name) const {
|
| - return PrefValueInStore(name, PrefNotifier::EXTENSION_STORE);
|
| + return PrefValueInStore(name, EXTENSION_STORE);
|
| }
|
|
|
| bool PrefValueStore::PrefValueInUserStore(const char* name) const {
|
| - return PrefValueInStore(name, PrefNotifier::USER_STORE);
|
| -}
|
| -
|
| -bool PrefValueStore::PrefValueInStoreRange(
|
| - const char* name,
|
| - PrefNotifier::PrefStoreType first_checked_store,
|
| - PrefNotifier::PrefStoreType last_checked_store) {
|
| - if (first_checked_store > last_checked_store) {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| -
|
| - for (size_t i = first_checked_store;
|
| - i <= static_cast<size_t>(last_checked_store); ++i) {
|
| - if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i)))
|
| - return true;
|
| - }
|
| - return false;
|
| + return PrefValueInStore(name, USER_STORE);
|
| }
|
|
|
| bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const {
|
| - return ControllingPrefStoreForPref(name) == PrefNotifier::EXTENSION_STORE;
|
| + return ControllingPrefStoreForPref(name) == EXTENSION_STORE;
|
| }
|
|
|
| bool PrefValueStore::PrefValueFromUserStore(const char* name) const {
|
| - return ControllingPrefStoreForPref(name) == PrefNotifier::USER_STORE;
|
| + return ControllingPrefStoreForPref(name) == USER_STORE;
|
| }
|
|
|
| bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const {
|
| - return ControllingPrefStoreForPref(name) == PrefNotifier::DEFAULT_STORE;
|
| + return ControllingPrefStoreForPref(name) == DEFAULT_STORE;
|
| }
|
|
|
| bool PrefValueStore::PrefValueUserModifiable(const char* name) const {
|
| - PrefNotifier::PrefStoreType effective_store =
|
| - ControllingPrefStoreForPref(name);
|
| - return effective_store >= PrefNotifier::USER_STORE ||
|
| - effective_store == PrefNotifier::INVALID_STORE;
|
| + PrefStoreType effective_store = ControllingPrefStoreForPref(name);
|
| + return effective_store >= USER_STORE ||
|
| + effective_store == INVALID_STORE;
|
| }
|
|
|
| -PrefNotifier::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
|
| - const char* name) const {
|
| - for (int i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
|
| - if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i)))
|
| - return static_cast<PrefNotifier::PrefStoreType>(i);
|
| +bool PrefValueStore::HasPolicyConflictingUserProxySettings() const {
|
| + using policy::ConfigurationPolicyPrefStore;
|
| + ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs;
|
| + ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs);
|
| + ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i;
|
| + for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) {
|
| + if ((PrefValueInManagedPlatformStore(*i) ||
|
| + PrefValueInDeviceManagementStore(*i)) &&
|
| + PrefValueInStoreRange(*i,
|
| + COMMAND_LINE_STORE,
|
| + USER_STORE))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +// Returns true if the actual value is a valid type for the expected type when
|
| +// found in the given store.
|
| +bool PrefValueStore::IsValidType(Value::ValueType expected,
|
| + Value::ValueType actual,
|
| + PrefValueStore::PrefStoreType store) {
|
| + if (expected == actual)
|
| + return true;
|
| +
|
| + // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only
|
| + // in the default pref store.
|
| + if (store == DEFAULT_STORE &&
|
| + actual == Value::TYPE_NULL &&
|
| + (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) {
|
| + return true;
|
| }
|
| - return PrefNotifier::INVALID_STORE;
|
| + return false;
|
| }
|
|
|
| bool PrefValueStore::PrefValueInStore(
|
| const char* name,
|
| - PrefNotifier::PrefStoreType store) const {
|
| + PrefValueStore::PrefStoreType store) const {
|
| // Declare a temp Value* and call GetValueFromStore,
|
| // ignoring the output value.
|
| Value* tmp_value = NULL;
|
| return GetValueFromStore(name, store, &tmp_value);
|
| }
|
|
|
| -bool PrefValueStore::GetValueFromStore(
|
| +bool PrefValueStore::PrefValueInStoreRange(
|
| const char* name,
|
| - PrefNotifier::PrefStoreType store,
|
| - Value** out_value) const {
|
| + PrefValueStore::PrefStoreType first_checked_store,
|
| + PrefValueStore::PrefStoreType last_checked_store) const {
|
| + if (first_checked_store > last_checked_store) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| +
|
| + for (size_t i = first_checked_store;
|
| + i <= static_cast<size_t>(last_checked_store); ++i) {
|
| + if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
|
| + const char* name) const {
|
| + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
|
| + if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
|
| + return static_cast<PrefStoreType>(i);
|
| + }
|
| + return INVALID_STORE;
|
| +}
|
| +
|
| +bool PrefValueStore::GetValueFromStore(const char* name,
|
| + PrefValueStore::PrefStoreType store_type,
|
| + Value** out_value) const {
|
| // Only return true if we find a value and it is the correct type, so stale
|
| // values with the incorrect type will be ignored.
|
| - if (pref_stores_[store].get() &&
|
| - pref_stores_[store]->prefs()->Get(name, out_value)) {
|
| - // If the value is the sentinel that redirects to the default
|
| - // store, re-fetch the value from the default store explicitly.
|
| - // Because the default values are not available when creating
|
| - // stores, the default value must be fetched dynamically for every
|
| - // redirect.
|
| + const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type));
|
| + if (store && store->prefs()->Get(name, out_value)) {
|
| + // If the value is the sentinel that redirects to the default store,
|
| + // re-fetch the value from the default store explicitly. Because the default
|
| + // values are not available when creating stores, the default value must be
|
| + // fetched dynamically for every redirect.
|
| if (PrefStore::IsUseDefaultSentinelValue(*out_value)) {
|
| - DCHECK(pref_stores_[PrefNotifier::DEFAULT_STORE].get());
|
| - if (!pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Get(name,
|
| - out_value)) {
|
| + store = GetPrefStore(DEFAULT_STORE);
|
| + if (!store || !store->prefs()->Get(name, out_value)) {
|
| *out_value = NULL;
|
| return false;
|
| }
|
| - store = PrefNotifier::DEFAULT_STORE;
|
| + store_type = DEFAULT_STORE;
|
| }
|
| - if (IsValidType(GetRegisteredType(name), (*out_value)->GetType(), store))
|
| + if (IsValidType(GetRegisteredType(name),
|
| + (*out_value)->GetType(),
|
| + store_type)) {
|
| return true;
|
| + }
|
| }
|
| // No valid value found for the given preference name: set the return false.
|
| *out_value = NULL;
|
| @@ -305,9 +344,7 @@ void PrefValueStore::RefreshPolicyPrefsOnFileThread(
|
| BrowserThread::ID calling_thread_id,
|
| PrefStore* new_managed_platform_pref_store,
|
| PrefStore* new_device_management_pref_store,
|
| - PrefStore* new_recommended_pref_store,
|
| - AfterRefreshCallback* callback_pointer) {
|
| - scoped_ptr<AfterRefreshCallback> callback(callback_pointer);
|
| + PrefStore* new_recommended_pref_store) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| scoped_ptr<PrefStore> managed_platform_pref_store(
|
| new_managed_platform_pref_store);
|
| @@ -343,30 +380,54 @@ void PrefValueStore::RefreshPolicyPrefsOnFileThread(
|
| &PrefValueStore::RefreshPolicyPrefsCompletion,
|
| managed_platform_pref_store.release(),
|
| device_management_pref_store.release(),
|
| - recommended_pref_store.release(),
|
| - callback.release()));
|
| + recommended_pref_store.release()));
|
| +}
|
| +
|
| +void PrefValueStore::RefreshPolicyPrefs() {
|
| + using policy::ConfigurationPolicyPrefStore;
|
| + // Because loading of policy information must happen on the FILE
|
| + // thread, it's not possible to just replace the contents of the
|
| + // managed and recommended stores in place due to possible
|
| + // concurrent access from the UI thread. Instead, new stores are
|
| + // created and the refreshed policy read into them. The new stores
|
| + // are swapped with the old from a Task on the UI thread after the
|
| + // load is complete.
|
| + PrefStore* new_managed_platform_pref_store(
|
| + ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore());
|
| + PrefStore* new_device_management_pref_store(
|
| + ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
|
| + profile_));
|
| + PrefStore* new_recommended_pref_store(
|
| + ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore());
|
| + BrowserThread::ID current_thread_id;
|
| + CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &PrefValueStore::RefreshPolicyPrefsOnFileThread,
|
| + current_thread_id,
|
| + new_managed_platform_pref_store,
|
| + new_device_management_pref_store,
|
| + new_recommended_pref_store));
|
| }
|
|
|
| void PrefValueStore::RefreshPolicyPrefsCompletion(
|
| PrefStore* new_managed_platform_pref_store,
|
| PrefStore* new_device_management_pref_store,
|
| - PrefStore* new_recommended_pref_store,
|
| - AfterRefreshCallback* callback_pointer) {
|
| - scoped_ptr<AfterRefreshCallback> callback(callback_pointer);
|
| -
|
| + PrefStore* new_recommended_pref_store) {
|
| // Determine the paths of all the changed preferences values in the three
|
| // policy-related stores (managed platform, device management and
|
| // recommended).
|
| DictionaryValue* managed_platform_prefs_before(
|
| - pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE]->prefs());
|
| + GetPrefStore(MANAGED_PLATFORM_STORE)->prefs());
|
| DictionaryValue* managed_platform_prefs_after(
|
| new_managed_platform_pref_store->prefs());
|
| DictionaryValue* device_management_prefs_before(
|
| - pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE]->prefs());
|
| + GetPrefStore(DEVICE_MANAGEMENT_STORE)->prefs());
|
| DictionaryValue* device_management_prefs_after(
|
| new_device_management_pref_store->prefs());
|
| DictionaryValue* recommended_prefs_before(
|
| - pref_stores_[PrefNotifier::RECOMMENDED_STORE]->prefs());
|
| + GetPrefStore(RECOMMENDED_STORE)->prefs());
|
| DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs());
|
|
|
| std::vector<std::string> changed_managed_platform_paths;
|
| @@ -412,84 +473,45 @@ void PrefValueStore::RefreshPolicyPrefsCompletion(
|
|
|
| // Replace the old stores with the new and send notification of the changed
|
| // preferences.
|
| - pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset(
|
| - new_managed_platform_pref_store);
|
| - pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset(
|
| - new_device_management_pref_store);
|
| - pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(
|
| - new_recommended_pref_store);
|
| - callback->Run(changed_paths);
|
| + InitPrefStore(MANAGED_PLATFORM_STORE, new_managed_platform_pref_store);
|
| + InitPrefStore(DEVICE_MANAGEMENT_STORE, new_device_management_pref_store);
|
| + InitPrefStore(RECOMMENDED_STORE, new_recommended_pref_store);
|
| +
|
| + std::vector<std::string>::const_iterator current;
|
| + for (current = changed_paths.begin();
|
| + current != changed_paths.end();
|
| + ++current) {
|
| + pref_notifier_->OnPreferenceChanged(current->c_str());
|
| + }
|
| }
|
|
|
| -void PrefValueStore::RefreshPolicyPrefs(
|
| - AfterRefreshCallback* callback) {
|
| - using policy::ConfigurationPolicyPrefStore;
|
| - // Because loading of policy information must happen on the FILE
|
| - // thread, it's not possible to just replace the contents of the
|
| - // managed and recommended stores in place due to possible
|
| - // concurrent access from the UI thread. Instead, new stores are
|
| - // created and the refreshed policy read into them. The new stores
|
| - // are swapped with the old from a Task on the UI thread after the
|
| - // load is complete.
|
| - PrefStore* new_managed_platform_pref_store(
|
| - ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore());
|
| - PrefStore* new_device_management_pref_store(
|
| - ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
|
| - profile_));
|
| - PrefStore* new_recommended_pref_store(
|
| - ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore());
|
| - BrowserThread::ID current_thread_id;
|
| - CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id));
|
| - BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - NewRunnableMethod(this,
|
| - &PrefValueStore::RefreshPolicyPrefsOnFileThread,
|
| - current_thread_id,
|
| - new_managed_platform_pref_store,
|
| - new_device_management_pref_store,
|
| - new_recommended_pref_store,
|
| - callback));
|
| +void PrefValueStore::Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details) {
|
| + if (type == NotificationType::POLICY_CHANGED)
|
| + RefreshPolicyPrefs();
|
| }
|
|
|
| -bool PrefValueStore::HasPolicyConflictingUserProxySettings() {
|
| - using policy::ConfigurationPolicyPrefStore;
|
| - ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs;
|
| - ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs);
|
| - ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i;
|
| - for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) {
|
| - if ((PrefValueInManagedPlatformStore(*i) ||
|
| - PrefValueInDeviceManagementStore(*i)) &&
|
| - PrefValueInStoreRange(*i,
|
| - PrefNotifier::COMMAND_LINE_STORE,
|
| - PrefNotifier::USER_STORE))
|
| - return true;
|
| - }
|
| - return false;
|
| +void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type,
|
| + const std::string& key) {
|
| + NotifyPrefChanged(key.c_str(), type);
|
| }
|
|
|
| -PrefStore* PrefValueStore::GetExtensionPrefStore() const {
|
| - return pref_stores_[PrefNotifier::EXTENSION_STORE].get();
|
| +void PrefValueStore::OnInitializationCompleted(
|
| + PrefValueStore::PrefStoreType type) {
|
| + CheckInitializationCompleted();
|
| }
|
|
|
| -PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs,
|
| - PrefStore* device_management_prefs,
|
| - PrefStore* extension_prefs,
|
| - PrefStore* command_line_prefs,
|
| - PrefStore* user_prefs,
|
| - PrefStore* recommended_prefs,
|
| - PrefStore* default_prefs,
|
| - Profile* profile)
|
| - : profile_(profile) {
|
| - // NULL default pref store is usually bad, but may be OK for some unit tests.
|
| - if (!default_prefs)
|
| - LOG(WARNING) << "default pref store is null";
|
| - pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset(
|
| - managed_platform_prefs);
|
| - pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset(
|
| - device_management_prefs);
|
| - pref_stores_[PrefNotifier::EXTENSION_STORE].reset(extension_prefs);
|
| - pref_stores_[PrefNotifier::COMMAND_LINE_STORE].reset(command_line_prefs);
|
| - pref_stores_[PrefNotifier::USER_STORE].reset(user_prefs);
|
| - pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(recommended_prefs);
|
| - pref_stores_[PrefNotifier::DEFAULT_STORE].reset(default_prefs);
|
| +void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type,
|
| + PrefStore* pref_store) {
|
| + pref_stores_[type].Initialize(this, pref_store, type);
|
| +}
|
| +
|
| +void PrefValueStore::CheckInitializationCompleted() {
|
| + for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
|
| + PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i));
|
| + if (store && !store->IsInitializationComplete())
|
| + return;
|
| + }
|
| + pref_notifier_->OnInitializationCompleted();
|
| }
|
|
|