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 @@ ...@@ -3,150 +3,12 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/prefs/incognito_user_pref_store.h" #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" #include "chrome/common/pref_names.h"
IncognitoUserPrefStore::IncognitoUserPrefStore( IncognitoUserPrefStore::IncognitoUserPrefStore(PersistentPrefStore* underlay)
PersistentPrefStore* underlay) : OverlayUserPrefStore(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 {
// List of keys that cannot be changed in the user prefs file by the incognito // List of keys that cannot be changed in the user prefs file by the incognito
// profile: // profile. All preferences that store information about the browsing history
return key == prefs::kBrowserWindowPlacement; // or behavior of the user should have this property.
RegisterOverlayProperty(prefs::kBrowserWindowPlacement);
} }
...@@ -8,62 +8,13 @@ ...@@ -8,62 +8,13 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "chrome/browser/prefs/overlay_user_pref_store.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 class IncognitoUserPrefStore : public OverlayUserPrefStore {
// 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 {
public: public:
explicit IncognitoUserPrefStore(PersistentPrefStore* underlay); 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: 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); 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_
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/prefs/incognito_user_pref_store.h" #include "chrome/browser/prefs/overlay_user_pref_store.h"
#include "chrome/browser/prefs/testing_pref_store.h" #include "chrome/browser/prefs/testing_pref_store.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/common/pref_store_observer_mock.h" #include "chrome/common/pref_store_observer_mock.h"
...@@ -15,152 +15,144 @@ using ::testing::StrEq; ...@@ -15,152 +15,144 @@ using ::testing::StrEq;
namespace { namespace {
const char* incognito_key = prefs::kBrowserWindowPlacement; const char* overlay_key = prefs::kBrowserWindowPlacement;
const char* regular_key = prefs::kShowBookmarkBar; const char* regular_key = prefs::kShowBookmarkBar;
// There is no real-life sense in mapping these two properties, it for test
// purposes only.
const char* mapped_overlay_key = prefs::kWebKitJavascriptEnabled;
const char* mapped_underlay_key = prefs::kWebKitJavaEnabled;
} // namespace } // namespace
class IncognitoUserPrefStoreTest : public testing::Test { class OverlayUserPrefStoreTest : public testing::Test {
public: protected:
IncognitoUserPrefStoreTest() OverlayUserPrefStoreTest()
: underlay_(new TestingPrefStore()), : underlay_(new TestingPrefStore()),
overlay_(new IncognitoUserPrefStore(underlay_.get())) { overlay_(new OverlayUserPrefStore(underlay_.get())) {
overlay_->RegisterOverlayProperty(overlay_key);
overlay_->RegisterOverlayProperty(mapped_overlay_key, mapped_underlay_key);
} }
virtual ~IncognitoUserPrefStoreTest() {} virtual ~OverlayUserPrefStoreTest() {}
scoped_refptr<TestingPrefStore> underlay_; scoped_refptr<TestingPrefStore> underlay_;
scoped_refptr<IncognitoUserPrefStore> overlay_; scoped_refptr<OverlayUserPrefStore> overlay_;
}; };
TEST_F(IncognitoUserPrefStoreTest, Observer) { TEST_F(OverlayUserPrefStoreTest, Observer) {
PrefStoreObserverMock obs; PrefStoreObserverMock obs;
overlay_->AddObserver(&obs); overlay_->AddObserver(&obs);
// Check that underlay first value is reported. // Check that underlay first value is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(1);
underlay_->SetValue(incognito_key, Value::CreateIntegerValue(42)); underlay_->SetValue(overlay_key, Value::CreateIntegerValue(42));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
// Check that underlay overwriting is reported. // Check that underlay overwriting is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(1);
underlay_->SetValue(incognito_key, Value::CreateIntegerValue(43)); underlay_->SetValue(overlay_key, Value::CreateIntegerValue(43));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
// Check that overwriting change in overlay is reported. // Check that overwriting change in overlay is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(1);
overlay_->SetValue(incognito_key, Value::CreateIntegerValue(44)); overlay_->SetValue(overlay_key, Value::CreateIntegerValue(44));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
// Check that hidden underlay change is not reported. // Check that hidden underlay change is not reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(0); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(0);
underlay_->SetValue(incognito_key, Value::CreateIntegerValue(45)); underlay_->SetValue(overlay_key, Value::CreateIntegerValue(45));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
// Check that overlay remove is reported. // Check that overlay remove is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(1);
overlay_->RemoveValue(incognito_key); overlay_->RemoveValue(overlay_key);
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
// Check that underlay remove is reported. // Check that underlay remove is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(1);
underlay_->RemoveValue(incognito_key); underlay_->RemoveValue(overlay_key);
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
// Check respecting of silence. // Check respecting of silence.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(0); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(0);
overlay_->SetValueSilently(incognito_key, Value::CreateIntegerValue(46)); overlay_->SetValueSilently(overlay_key, Value::CreateIntegerValue(46));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
overlay_->RemoveObserver(&obs); overlay_->RemoveObserver(&obs);
// Check successful unsubscription. // Check successful unsubscription.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(incognito_key))).Times(0); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(overlay_key))).Times(0);
underlay_->SetValue(incognito_key, Value::CreateIntegerValue(47)); underlay_->SetValue(overlay_key, Value::CreateIntegerValue(47));
overlay_->SetValue(incognito_key, Value::CreateIntegerValue(48)); overlay_->SetValue(overlay_key, Value::CreateIntegerValue(48));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
} }
TEST_F(IncognitoUserPrefStoreTest, GetAndSet) { TEST_F(OverlayUserPrefStoreTest, GetAndSet) {
const Value* value = NULL; const Value* value = NULL;
int i = -1;
EXPECT_EQ(PrefStore::READ_NO_VALUE, EXPECT_EQ(PrefStore::READ_NO_VALUE,
overlay_->GetValue(incognito_key, &value)); overlay_->GetValue(overlay_key, &value));
EXPECT_EQ(PrefStore::READ_NO_VALUE, EXPECT_EQ(PrefStore::READ_NO_VALUE,
underlay_->GetValue(incognito_key, &value)); underlay_->GetValue(overlay_key, &value));
underlay_->SetValue(incognito_key, Value::CreateIntegerValue(42)); underlay_->SetValue(overlay_key, Value::CreateIntegerValue(42));
// Value shines through: // Value shines through:
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(incognito_key, &value)); EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(overlay_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(42, i);
EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(incognito_key, &value)); EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(overlay_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(42, i);
overlay_->SetValue(incognito_key, Value::CreateIntegerValue(43)); overlay_->SetValue(overlay_key, Value::CreateIntegerValue(43));
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(incognito_key, &value)); EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(overlay_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(43, i);
EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(incognito_key, &value)); EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(overlay_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(42, i);
overlay_->RemoveValue(incognito_key); overlay_->RemoveValue(overlay_key);
// Value shines through: // Value shines through:
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(incognito_key, &value)); EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(overlay_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(42, i); EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(overlay_key, &value));
EXPECT_TRUE(base::FundamentalValue(42).Equals(value));
EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(incognito_key, &value));
ASSERT_TRUE(value);
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(42, i);
} }
// Check that GetMutableValue does not return the dictionary of the underlay. // Check that GetMutableValue does not return the dictionary of the underlay.
TEST_F(IncognitoUserPrefStoreTest, ModifyDictionaries) { TEST_F(OverlayUserPrefStoreTest, ModifyDictionaries) {
underlay_->SetValue(incognito_key, new DictionaryValue); underlay_->SetValue(overlay_key, new DictionaryValue);
Value* modify = NULL; Value* modify = NULL;
EXPECT_EQ(PrefStore::READ_OK, EXPECT_EQ(PrefStore::READ_OK,
overlay_->GetMutableValue(incognito_key, &modify)); overlay_->GetMutableValue(overlay_key, &modify));
ASSERT_TRUE(modify); ASSERT_TRUE(modify);
ASSERT_TRUE(modify->GetType() == Value::TYPE_DICTIONARY); ASSERT_TRUE(modify->IsType(Value::TYPE_DICTIONARY));
static_cast<DictionaryValue*>(modify)->SetInteger(incognito_key, 42); static_cast<DictionaryValue*>(modify)->SetInteger(overlay_key, 42);
Value* original_in_underlay = NULL; Value* original_in_underlay = NULL;
EXPECT_EQ(PrefStore::READ_OK, EXPECT_EQ(PrefStore::READ_OK,
underlay_->GetMutableValue(incognito_key, &original_in_underlay)); underlay_->GetMutableValue(overlay_key, &original_in_underlay));
ASSERT_TRUE(original_in_underlay); ASSERT_TRUE(original_in_underlay);
ASSERT_TRUE(original_in_underlay->GetType() == Value::TYPE_DICTIONARY); ASSERT_TRUE(original_in_underlay->IsType(Value::TYPE_DICTIONARY));
EXPECT_TRUE(static_cast<DictionaryValue*>(original_in_underlay)->empty()); EXPECT_TRUE(static_cast<DictionaryValue*>(original_in_underlay)->empty());
Value* modified = NULL; Value* modified = NULL;
EXPECT_EQ(PrefStore::READ_OK, EXPECT_EQ(PrefStore::READ_OK,
overlay_->GetMutableValue(incognito_key, &modified)); overlay_->GetMutableValue(overlay_key, &modified));
ASSERT_TRUE(modified); ASSERT_TRUE(modified);
ASSERT_TRUE(modified->GetType() == Value::TYPE_DICTIONARY); ASSERT_TRUE(modified->IsType(Value::TYPE_DICTIONARY));
EXPECT_TRUE(Value::Equals(modify, static_cast<DictionaryValue*>(modified))); EXPECT_TRUE(Value::Equals(modify, static_cast<DictionaryValue*>(modified)));
} }
// Here we consider a global preference that is not incognito specific. // Here we consider a global preference that is not overlayed.
TEST_F(IncognitoUserPrefStoreTest, GlobalPref) { TEST_F(OverlayUserPrefStoreTest, GlobalPref) {
PrefStoreObserverMock obs; PrefStoreObserverMock obs;
overlay_->AddObserver(&obs); overlay_->AddObserver(&obs);
const Value* value = NULL; const Value* value = NULL;
int i = -1;
// Check that underlay first value is reported. // Check that underlay first value is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(regular_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(regular_key))).Times(1);
...@@ -174,9 +166,7 @@ TEST_F(IncognitoUserPrefStoreTest, GlobalPref) { ...@@ -174,9 +166,7 @@ TEST_F(IncognitoUserPrefStoreTest, GlobalPref) {
// Check that we get this value from the overlay // Check that we get this value from the overlay
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(regular_key, &value)); EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(regular_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(43, i);
// Check that overwriting change in overlay is reported. // Check that overwriting change in overlay is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(regular_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(regular_key))).Times(1);
...@@ -185,13 +175,9 @@ TEST_F(IncognitoUserPrefStoreTest, GlobalPref) { ...@@ -185,13 +175,9 @@ TEST_F(IncognitoUserPrefStoreTest, GlobalPref) {
// Check that we get this value from the overlay and the underlay. // Check that we get this value from the overlay and the underlay.
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(regular_key, &value)); EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(regular_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(44).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(44, i);
EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(regular_key, &value)); EXPECT_EQ(PrefStore::READ_OK, underlay_->GetValue(regular_key, &value));
ASSERT_TRUE(value); EXPECT_TRUE(base::FundamentalValue(44).Equals(value));
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(44, i);
// Check that overlay remove is reported. // Check that overlay remove is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(regular_key))).Times(1); EXPECT_CALL(obs, OnPrefValueChanged(StrEq(regular_key))).Times(1);
...@@ -215,3 +201,82 @@ TEST_F(IncognitoUserPrefStoreTest, GlobalPref) { ...@@ -215,3 +201,82 @@ TEST_F(IncognitoUserPrefStoreTest, GlobalPref) {
overlay_->SetValue(regular_key, Value::CreateIntegerValue(48)); overlay_->SetValue(regular_key, Value::CreateIntegerValue(48));
Mock::VerifyAndClearExpectations(&obs); Mock::VerifyAndClearExpectations(&obs);
} }
// Check that names mapping works correctly.
TEST_F(OverlayUserPrefStoreTest, NamesMapping) {
PrefStoreObserverMock obs;
overlay_->AddObserver(&obs);
const Value* value = NULL;
// Check that if there is no override in the overlay, changing underlay value
// is reported as changing an overlay value.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(1);
underlay_->SetValue(mapped_underlay_key, Value::CreateIntegerValue(42));
Mock::VerifyAndClearExpectations(&obs);
// Check that underlay overwriting is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(1);
underlay_->SetValue(mapped_underlay_key, Value::CreateIntegerValue(43));
Mock::VerifyAndClearExpectations(&obs);
// Check that we get this value from the overlay with both keys
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(mapped_overlay_key, &value));
EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
// In this case, overlay reads directly from the underlay.
EXPECT_EQ(PrefStore::READ_OK,
overlay_->GetValue(mapped_underlay_key, &value));
EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
// Check that overwriting change in overlay is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(1);
overlay_->SetValue(mapped_overlay_key, Value::CreateIntegerValue(44));
Mock::VerifyAndClearExpectations(&obs);
// Check that we get an overriden value from overlay, while reading the
// value from underlay still holds an old value.
EXPECT_EQ(PrefStore::READ_OK, overlay_->GetValue(mapped_overlay_key, &value));
EXPECT_TRUE(base::FundamentalValue(44).Equals(value));
EXPECT_EQ(PrefStore::READ_OK,
overlay_->GetValue(mapped_underlay_key, &value));
EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
EXPECT_EQ(PrefStore::READ_OK,
underlay_->GetValue(mapped_underlay_key, &value));
EXPECT_TRUE(base::FundamentalValue(43).Equals(value));
// Check that hidden underlay change is not reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(0);
underlay_->SetValue(mapped_underlay_key, Value::CreateIntegerValue(45));
Mock::VerifyAndClearExpectations(&obs);
// Check that overlay remove is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(1);
overlay_->RemoveValue(mapped_overlay_key);
Mock::VerifyAndClearExpectations(&obs);
// Check that underlay remove is reported.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(1);
underlay_->RemoveValue(mapped_underlay_key);
Mock::VerifyAndClearExpectations(&obs);
// Check that value was removed.
EXPECT_EQ(PrefStore::READ_NO_VALUE,
overlay_->GetValue(mapped_overlay_key, &value));
EXPECT_EQ(PrefStore::READ_NO_VALUE,
overlay_->GetValue(mapped_underlay_key, &value));
// Check respecting of silence.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(0);
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_underlay_key))).Times(0);
overlay_->SetValueSilently(mapped_overlay_key, Value::CreateIntegerValue(46));
Mock::VerifyAndClearExpectations(&obs);
overlay_->RemoveObserver(&obs);
// Check successful unsubscription.
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_overlay_key))).Times(0);
EXPECT_CALL(obs, OnPrefValueChanged(StrEq(mapped_underlay_key))).Times(0);
underlay_->SetValue(mapped_underlay_key, Value::CreateIntegerValue(47));
overlay_->SetValue(mapped_overlay_key, Value::CreateIntegerValue(48));
Mock::VerifyAndClearExpectations(&obs);
}
...@@ -1827,6 +1827,8 @@ ...@@ -1827,6 +1827,8 @@
'browser/prefs/incognito_mode_prefs.h', 'browser/prefs/incognito_mode_prefs.h',
'browser/prefs/incognito_user_pref_store.cc', 'browser/prefs/incognito_user_pref_store.cc',
'browser/prefs/incognito_user_pref_store.h', '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.cc',
'browser/prefs/pref_change_registrar.h', 'browser/prefs/pref_change_registrar.h',
'browser/prefs/pref_member.cc', 'browser/prefs/pref_member.cc',
......
...@@ -1503,7 +1503,7 @@ ...@@ -1503,7 +1503,7 @@
'browser/preferences_mock_mac.h', 'browser/preferences_mock_mac.h',
'browser/prefs/command_line_pref_store_unittest.cc', 'browser/prefs/command_line_pref_store_unittest.cc',
'browser/prefs/incognito_mode_prefs_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_change_registrar_unittest.cc',
'browser/prefs/pref_member_unittest.cc', 'browser/prefs/pref_member_unittest.cc',
'browser/prefs/pref_model_associator_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