root/base/prefs/pref_value_store.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. type_
  2. Initialize
  3. OnPrefValueChanged
  4. OnInitializationCompleted
  5. initialization_failed_
  6. CloneAndSpecialize
  7. set_callback
  8. GetValue
  9. GetRecommendedValue
  10. NotifyPrefChanged
  11. PrefValueInManagedStore
  12. PrefValueInExtensionStore
  13. PrefValueInUserStore
  14. PrefValueFromExtensionStore
  15. PrefValueFromUserStore
  16. PrefValueFromRecommendedStore
  17. PrefValueFromDefaultStore
  18. PrefValueUserModifiable
  19. PrefValueExtensionModifiable
  20. UpdateCommandLinePrefStore
  21. PrefValueInStore
  22. PrefValueInStoreRange
  23. ControllingPrefStoreForPref
  24. GetValueFromStore
  25. GetValueFromStoreWithType
  26. OnPrefValueChanged
  27. OnInitializationCompleted
  28. InitPrefStore
  29. CheckInitializationCompleted

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/prefs/pref_value_store.h"

#include "base/logging.h"
#include "base/prefs/pref_notifier.h"
#include "base/prefs/pref_observer.h"

PrefValueStore::PrefStoreKeeper::PrefStoreKeeper()
    : pref_value_store_(NULL),
      type_(PrefValueStore::INVALID_STORE) {
}

PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() {
  if (pref_store_.get()) {
    pref_store_->RemoveObserver(this);
    pref_store_ = NULL;
  }
  pref_value_store_ = NULL;
}

void PrefValueStore::PrefStoreKeeper::Initialize(
    PrefValueStore* store,
    PrefStore* pref_store,
    PrefValueStore::PrefStoreType type) {
  if (pref_store_.get()) {
    pref_store_->RemoveObserver(this);
    DCHECK(!pref_store_->HasObservers());
  }
  type_ = type;
  pref_value_store_ = store;
  pref_store_ = pref_store;
  if (pref_store_.get())
    pref_store_->AddObserver(this);
}

void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged(
    const std::string& key) {
  pref_value_store_->OnPrefValueChanged(type_, key);
}

void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted(
    bool succeeded) {
  pref_value_store_->OnInitializationCompleted(type_, succeeded);
}

PrefValueStore::PrefValueStore(PrefStore* managed_prefs,
                               PrefStore* supervised_user_prefs,
                               PrefStore* extension_prefs,
                               PrefStore* command_line_prefs,
                               PrefStore* user_prefs,
                               PrefStore* recommended_prefs,
                               PrefStore* default_prefs,
                               PrefNotifier* pref_notifier)
    : pref_notifier_(pref_notifier),
      initialization_failed_(false) {
  InitPrefStore(MANAGED_STORE, managed_prefs);
  InitPrefStore(SUPERVISED_USER_STORE, supervised_user_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);

  CheckInitializationCompleted();
}

PrefValueStore::~PrefValueStore() {}

PrefValueStore* PrefValueStore::CloneAndSpecialize(
    PrefStore* managed_prefs,
    PrefStore* supervised_user_prefs,
    PrefStore* extension_prefs,
    PrefStore* command_line_prefs,
    PrefStore* user_prefs,
    PrefStore* recommended_prefs,
    PrefStore* default_prefs,
    PrefNotifier* pref_notifier) {
  DCHECK(pref_notifier);
  if (!managed_prefs)
    managed_prefs = GetPrefStore(MANAGED_STORE);
  if (!supervised_user_prefs)
    supervised_user_prefs = GetPrefStore(SUPERVISED_USER_STORE);
  if (!extension_prefs)
    extension_prefs = GetPrefStore(EXTENSION_STORE);
  if (!command_line_prefs)
    command_line_prefs = GetPrefStore(COMMAND_LINE_STORE);
  if (!user_prefs)
    user_prefs = GetPrefStore(USER_STORE);
  if (!recommended_prefs)
    recommended_prefs = GetPrefStore(RECOMMENDED_STORE);
  if (!default_prefs)
    default_prefs = GetPrefStore(DEFAULT_STORE);

  return new PrefValueStore(
      managed_prefs, supervised_user_prefs, extension_prefs, command_line_prefs,
      user_prefs, recommended_prefs, default_prefs, pref_notifier);
}

void PrefValueStore::set_callback(const PrefChangedCallback& callback) {
  pref_changed_callback_ = callback;
}

bool PrefValueStore::GetValue(const std::string& name,
                              base::Value::Type type,
                              const base::Value** out_value) const {
  // Check the |PrefStore|s in order of their priority from highest to lowest,
  // looking for the first preference value with the given |name| and |type|.
  for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
    if (GetValueFromStoreWithType(name.c_str(), type,
                                  static_cast<PrefStoreType>(i), out_value))
      return true;
  }
  return false;
}

bool PrefValueStore::GetRecommendedValue(const std::string& name,
                                         base::Value::Type type,
                                         const base::Value** out_value) const {
  return GetValueFromStoreWithType(name.c_str(), type, RECOMMENDED_STORE,
                                   out_value);
}

void PrefValueStore::NotifyPrefChanged(
    const char* path,
    PrefValueStore::PrefStoreType new_store) {
  DCHECK(new_store != INVALID_STORE);
  // A notification is sent when the pref value in any store changes. If this
  // store is currently being overridden by a higher-priority store, the
  // effective value of the pref will not have changed.
  pref_notifier_->OnPreferenceChanged(path);
  if (!pref_changed_callback_.is_null())
    pref_changed_callback_.Run(path);
}

bool PrefValueStore::PrefValueInManagedStore(const char* name) const {
  return PrefValueInStore(name, MANAGED_STORE);
}

bool PrefValueStore::PrefValueInExtensionStore(const char* name) const {
  return PrefValueInStore(name, EXTENSION_STORE);
}

bool PrefValueStore::PrefValueInUserStore(const char* name) const {
  return PrefValueInStore(name, USER_STORE);
}

bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const {
  return ControllingPrefStoreForPref(name) == EXTENSION_STORE;
}

bool PrefValueStore::PrefValueFromUserStore(const char* name) const {
  return ControllingPrefStoreForPref(name) == USER_STORE;
}

bool PrefValueStore::PrefValueFromRecommendedStore(const char* name) const {
  return ControllingPrefStoreForPref(name) == RECOMMENDED_STORE;
}

bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const {
  return ControllingPrefStoreForPref(name) == DEFAULT_STORE;
}

bool PrefValueStore::PrefValueUserModifiable(const char* name) const {
  PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  return effective_store >= USER_STORE ||
         effective_store == INVALID_STORE;
}

bool PrefValueStore::PrefValueExtensionModifiable(const char* name) const {
  PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  return effective_store >= EXTENSION_STORE ||
         effective_store == INVALID_STORE;
}

void PrefValueStore::UpdateCommandLinePrefStore(PrefStore* command_line_prefs) {
  InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
}

bool PrefValueStore::PrefValueInStore(
    const char* name,
    PrefValueStore::PrefStoreType store) const {
  // Declare a temp Value* and call GetValueFromStore,
  // ignoring the output value.
  const base::Value* tmp_value = NULL;
  return GetValueFromStore(name, store, &tmp_value);
}

bool PrefValueStore::PrefValueInStoreRange(
    const char* name,
    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,
                                       const base::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.
  const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type));
  if (store && store->GetValue(name, out_value))
    return true;

  // No valid value found for the given preference name: set the return value
  // to false.
  *out_value = NULL;
  return false;
}

bool PrefValueStore::GetValueFromStoreWithType(
    const char* name,
    base::Value::Type type,
    PrefStoreType store,
    const base::Value** out_value) const {
  if (GetValueFromStore(name, store, out_value)) {
    if ((*out_value)->IsType(type))
      return true;

    LOG(WARNING) << "Expected type for " << name << " is " << type
                 << " but got " << (*out_value)->GetType()
                 << " in store " << store;
  }

  *out_value = NULL;
  return false;
}

void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type,
                                        const std::string& key) {
  NotifyPrefChanged(key.c_str(), type);
}

void PrefValueStore::OnInitializationCompleted(
    PrefValueStore::PrefStoreType type, bool succeeded) {
  if (initialization_failed_)
    return;
  if (!succeeded) {
    initialization_failed_ = true;
    pref_notifier_->OnInitializationCompleted(false);
    return;
  }
  CheckInitializationCompleted();
}

void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type,
                                   PrefStore* pref_store) {
  pref_stores_[type].Initialize(this, pref_store, type);
}

void PrefValueStore::CheckInitializationCompleted() {
  if (initialization_failed_)
    return;
  for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
    scoped_refptr<PrefStore> store =
        GetPrefStore(static_cast<PrefStoreType>(i));
    if (store.get() && !store->IsInitializationComplete())
      return;
  }
  pref_notifier_->OnInitializationCompleted(true);
}

/* [<][>][^][v][top][bottom][index][help] */