diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-25 21:45:51 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-25 21:45:51 +0000 |
commit | 9783c1681d454d42217f81086d07e20327c068ce (patch) | |
tree | 306ae1cd1fa69ecdf60c28dbbb692b458a1c90ab /chrome/browser/extensions | |
parent | edee3faf1cbf22b074a0c95304a37d22246ccf32 (diff) | |
download | chromium_src-9783c1681d454d42217f81086d07e20327c068ce.zip chromium_src-9783c1681d454d42217f81086d07e20327c068ce.tar.gz chromium_src-9783c1681d454d42217f81086d07e20327c068ce.tar.bz2 |
Support persistent incognito preferences
BUG=no
TEST=no
Review URL: http://codereview.chromium.org/7065033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86713 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
10 files changed, 259 insertions, 128 deletions
diff --git a/chrome/browser/extensions/extension_content_settings_apitest.cc b/chrome/browser/extensions/extension_content_settings_apitest.cc index db3d481..f16fdff 100644 --- a/chrome/browser/extensions/extension_content_settings_apitest.cc +++ b/chrome/browser/extensions/extension_content_settings_apitest.cc @@ -40,8 +40,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoContentSettings) { // Setting an incognito preference should not create an incognito profile. EXPECT_FALSE(browser()->profile()->HasOffTheRecordProfile()); - // TODO(battre): re-enable when incognito is available again. -#if 0 PrefService* otr_prefs = browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); const PrefService::Preference* pref = @@ -54,7 +52,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoContentSettings) { ASSERT_TRUE(pref); EXPECT_FALSE(pref->IsExtensionControlled()); EXPECT_FALSE(prefs->GetBoolean(prefs::kBlockThirdPartyCookies)); -#endif } IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoDisabledContentSettings) { diff --git a/chrome/browser/extensions/extension_pref_value_map.cc b/chrome/browser/extensions/extension_pref_value_map.cc index 7032be9..5b0b5ee 100644 --- a/chrome/browser/extensions/extension_pref_value_map.cc +++ b/chrome/browser/extensions/extension_pref_value_map.cc @@ -13,10 +13,11 @@ struct ExtensionPrefValueMap::ExtensionEntry { base::Time install_time; // Whether extension is enabled in the profile. bool enabled; - // Regular preferences. - PrefValueMap reg_preferences; - // Incognito preferences, empty for regular ExtensionPrefStore. - PrefValueMap inc_preferences; + // Extension controlled preferences for the regular profile. + PrefValueMap regular_profile_preferences; + // Persistent extension controlled preferences for the incognito profile, + // empty for regular profile ExtensionPrefStore. + PrefValueMap incognito_profile_preferences_persistent; }; ExtensionPrefValueMap::ExtensionPrefValueMap() { @@ -30,18 +31,19 @@ ExtensionPrefValueMap::~ExtensionPrefValueMap() { void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id, const std::string& key, - bool incognito, + extension_prefs_scope::Scope scope, Value* value) { - PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito); + PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope); if (prefs->SetValue(key, value)) NotifyPrefValueChanged(key); } -void ExtensionPrefValueMap::RemoveExtensionPref(const std::string& ext_id, - const std::string& key, - bool incognito) { - PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito); +void ExtensionPrefValueMap::RemoveExtensionPref( + const std::string& ext_id, + const std::string& key, + extension_prefs_scope::Scope scope) { + PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope); if (prefs->RemoveValue(key)) NotifyPrefValueChanged(key); } @@ -115,20 +117,32 @@ void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id, PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap( const std::string& ext_id, - bool incognito) { + extension_prefs_scope::Scope scope) { ExtensionEntryMap::const_iterator i = entries_.find(ext_id); CHECK(i != entries_.end()); - return incognito ? &(i->second->inc_preferences) - : &(i->second->reg_preferences); + switch (scope) { + case extension_prefs_scope::kRegular: + return &(i->second->regular_profile_preferences); + case extension_prefs_scope::kIncognitoPersistent: + return &(i->second->incognito_profile_preferences_persistent); + } + NOTREACHED(); + return NULL; } const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap( const std::string& ext_id, - bool incognito) const { + extension_prefs_scope::Scope scope) const { ExtensionEntryMap::const_iterator i = entries_.find(ext_id); CHECK(i != entries_.end()); - return incognito ? &(i->second->inc_preferences) - : &(i->second->reg_preferences); + switch (scope) { + case extension_prefs_scope::kRegular: + return &(i->second->regular_profile_preferences); + case extension_prefs_scope::kIncognitoPersistent: + return &(i->second->incognito_profile_preferences_persistent); + } + NOTREACHED(); + return NULL; } void ExtensionPrefValueMap::GetExtensionControlledKeys( @@ -136,12 +150,13 @@ void ExtensionPrefValueMap::GetExtensionControlledKeys( std::set<std::string>* out) const { PrefValueMap::const_iterator i; - const PrefValueMap& reg_prefs = entry.reg_preferences; + const PrefValueMap& reg_prefs = entry.regular_profile_preferences; for (i = reg_prefs.begin(); i != reg_prefs.end(); ++i) out->insert(i->first); - const PrefValueMap& inc_prefs = entry.inc_preferences; - for (i = inc_prefs.begin(); i != inc_prefs.end(); ++i) + const PrefValueMap& inc_prefs_pers = + entry.incognito_profile_preferences_persistent; + for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i) out->insert(i->first); } @@ -156,10 +171,16 @@ const Value* ExtensionPrefValueMap::GetEffectivePrefValue( const Value* value = NULL; const std::string& ext_id = winner->first; - if (incognito) - GetExtensionPrefValueMap(ext_id, true)->GetValue(key, &value); - if (!value) - GetExtensionPrefValueMap(ext_id, false)->GetValue(key, &value); + if (incognito) { + const PrefValueMap* prefs = GetExtensionPrefValueMap( + ext_id, extension_prefs_scope::kIncognitoPersistent); + prefs->GetValue(key, &value); + } + if (!value) { + const PrefValueMap* prefs = GetExtensionPrefValueMap( + ext_id, extension_prefs_scope::kRegular); + prefs->GetValue(key, &value); + } return value; } @@ -183,7 +204,8 @@ ExtensionPrefValueMap::GetEffectivePrefValueController( continue; const Value* value = NULL; - const PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, false); + const PrefValueMap* prefs = GetExtensionPrefValueMap( + ext_id, extension_prefs_scope::kRegular); if (prefs->GetValue(key, &value)) { winner = i; winners_install_time = install_time; @@ -194,7 +216,8 @@ ExtensionPrefValueMap::GetEffectivePrefValueController( if (!incognito) continue; - prefs = GetExtensionPrefValueMap(ext_id, true); + prefs = GetExtensionPrefValueMap( + ext_id, extension_prefs_scope::kIncognitoPersistent); if (prefs->GetValue(key, &value)) { winner = i; winners_install_time = install_time; diff --git a/chrome/browser/extensions/extension_pref_value_map.h b/chrome/browser/extensions/extension_pref_value_map.h index 6a8d2eb..8b4db03 100644 --- a/chrome/browser/extensions/extension_pref_value_map.h +++ b/chrome/browser/extensions/extension_pref_value_map.h @@ -12,6 +12,7 @@ #include "base/time.h" #include "chrome/browser/prefs/value_map_pref_store.h" +#include "chrome/browser/extensions/extension_prefs_scope.h" // Non-persistent data container that is shared by ExtensionPrefStores. All // extension pref values (incognito and regular) are stored herein and @@ -70,14 +71,14 @@ class ExtensionPrefValueMap { // Precondition: the extension must be registered. void SetExtensionPref(const std::string& ext_id, const std::string& key, - bool incognito, + extension_prefs_scope::Scope scope, Value* value); // Remove the extension preference value for |key| of extension |ext_id|. // Precondition: the extension must be registered. void RemoveExtensionPref(const std::string& ext_id, const std::string& key, - bool incognito); + extension_prefs_scope::Scope scope); // Returns true if currently no extension with higher precedence controls the // preference. @@ -127,11 +128,13 @@ class ExtensionPrefValueMap { typedef std::map<std::string, ExtensionEntry*> ExtensionEntryMap; - const PrefValueMap* GetExtensionPrefValueMap(const std::string& ext_id, - bool incognito) const; + const PrefValueMap* GetExtensionPrefValueMap( + const std::string& ext_id, + extension_prefs_scope::Scope scope) const; - PrefValueMap* GetExtensionPrefValueMap(const std::string& ext_id, - bool incognito); + PrefValueMap* GetExtensionPrefValueMap( + const std::string& ext_id, + extension_prefs_scope::Scope scope); // Returns all keys of pref values that are set by the extension of |entry|, // regardless whether they are set for incognito or regular pref values. diff --git a/chrome/browser/extensions/extension_pref_value_map_unittest.cc b/chrome/browser/extensions/extension_pref_value_map_unittest.cc index 75af385..d4ac026 100644 --- a/chrome/browser/extensions/extension_pref_value_map_unittest.cc +++ b/chrome/browser/extensions/extension_pref_value_map_unittest.cc @@ -66,8 +66,9 @@ class ExtensionPrefValueMapObserverMock }; TEST_F(ExtensionPrefValueMapTest, SetAndGetPrefValue) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); EXPECT_EQ("val1", GetValue(kPref1, false)); }; @@ -78,20 +79,21 @@ TEST_F(ExtensionPrefValueMapTest, GetNotSetPrefValue) { // Make sure the last-installed extension wins for each preference. TEST_F(ExtensionPrefValueMapTest, Override) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); epvm_.RegisterExtension(kExt2, CreateTime(20), true); epvm_.RegisterExtension(kExt3, CreateTime(30), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); - epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2")); - epvm_.SetExtensionPref(kExt3, kPref1, false, CreateVal("val3")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); + epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2")); + epvm_.SetExtensionPref(kExt3, kPref1, kRegular, CreateVal("val3")); - epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val4")); - epvm_.SetExtensionPref(kExt2, kPref2, false, CreateVal("val5")); + epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val4")); + epvm_.SetExtensionPref(kExt2, kPref2, kRegular, CreateVal("val5")); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val6")); - epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val7")); - epvm_.SetExtensionPref(kExt1, kPref3, false, CreateVal("val8")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val6")); + epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val7")); + epvm_.SetExtensionPref(kExt1, kPref3, kRegular, CreateVal("val8")); EXPECT_EQ("val3", GetValue(kPref1, false)); EXPECT_EQ("val5", GetValue(kPref2, false)); @@ -99,6 +101,7 @@ TEST_F(ExtensionPrefValueMapTest, Override) { } TEST_F(ExtensionPrefValueMapTest, OverrideChecks) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); epvm_.RegisterExtension(kExt2, CreateTime(20), true); epvm_.RegisterExtension(kExt3, CreateTime(30), true); @@ -110,7 +113,7 @@ TEST_F(ExtensionPrefValueMapTest, OverrideChecks) { EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt2, kPref1, false)); EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt3, kPref1, false)); - epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val1")); EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt1, kPref1, false)); EXPECT_TRUE(epvm_.DoesExtensionControlPref(kExt2, kPref1, false)); @@ -121,14 +124,16 @@ TEST_F(ExtensionPrefValueMapTest, OverrideChecks) { } TEST_F(ExtensionPrefValueMapTest, SetAndGetPrefValueIncognito) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); EXPECT_EQ("val1", GetValue(kPref1, true)); } TEST_F(ExtensionPrefValueMapTest, UninstallOnlyExtension) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); epvm_.UnregisterExtension(kExt1); EXPECT_EQ("", GetValue(kPref1, false)); @@ -136,14 +141,15 @@ TEST_F(ExtensionPrefValueMapTest, UninstallOnlyExtension) { // Tests uninstalling an extension that wasn't winning for any preferences. TEST_F(ExtensionPrefValueMapTest, UninstallIrrelevantExtension) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); epvm_.RegisterExtension(kExt2, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); - epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); + epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2")); - epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val3")); - epvm_.SetExtensionPref(kExt2, kPref2, false, CreateVal("val4")); + epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val3")); + epvm_.SetExtensionPref(kExt2, kPref2, kRegular, CreateVal("val4")); epvm_.UnregisterExtension(kExt1); @@ -153,16 +159,17 @@ TEST_F(ExtensionPrefValueMapTest, UninstallIrrelevantExtension) { // Tests uninstalling an extension that was winning for all preferences. TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromTop) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); epvm_.RegisterExtension(kExt2, CreateTime(20), true); epvm_.RegisterExtension(kExt3, CreateTime(30), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); - epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2")); - epvm_.SetExtensionPref(kExt3, kPref1, false, CreateVal("val3")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); + epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2")); + epvm_.SetExtensionPref(kExt3, kPref1, kRegular, CreateVal("val3")); - epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val4")); - epvm_.SetExtensionPref(kExt3, kPref2, false, CreateVal("val5")); + epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val4")); + epvm_.SetExtensionPref(kExt3, kPref2, kRegular, CreateVal("val5")); epvm_.UnregisterExtension(kExt3); @@ -172,20 +179,21 @@ TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromTop) { // Tests uninstalling an extension that was winning for only some preferences. TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromMiddle) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); epvm_.RegisterExtension(kExt2, CreateTime(20), true); epvm_.RegisterExtension(kExt3, CreateTime(30), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); - epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2")); - epvm_.SetExtensionPref(kExt3, kPref1, false, CreateVal("val3")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); + epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2")); + epvm_.SetExtensionPref(kExt3, kPref1, kRegular, CreateVal("val3")); - epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val4")); - epvm_.SetExtensionPref(kExt2, kPref2, false, CreateVal("val5")); + epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val4")); + epvm_.SetExtensionPref(kExt2, kPref2, kRegular, CreateVal("val5")); - epvm_.SetExtensionPref(kExt1, kPref3, false, CreateVal("val6")); + epvm_.SetExtensionPref(kExt1, kPref3, kRegular, CreateVal("val6")); - epvm_.SetExtensionPref(kExt2, kPref4, false, CreateVal("val7")); + epvm_.SetExtensionPref(kExt2, kPref4, kRegular, CreateVal("val7")); epvm_.UnregisterExtension(kExt2); @@ -200,6 +208,7 @@ TEST_F(ExtensionPrefValueMapTest, NotifyWhenNeeded) { using testing::_; using testing::Mock; using testing::StrEq; + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); @@ -207,22 +216,22 @@ TEST_F(ExtensionPrefValueMapTest, NotifyWhenNeeded) { epvm_.AddObserver(&observer); EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); Mock::VerifyAndClearExpectations(&observer); // Write the same value again. EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))).Times(0); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); Mock::VerifyAndClearExpectations(&observer); // Override incognito value. EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))); - epvm_.SetExtensionPref(kExt1, kPref1, true, CreateVal("val2")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val2")); Mock::VerifyAndClearExpectations(&observer); // Override non-incognito value. EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val3")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val3")); Mock::VerifyAndClearExpectations(&observer); // Disable. @@ -245,24 +254,26 @@ TEST_F(ExtensionPrefValueMapTest, NotifyWhenNeeded) { // Write new value --> no notification after removing observer. EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))).Times(0); epvm_.RegisterExtension(kExt1, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val4")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val4")); Mock::VerifyAndClearExpectations(&observer); } // Tests disabling an extension. TEST_F(ExtensionPrefValueMapTest, DisableExt) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); epvm_.SetExtensionState(kExt1, false); EXPECT_EQ("", GetValue(kPref1, false)); } // Tests disabling and reenabling an extension. TEST_F(ExtensionPrefValueMapTest, ReenableExt) { + using namespace extension_prefs_scope; epvm_.RegisterExtension(kExt1, CreateTime(10), true); - epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1")); + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1")); epvm_.SetExtensionState(kExt1, false); epvm_.SetExtensionState(kExt1, true); EXPECT_EQ("val1", GetValue(kPref1, false)); @@ -296,6 +307,7 @@ class ExtensionPrefValueMapTestIncognitoTests }; TEST_P(ExtensionPrefValueMapTestIncognitoTests, OverrideIncognito) { + using namespace extension_prefs_scope; OverrideIncognitoTestCase test = GetParam(); const char* strings[] = { "undefined", @@ -308,19 +320,19 @@ TEST_P(ExtensionPrefValueMapTestIncognitoTests, OverrideIncognito) { epvm_.RegisterExtension(kExt1, CreateTime(10), true); epvm_.RegisterExtension(kExt2, CreateTime(20), true); if (test.val_ext1_regular_) { - epvm_.SetExtensionPref(kExt1, kPref1, false, + epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal(strings[test.val_ext1_regular_])); } if (test.val_ext1_incognito_) { - epvm_.SetExtensionPref(kExt1, kPref1, true, + epvm_.SetExtensionPref(kExt1, kPref1, kIncognitoPersistent, CreateVal(strings[test.val_ext1_incognito_])); } if (test.val_ext2_regular_) { - epvm_.SetExtensionPref(kExt2, kPref1, false, + epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal(strings[test.val_ext2_regular_])); } if (test.val_ext2_incognito_) { - epvm_.SetExtensionPref(kExt2, kPref1, true, + epvm_.SetExtensionPref(kExt2, kPref1, kIncognitoPersistent, CreateVal(strings[test.val_ext2_incognito_])); } std::string actual; diff --git a/chrome/browser/extensions/extension_preference_api.cc b/chrome/browser/extensions/extension_preference_api.cc index 4b57a12..3dcde37 100644 --- a/chrome/browser/extensions/extension_preference_api.cc +++ b/chrome/browser/extensions/extension_preference_api.cc @@ -13,6 +13,7 @@ #include "base/values.h" #include "chrome/browser/extensions/extension_event_router.h" #include "chrome/browser/extensions/extension_prefs.h" +#include "chrome/browser/extensions/extension_prefs_scope.h" #include "chrome/browser/extensions/extension_proxy_api.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" @@ -35,7 +36,10 @@ const char kControlledByThisExtension[] = "ControlledByThisExtension"; const char kIncognito[] = "incognito"; const char kIncognitoSpecific[] = "incognitoSpecific"; +const char kScope[] = "scope"; const char kLevelOfControl[] = "levelOfControl"; +const char kRegular[] = "regular"; +const char kIncognitoPersistent[] = "incognito_persistent"; const char kValue[] = "value"; const char kOnPrefChangeFormat[] = @@ -109,6 +113,16 @@ const char* GetLevelOfControl( return kControlledByOtherExtensions; } +bool StringToScope(const std::string& s, extension_prefs_scope::Scope* scope) { + if (s == kRegular) + *scope = extension_prefs_scope::kRegular; + else if (s == kIncognitoPersistent) + *scope = extension_prefs_scope::kIncognitoPersistent; + else + return false; + return true; +} + class PrefMapping { public: static PrefMapping* GetInstance() { @@ -346,15 +360,28 @@ bool SetPreferenceFunction::RunImpl() { Value* value = NULL; EXTENSION_FUNCTION_VALIDATE(details->Get(kValue, &value)); - bool incognito = false; + std::string scope_str = kRegular; + if (details->HasKey(kScope)) + EXTENSION_FUNCTION_VALIDATE(details->GetString(kScope, &scope_str)); - // TODO(battre): enable incognito preferences again. - // if (details->HasKey(kIncognito)) - // EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(kIncognito, &incognito)); + extension_prefs_scope::Scope scope; + EXTENSION_FUNCTION_VALIDATE(StringToScope(scope_str, &scope)); - if (incognito && !include_incognito()) { - error_ = kIncognitoErrorMessage; - return false; + // TODO(battre): add kIncognitoSessionOnly + bool incognito = (scope == extension_prefs_scope::kIncognitoPersistent); + if (incognito) { + // Regular profiles can't access incognito unless include_incognito is true. + if (!profile()->IsOffTheRecord() && !include_incognito()) { + error_ = kIncognitoErrorMessage; + return false; + } + } else { + // Incognito profiles can't access regular mode ever, they only exist in + // split mode. + if (profile()->IsOffTheRecord()) { + error_ = "Can't modify regular settings from an incognito context."; + return false; + } } std::string browser_pref; @@ -384,7 +411,7 @@ bool SetPreferenceFunction::RunImpl() { } prefs->SetExtensionControlledPref(extension_id(), browser_pref, - incognito, + scope, browserPrefValue); return true; } @@ -397,14 +424,26 @@ bool ClearPreferenceFunction::RunImpl() { DictionaryValue* details = NULL; EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); - bool incognito = false; + std::string scope_str = kRegular; + if (details->HasKey(kScope)) + EXTENSION_FUNCTION_VALIDATE(details->GetString(kScope, &scope_str)); - // TODO(battre): enable incognito preferences again. - // if (details->HasKey(kIncognito)) - // EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(kIncognito, &incognito)); + extension_prefs_scope::Scope scope; + EXTENSION_FUNCTION_VALIDATE(StringToScope(scope_str, &scope)); - // We don't check incognito permissions here, as an extension should be always - // allowed to clear its own settings. + // TODO(battre): add kIncognitoSessionOnly + bool incognito = (scope == extension_prefs_scope::kIncognitoPersistent); + if (incognito) { + // We don't check incognito permissions here, as an extension should be + // always allowed to clear its own settings. + } else { + // Incognito profiles can't access regular mode ever, they only exist in + // split mode. + if (profile()->IsOffTheRecord()) { + error_ = "Can't modify regular settings from an incognito context."; + return false; + } + } std::string browser_pref; std::string permission; @@ -416,6 +455,6 @@ bool ClearPreferenceFunction::RunImpl() { return false; } ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); - prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, incognito); + prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); return true; } diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index 5529194..57cd52a 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -113,6 +113,9 @@ const char kPrefInstallTime[] = "install_time"; // A preference that contains any extension-controlled preferences. const char kPrefPreferences[] = "preferences"; +// A preference that contains any extension-controlled incognito preferences. +const char kPrefIncognitoPreferences[] = "incognito_preferences"; + // A preference that contains extension-set content settings. const char kPrefContentSettings[] = "content_settings"; @@ -150,11 +153,17 @@ class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate { // Provider of write access to a dictionary storing extension controlled prefs. class ScopedExtensionControlledPrefUpdate : public DictionaryPrefUpdate { public: - ScopedExtensionControlledPrefUpdate(PrefService* service, - const std::string& extension_id) : + // |incognito_or_regular_path| indicates the sub-path where the + // extension controlled preferences are stored. This has to be either + // kPrefPreferences or kPrefIncognitoPreferences. + ScopedExtensionControlledPrefUpdate( + PrefService* service, + const std::string& extension_id, + const std::string& incognito_or_regular_path) : DictionaryPrefUpdate(service, ExtensionPrefs::kExtensionsPref), prefs_(service), - extension_id_(extension_id) {} + extension_id_(extension_id), + incognito_or_regular_path_(incognito_or_regular_path) {} virtual ~ScopedExtensionControlledPrefUpdate() { prefs_->ScheduleSavePersistentPrefs(); @@ -163,7 +172,8 @@ class ScopedExtensionControlledPrefUpdate : public DictionaryPrefUpdate { virtual DictionaryValue* Get() { DictionaryValue* dict = DictionaryPrefUpdate::Get(); DictionaryValue* preferences = NULL; - std::string key = extension_id_ + std::string(".") + kPrefPreferences; + std::string key = + extension_id_ + std::string(".") + incognito_or_regular_path_; if (!dict->GetDictionary(key, &preferences)) { preferences = new DictionaryValue; dict->Set(key, preferences); @@ -174,6 +184,7 @@ class ScopedExtensionControlledPrefUpdate : public DictionaryPrefUpdate { private: PrefService* prefs_; const std::string extension_id_; + const std::string incognito_or_regular_path_; DISALLOW_COPY_AND_ASSIGN(ScopedExtensionControlledPrefUpdate); }; @@ -882,6 +893,7 @@ void ExtensionPrefs::OnExtensionInstalled( Value::CreateStringValue( base::Int64ToString(install_time.ToInternalValue()))); extension_dict->Set(kPrefPreferences, new DictionaryValue()); + extension_dict->Set(kPrefIncognitoPreferences, new DictionaryValue()); extension_dict->Set(kPrefContentSettings, new ListValue()); FilePath::StringType path = MakePathRelative(install_directory_, @@ -1374,8 +1386,10 @@ void ExtensionPrefs::FixMissingPrefs(const ExtensionIdSet& extension_ids) { } const DictionaryValue* ExtensionPrefs::GetExtensionControlledPrefs( - const std::string& extension_id) const { - std::string key = extension_id + std::string(".") + kPrefPreferences; + const std::string& extension_id, + bool incognito) const { + std::string key = extension_id + std::string(".") + + (incognito ? kPrefIncognitoPreferences : kPrefPreferences); DictionaryValue* preferences = NULL; // First try the regular lookup. const DictionaryValue* source_dict = prefs_->GetDictionary(kExtensionsPref); @@ -1417,14 +1431,27 @@ void ExtensionPrefs::InitPrefStore() { GetInstallTime(*ext_id), GetExtensionState(*ext_id) == Extension::ENABLED); - const DictionaryValue* prefs = GetExtensionControlledPrefs(*ext_id); + // Set regular extension controlled prefs. + const DictionaryValue* prefs = GetExtensionControlledPrefs(*ext_id, false); + for (DictionaryValue::key_iterator i = prefs->begin_keys(); + i != prefs->end_keys(); ++i) { + Value* value; + if (!prefs->GetWithoutPathExpansion(*i, &value)) + continue; + extension_pref_value_map_->SetExtensionPref( + *ext_id, *i, extension_prefs_scope::kRegular, value->DeepCopy()); + } + + // Set incognito extension controlled prefs. + prefs = GetExtensionControlledPrefs(*ext_id, true); for (DictionaryValue::key_iterator i = prefs->begin_keys(); i != prefs->end_keys(); ++i) { Value* value; if (!prefs->GetWithoutPathExpansion(*i, &value)) continue; extension_pref_value_map_->SetExtensionPref( - *ext_id, *i, false, value->DeepCopy()); + *ext_id, *i, extension_prefs_scope::kIncognitoPersistent, + value->DeepCopy()); } const DictionaryValue* extension_prefs = GetExtensionPref(*ext_id); @@ -1440,10 +1467,11 @@ void ExtensionPrefs::InitPrefStore() { } -void ExtensionPrefs::SetExtensionControlledPref(const std::string& extension_id, - const std::string& pref_key, - bool incognito, - Value* value) { +void ExtensionPrefs::SetExtensionControlledPref( + const std::string& extension_id, + const std::string& pref_key, + extension_prefs_scope::Scope scope, + Value* value) { #ifndef NDEBUG const PrefService::Preference* pref = pref_service()->FindPreference(pref_key.c_str()); @@ -1453,34 +1481,44 @@ void ExtensionPrefs::SetExtensionControlledPref(const std::string& extension_id, << "Extension controlled preference " << pref_key << " has wrong type."; #endif - if (!incognito) { + if (scope == extension_prefs_scope::kRegular) { // Also store in persisted Preferences file to recover after a // browser restart. - ScopedExtensionControlledPrefUpdate update(prefs_, extension_id); + ScopedExtensionControlledPrefUpdate update(prefs_, extension_id, + kPrefPreferences); + update->SetWithoutPathExpansion(pref_key, value->DeepCopy()); + } else if (scope == extension_prefs_scope::kIncognitoPersistent) { + ScopedExtensionControlledPrefUpdate update(prefs_, extension_id, + kPrefIncognitoPreferences); update->SetWithoutPathExpansion(pref_key, value->DeepCopy()); } extension_pref_value_map_->SetExtensionPref( - extension_id, pref_key, incognito, value); + extension_id, pref_key, scope, value); } void ExtensionPrefs::RemoveExtensionControlledPref( const std::string& extension_id, const std::string& pref_key, - bool incognito) { + extension_prefs_scope::Scope scope) { DCHECK(pref_service()->FindPreference(pref_key.c_str())) << "Extension controlled preference key " << pref_key << " not registered."; - if (!incognito) { + if (scope == extension_prefs_scope::kRegular) { // Also store in persisted Preferences file to recover after a // browser restart. - ScopedExtensionControlledPrefUpdate update(prefs_, extension_id); + ScopedExtensionControlledPrefUpdate update(prefs_, extension_id, + kPrefPreferences); + update->RemoveWithoutPathExpansion(pref_key, NULL); + } else if (scope == extension_prefs_scope::kIncognitoPersistent) { + ScopedExtensionControlledPrefUpdate update(prefs_, extension_id, + kPrefIncognitoPreferences); update->RemoveWithoutPathExpansion(pref_key, NULL); } extension_pref_value_map_->RemoveExtensionPref( - extension_id, pref_key, incognito); + extension_id, pref_key, scope); } bool ExtensionPrefs::CanExtensionControlPref(const std::string& extension_id, diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index 7414608..55e87a7 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -13,6 +13,7 @@ #include "base/memory/linked_ptr.h" #include "base/time.h" #include "chrome/browser/extensions/extension_content_settings_store.h" +#include "chrome/browser/extensions/extension_prefs_scope.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/common/extensions/extension.h" #include "googleurl/src/gurl.h" @@ -303,12 +304,12 @@ class ExtensionPrefs : public ExtensionContentSettingsStore::Observer { // Takes ownership of |value|. void SetExtensionControlledPref(const std::string& extension_id, const std::string& pref_key, - bool incognito, + extension_prefs_scope::Scope scope, Value* value); void RemoveExtensionControlledPref(const std::string& extension_id, const std::string& pref_key, - bool incognito); + extension_prefs_scope::Scope scope); // Returns true if currently no extension with higher precedence controls the // preference. @@ -415,7 +416,8 @@ class ExtensionPrefs : public ExtensionContentSettingsStore::Observer { // or creates a new one. All entries in the dictionary contain non-expanded // paths. const DictionaryValue* GetExtensionControlledPrefs( - const std::string& id) const; + const std::string& id, + bool incognito) const; // Serializes the data and schedules a persistent save via the |PrefService|. // TODO(andybons): Fire an EXTENSION_PREF_CHANGED notification to be more diff --git a/chrome/browser/extensions/extension_prefs_scope.h b/chrome/browser/extensions/extension_prefs_scope.h new file mode 100644 index 0000000..6447234 --- /dev/null +++ b/chrome/browser/extensions/extension_prefs_scope.h @@ -0,0 +1,25 @@ +// 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_EXTENSIONS_EXTENSION_PREFS_SCOPE_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREFS_SCOPE_H_ +#pragma once + +// TODO(battre): get rid of this namespace, see +// http://codereview.chromium.org/7065033/diff/3003/chrome/browser/extensions/extension_prefs_scope.h +namespace extension_prefs_scope { + +// Scope for a preference. +enum Scope { + // Regular profile. + kRegular, + // Incognito profile; preference is persisted to disk and remains active + // after a browser restart. + kIncognitoPersistent, + // TODO(battre): add kIncognitoSession +}; + +} // extension_prefs_scope + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PREFS_SCOPE_H_ diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc index 5b790d1..f386957 100644 --- a/chrome/browser/extensions/extension_prefs_unittest.cc +++ b/chrome/browser/extensions/extension_prefs_unittest.cc @@ -695,15 +695,18 @@ class ExtensionPrefsPreferencesBase : public ExtensionPrefsTest { void InstallExtControlledPref(Extension *ext, const std::string& key, Value* val) { + using namespace extension_prefs_scope; EnsureExtensionInstalled(ext); - prefs()->SetExtensionControlledPref(ext->id(), key, false, val); + prefs()->SetExtensionControlledPref(ext->id(), key, kRegular, val); } void InstallExtControlledPrefIncognito(Extension *ext, const std::string& key, Value* val) { + using namespace extension_prefs_scope; EnsureExtensionInstalled(ext); - prefs()->SetExtensionControlledPref(ext->id(), key, true, val); + prefs()->SetExtensionControlledPref(ext->id(), key, + kIncognitoPersistent, val); } void InstallExtension(Extension *ext) { @@ -763,12 +766,10 @@ class ExtensionPrefsInstallOneExtension }; TEST_F(ExtensionPrefsInstallOneExtension, ExtensionPrefsInstallOneExtension) {} -// Check that we forget incognito values after a reload. +// Check that we do not forget persistent incognito values after a reload. class ExtensionPrefsInstallIncognito : public ExtensionPrefsPreferencesBase { public: - ExtensionPrefsInstallIncognito() : iteration_(0) {} - virtual void Initialize() { InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1")); InstallExtControlledPrefIncognito(ext1_, kPref1, @@ -781,18 +782,11 @@ class ExtensionPrefsInstallIncognito // Main pref service shall see only non-incognito settings. std::string actual = prefs()->pref_service()->GetString(kPref1); EXPECT_EQ("val1", actual); - // Incognito pref service shall see incognito values only during first run. - // Once the pref service was reloaded, all values shall be discarded. + // Incognito pref service shall see incognito values. scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService()); actual = incog_prefs->GetString(kPref1); - if (iteration_ == 0) { - EXPECT_EQ("val2", actual); - } else { - EXPECT_EQ("val1", actual); - } - ++iteration_; + EXPECT_EQ("val2", actual); } - int iteration_; }; TEST_F(ExtensionPrefsInstallIncognito, ExtensionPrefsInstallOneExtension) {} diff --git a/chrome/browser/extensions/extension_proxy_apitest.cc b/chrome/browser/extensions/extension_proxy_apitest.cc index 7af1f4c..5280d64 100644 --- a/chrome/browser/extensions/extension_proxy_apitest.cc +++ b/chrome/browser/extensions/extension_proxy_apitest.cc @@ -169,9 +169,8 @@ IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedIndividual) { } // Tests setting values only for incognito mode -// TODO(battre): re-enable when incognito is supported again IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, - DISABLED_ProxyFixedIndividualIncognitoOnly) { + ProxyFixedIndividualIncognitoOnly) { ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual_incognito_only")) << message_; const Extension* extension = GetSingleLoadedExtension(); @@ -193,9 +192,8 @@ IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, } // Tests setting values also for incognito mode -// TODO(battre): re-enable when incognito is supported again IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, - DISABLED_ProxyFixedIndividualIncognitoAlso) { + ProxyFixedIndividualIncognitoAlso) { ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual_incognito_also")) << message_; const Extension* extension = GetSingleLoadedExtension(); |