Commit 39565dde authored by mnaganov@chromium.org's avatar mnaganov@chromium.org

Take out and generalize user prefs overriding from IncognitoUserPrefStore.

Add support for "local" and "global" user preferences where
a "local" preference set in the overlay shadows the "global" preference.

BUG=none
TEST=OverlayUserPrefStoreTest*

Review URL: http://codereview.chromium.org/8515002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109865 0039d316-1c4b-4281-b951-d872f2087c98
parent 36fde602
......@@ -3,150 +3,12 @@
// found in the LICENSE file.
#include "chrome/browser/prefs/incognito_user_pref_store.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/common/pref_names.h"
IncognitoUserPrefStore::IncognitoUserPrefStore(
PersistentPrefStore* underlay)
: underlay_(underlay) {
underlay_->AddObserver(this);
}
IncognitoUserPrefStore::~IncognitoUserPrefStore() {
underlay_->RemoveObserver(this);
}
bool IncognitoUserPrefStore::IsSetInOverlay(const std::string& key) const {
return overlay_.GetValue(key, NULL);
}
void IncognitoUserPrefStore::AddObserver(PrefStore::Observer* observer) {
observers_.AddObserver(observer);
}
void IncognitoUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
observers_.RemoveObserver(observer);
}
bool IncognitoUserPrefStore::IsInitializationComplete() const {
return underlay_->IsInitializationComplete();
}
PrefStore::ReadResult IncognitoUserPrefStore::GetValue(
const std::string& key,
const Value** result) const {
// If the |key| shall NOT be stored in the overlay store, there must not
// be an entry.
DCHECK(ShallBeStoredInOverlay(key) || !overlay_.GetValue(key, NULL));
if (overlay_.GetValue(key, result))
return READ_OK;
return underlay_->GetValue(key, result);
}
PrefStore::ReadResult IncognitoUserPrefStore::GetMutableValue(
const std::string& key,
Value** result) {
if (!ShallBeStoredInOverlay(key))
return underlay_->GetMutableValue(key, result);
if (overlay_.GetValue(key, result))
return READ_OK;
// Try to create copy of underlay if the overlay does not contain a value.
Value* underlay_value = NULL;
PrefStore::ReadResult read_result =
underlay_->GetMutableValue(key, &underlay_value);
if (read_result != READ_OK)
return read_result;
*result = underlay_value->DeepCopy();
overlay_.SetValue(key, *result);
return READ_OK;
}
void IncognitoUserPrefStore::SetValue(const std::string& key,
Value* value) {
if (!ShallBeStoredInOverlay(key)) {
underlay_->SetValue(key, value);
return;
}
if (overlay_.SetValue(key, value))
ReportValueChanged(key);
}
void IncognitoUserPrefStore::SetValueSilently(const std::string& key,
Value* value) {
if (!ShallBeStoredInOverlay(key)) {
underlay_->SetValueSilently(key, value);
return;
}
overlay_.SetValue(key, value);
}
void IncognitoUserPrefStore::RemoveValue(const std::string& key) {
if (!ShallBeStoredInOverlay(key)) {
underlay_->RemoveValue(key);
return;
}
if (overlay_.RemoveValue(key))
ReportValueChanged(key);
}
bool IncognitoUserPrefStore::ReadOnly() const {
return false;
}
PersistentPrefStore::PrefReadError IncognitoUserPrefStore::ReadPrefs() {
// We do not read intentionally.
OnInitializationCompleted(true);
return PersistentPrefStore::PREF_READ_ERROR_NONE;
}
void IncognitoUserPrefStore::ReadPrefsAsync(
ReadErrorDelegate* error_delegate_raw) {
scoped_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
// We do not read intentionally.
OnInitializationCompleted(true);
}
bool IncognitoUserPrefStore::WritePrefs() {
// We do not write our content intentionally.
return true;
}
void IncognitoUserPrefStore::ScheduleWritePrefs() {
underlay_->ScheduleWritePrefs();
// We do not write our content intentionally.
}
void IncognitoUserPrefStore::CommitPendingWrite() {
underlay_->CommitPendingWrite();
// We do not write our content intentionally.
}
void IncognitoUserPrefStore::ReportValueChanged(const std::string& key) {
FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
}
void IncognitoUserPrefStore::OnPrefValueChanged(const std::string& key) {
if (!overlay_.GetValue(key, NULL))
ReportValueChanged(key);
}
void IncognitoUserPrefStore::OnInitializationCompleted(bool succeeded) {
FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
OnInitializationCompleted(succeeded));
}
bool IncognitoUserPrefStore::ShallBeStoredInOverlay(
const std::string& key) const {
IncognitoUserPrefStore::IncognitoUserPrefStore(PersistentPrefStore* underlay)
: OverlayUserPrefStore(underlay) {
// List of keys that cannot be changed in the user prefs file by the incognito
// profile:
return key == prefs::kBrowserWindowPlacement;
// profile. All preferences that store information about the browsing history
// or behavior of the user should have this property.
RegisterOverlayProperty(prefs::kBrowserWindowPlacement);
}
......@@ -8,62 +8,13 @@
#include <string>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "chrome/browser/prefs/pref_value_map.h"
#include "chrome/common/persistent_pref_store.h"
#include "chrome/browser/prefs/overlay_user_pref_store.h"
// PersistentPrefStore that directs all write operations into an in-memory
// PrefValueMap. Read operations are first answered by the PrefValueMap.
// If the PrefValueMap does not contain a value for the requested key,
// the look-up is passed on to an underlying PersistentPrefStore |underlay_|.
class IncognitoUserPrefStore : public PersistentPrefStore,
public PrefStore::Observer {
class IncognitoUserPrefStore : public OverlayUserPrefStore {
public:
explicit IncognitoUserPrefStore(PersistentPrefStore* underlay);
virtual ~IncognitoUserPrefStore();
// Returns true if a value has been set for the |key| in this
// IncognitoUserPrefStore, i.e. if it potentially overrides a value
// from the |underlay_|.
virtual bool IsSetInOverlay(const std::string& key) const;
// Methods of PrefStore.
virtual void AddObserver(PrefStore::Observer* observer);
virtual void RemoveObserver(PrefStore::Observer* observer);
virtual bool IsInitializationComplete() const;
virtual ReadResult GetValue(const std::string& key,
const base::Value** result) const;
// Methods of PersistentPrefStore.
virtual ReadResult GetMutableValue(const std::string& key,
base::Value** result);
virtual void SetValue(const std::string& key, base::Value* value);
virtual void SetValueSilently(const std::string& key, base::Value* value);
virtual void RemoveValue(const std::string& key);
virtual bool ReadOnly() const;
virtual PrefReadError ReadPrefs();
virtual void ReadPrefsAsync(ReadErrorDelegate* delegate);
virtual bool WritePrefs();
virtual void ScheduleWritePrefs();
virtual void CommitPendingWrite();
virtual void ReportValueChanged(const std::string& key);
private:
// Methods of PrefStore::Observer.
virtual void OnPrefValueChanged(const std::string& key);
virtual void OnInitializationCompleted(bool succeeded);
// Returns true if |key| corresponds to a preference that shall be stored in
// an in-memory PrefStore that is not persisted to disk. All preferences
// that store information about the browsing history or behavior of the user
// should have this property.
virtual bool ShallBeStoredInOverlay(const std::string& key) const;
ObserverList<PrefStore::Observer, true> observers_;
PrefValueMap overlay_;
scoped_refptr<PersistentPrefStore> underlay_;
DISALLOW_COPY_AND_ASSIGN(IncognitoUserPrefStore);
};
......
// Copyright (c) 2011 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 "chrome/browser/prefs/incognito_user_pref_store.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
OverlayUserPrefStore::OverlayUserPrefStore(
PersistentPrefStore* underlay)
: underlay_(underlay) {
underlay_->AddObserver(this);
}
OverlayUserPrefStore::~OverlayUserPrefStore() {
underlay_->RemoveObserver(this);
}
bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const {
return overlay_.GetValue(key, NULL);
}
void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
observers_.AddObserver(observer);
}
void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
observers_.RemoveObserver(observer);
}
bool OverlayUserPrefStore::IsInitializationComplete() const {
return underlay_->IsInitializationComplete();
}
PrefStore::ReadResult OverlayUserPrefStore::GetValue(
const std::string& key,
const Value** result) const {
// If the |key| shall NOT be stored in the overlay store, there must not
// be an entry.
DCHECK(ShallBeStoredInOverlay(key) || !overlay_.GetValue(key, NULL));
if (overlay_.GetValue(key, result))
return READ_OK;
return underlay_->GetValue(GetUnderlayKey(key), result);
}
PrefStore::ReadResult OverlayUserPrefStore::GetMutableValue(
const std::string& key,
Value** result) {
if (!ShallBeStoredInOverlay(key))
return underlay_->GetMutableValue(GetUnderlayKey(key), result);
if (overlay_.GetValue(key, result))
return READ_OK;
// Try to create copy of underlay if the overlay does not contain a value.
Value* underlay_value = NULL;
PrefStore::ReadResult read_result =
underlay_->GetMutableValue(GetUnderlayKey(key), &underlay_value);
if (read_result != READ_OK)
return read_result;
*result = underlay_value->DeepCopy();
overlay_.SetValue(key, *result);
return READ_OK;
}
void OverlayUserPrefStore::SetValue(const std::string& key,
Value* value) {
if (!ShallBeStoredInOverlay(key)) {
underlay_->SetValue(GetUnderlayKey(key), value);
return;
}
if (overlay_.SetValue(key, value))
ReportValueChanged(key);
}
void OverlayUserPrefStore::SetValueSilently(const std::string& key,
Value* value) {
if (!ShallBeStoredInOverlay(key)) {
underlay_->SetValueSilently(GetUnderlayKey(key), value);
return;
}
overlay_.SetValue(key, value);
}
void OverlayUserPrefStore::RemoveValue(const std::string& key) {
if (!ShallBeStoredInOverlay(key)) {
underlay_->RemoveValue(GetUnderlayKey(key));
return;
}
if (overlay_.RemoveValue(key))
ReportValueChanged(key);
}
bool OverlayUserPrefStore::ReadOnly() const {
return false;
}
PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
// We do not read intentionally.
OnInitializationCompleted(true);
return PersistentPrefStore::PREF_READ_ERROR_NONE;
}
void OverlayUserPrefStore::ReadPrefsAsync(
ReadErrorDelegate* error_delegate_raw) {
scoped_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
// We do not read intentionally.
OnInitializationCompleted(true);
}
bool OverlayUserPrefStore::WritePrefs() {
// We do not write our content intentionally.
return true;
}
void OverlayUserPrefStore::ScheduleWritePrefs() {
underlay_->ScheduleWritePrefs();
// We do not write our content intentionally.
}
void OverlayUserPrefStore::CommitPendingWrite() {
underlay_->CommitPendingWrite();
// We do not write our content intentionally.
}
void OverlayUserPrefStore::ReportValueChanged(const std::string& key) {
FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
}
void OverlayUserPrefStore::RegisterOverlayProperty(const std::string& key) {
RegisterOverlayProperty(key, key);
}
void OverlayUserPrefStore::RegisterOverlayProperty(
const std::string& overlay_key,
const std::string& underlay_key) {
DCHECK(!overlay_key.empty()) << "Overlay key is empty";
DCHECK(overlay_to_underlay_names_map_.find(overlay_key) ==
overlay_to_underlay_names_map_.end()) <<
"Overlay key already registered";
DCHECK(!underlay_key.empty()) << "Underlay key is empty";
DCHECK(underlay_to_overlay_names_map_.find(underlay_key) ==
underlay_to_overlay_names_map_.end()) <<
"Underlay key already registered";
overlay_to_underlay_names_map_[overlay_key] = underlay_key;
underlay_to_overlay_names_map_[underlay_key] = overlay_key;
}
void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) {
if (!overlay_.GetValue(GetOverlayKey(key), NULL))
ReportValueChanged(GetOverlayKey(key));
}
void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) {
FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
OnInitializationCompleted(succeeded));
}
const std::string& OverlayUserPrefStore::GetOverlayKey(
const std::string& underlay_key) const {
NamesMap::const_iterator i =
underlay_to_overlay_names_map_.find(underlay_key);
return i != underlay_to_overlay_names_map_.end() ? i->second : underlay_key;
}
const std::string& OverlayUserPrefStore::GetUnderlayKey(
const std::string& overlay_key) const {
NamesMap::const_iterator i =
overlay_to_underlay_names_map_.find(overlay_key);
return i != overlay_to_underlay_names_map_.end() ? i->second : overlay_key;
}
bool OverlayUserPrefStore::ShallBeStoredInOverlay(
const std::string& key) const {
return overlay_to_underlay_names_map_.find(key) !=
overlay_to_underlay_names_map_.end();
}
// Copyright (c) 2011 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.
#ifndef CHROME_BROWSER_PREFS_OVERLAY_USER_PREF_STORE_H_
#define CHROME_BROWSER_PREFS_OVERLAY_USER_PREF_STORE_H_
#pragma once
#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "chrome/browser/prefs/pref_value_map.h"
#include "chrome/common/persistent_pref_store.h"
// PersistentPrefStore that directs all write operations into an in-memory
// PrefValueMap. Read operations are first answered by the PrefValueMap.
// If the PrefValueMap does not contain a value for the requested key,
// the look-up is passed on to an underlying PersistentPrefStore |underlay_|.
class OverlayUserPrefStore : public PersistentPrefStore,
public PrefStore::Observer {
public:
explicit OverlayUserPrefStore(PersistentPrefStore* underlay);
virtual ~OverlayUserPrefStore();
// Returns true if a value has been set for the |key| in this
// OverlayUserPrefStore, i.e. if it potentially overrides a value
// from the |underlay_|.
virtual bool IsSetInOverlay(const std::string& key) const;
// Methods of PrefStore.
virtual void AddObserver(PrefStore::Observer* observer);
virtual void RemoveObserver(PrefStore::Observer* observer);
virtual bool IsInitializationComplete() const;
virtual ReadResult GetValue(const std::string& key,
const base::Value** result) const;
// Methods of PersistentPrefStore.
virtual ReadResult GetMutableValue(const std::string& key,
base::Value** result);
virtual void SetValue(const std::string& key, base::Value* value);
virtual void SetValueSilently(const std::string& key, base::Value* value);
virtual void RemoveValue(const std::string& key);
virtual bool ReadOnly() const;
virtual PrefReadError ReadPrefs();
virtual void ReadPrefsAsync(ReadErrorDelegate* delegate);
virtual bool WritePrefs();
virtual void ScheduleWritePrefs();
virtual void CommitPendingWrite();
virtual void ReportValueChanged(const std::string& key);
protected:
void RegisterOverlayProperty(const std::string& key);
void RegisterOverlayProperty(const std::string& overlay_key,
const std::string& underlay_key);
private:
friend class OverlayUserPrefStoreTest;
typedef std::map<std::string, std::string> NamesMap;
// Methods of PrefStore::Observer.
virtual void OnPrefValueChanged(const std::string& key);
virtual void OnInitializationCompleted(bool succeeded);
const std::string& GetOverlayKey(const std::string& underlay_key) const;
const std::string& GetUnderlayKey(const std::string& overlay_key) const;
// Returns true if |key| corresponds to a preference that shall be stored in
// an in-memory PrefStore that is not persisted to disk.
bool ShallBeStoredInOverlay(const std::string& key) const;
ObserverList<PrefStore::Observer, true> observers_;
PrefValueMap overlay_;
scoped_refptr<PersistentPrefStore> underlay_;
NamesMap overlay_to_underlay_names_map_;
NamesMap underlay_to_overlay_names_map_;
DISALLOW_COPY_AND_ASSIGN(OverlayUserPrefStore);
};
#endif // CHROME_BROWSER_PREFS_OVERLAY_USER_PREF_STORE_H_
......@@ -1827,6 +1827,8 @@
'browser/prefs/incognito_mode_prefs.h',
'browser/prefs/incognito_user_pref_store.cc',
'browser/prefs/incognito_user_pref_store.h',
'browser/prefs/overlay_user_pref_store.cc',
'browser/prefs/overlay_user_pref_store.h',
'browser/prefs/pref_change_registrar.cc',
'browser/prefs/pref_change_registrar.h',
'browser/prefs/pref_member.cc',
......
......@@ -1503,7 +1503,7 @@
'browser/preferences_mock_mac.h',
'browser/prefs/command_line_pref_store_unittest.cc',
'browser/prefs/incognito_mode_prefs_unittest.cc',
'browser/prefs/incognito_user_pref_store_unittest.cc',
'browser/prefs/overlay_user_pref_store_unittest.cc',
'browser/prefs/pref_change_registrar_unittest.cc',
'browser/prefs/pref_member_unittest.cc',
'browser/prefs/pref_model_associator_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment