summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_content_settings_apitest.cc34
-rw-r--r--chrome/browser/extensions/extension_pref_value_map.cc52
-rw-r--r--chrome/browser/extensions/extension_pref_value_map.h3
-rw-r--r--chrome/browser/extensions/extension_pref_value_map_unittest.cc65
-rw-r--r--chrome/browser/extensions/extension_preference_api.cc21
-rw-r--r--chrome/browser/extensions/extension_prefs_scope.h4
-rw-r--r--chrome/browser/extensions/extension_prefs_unittest.cc60
-rw-r--r--chrome/browser/profiles/profile_impl.cc1
-rw-r--r--chrome/common/extensions/api/extension_api.json8
-rw-r--r--chrome/common/extensions/docs/preferences.html8
-rw-r--r--chrome/test/data/extensions/api_test/content_settings/persistent_incognito/manifest.json (renamed from chrome/test/data/extensions/api_test/content_settings/incognito/manifest.json)0
-rw-r--r--chrome/test/data/extensions/api_test/content_settings/persistent_incognito/test.html (renamed from chrome/test/data/extensions/api_test/content_settings/incognito/test.html)2
-rw-r--r--chrome/test/data/extensions/api_test/content_settings/session_only_incognito/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/content_settings/session_only_incognito/test.html82
14 files changed, 306 insertions, 41 deletions
diff --git a/chrome/browser/extensions/extension_content_settings_apitest.cc b/chrome/browser/extensions/extension_content_settings_apitest.cc
index f16fdff..1ec6923 100644
--- a/chrome/browser/extensions/extension_content_settings_apitest.cc
+++ b/chrome/browser/extensions/extension_content_settings_apitest.cc
@@ -27,14 +27,15 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentSettings) {
EXPECT_TRUE(pref_service->GetBoolean(prefs::kEnableReferrers));
}
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoContentSettings) {
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PersistentIncognitoContentSettings) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(prefs::kBlockThirdPartyCookies, false);
- EXPECT_TRUE(RunExtensionTestIncognito("content_settings/incognito")) <<
+ EXPECT_TRUE(
+ RunExtensionTestIncognito("content_settings/persistent_incognito")) <<
message_;
// Setting an incognito preference should not create an incognito profile.
@@ -58,7 +59,34 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoDisabledContentSettings) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
- EXPECT_FALSE(RunExtensionTest("content_settings/incognito"));
+ EXPECT_FALSE(RunExtensionTest("content_settings/persistent_incognito"));
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SessionOnlyIncognitoContentSettings) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ PrefService* prefs = browser()->profile()->GetPrefs();
+ prefs->SetBoolean(prefs::kBlockThirdPartyCookies, false);
+
+ EXPECT_TRUE(
+ RunExtensionTestIncognito("content_settings/session_only_incognito")) <<
+ message_;
+
+ EXPECT_TRUE(browser()->profile()->HasOffTheRecordProfile());
+
+ PrefService* otr_prefs =
+ browser()->profile()->GetOffTheRecordProfile()->GetPrefs();
+ const PrefService::Preference* pref =
+ otr_prefs->FindPreference(prefs::kBlockThirdPartyCookies);
+ ASSERT_TRUE(pref);
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_FALSE(otr_prefs->GetBoolean(prefs::kBlockThirdPartyCookies));
+
+ pref = prefs->FindPreference(prefs::kBlockThirdPartyCookies);
+ ASSERT_TRUE(pref);
+ EXPECT_FALSE(pref->IsExtensionControlled());
+ EXPECT_FALSE(prefs->GetBoolean(prefs::kBlockThirdPartyCookies));
}
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentSettingsClear) {
diff --git a/chrome/browser/extensions/extension_pref_value_map.cc b/chrome/browser/extensions/extension_pref_value_map.cc
index 5b0b5ee..99bceb1 100644
--- a/chrome/browser/extensions/extension_pref_value_map.cc
+++ b/chrome/browser/extensions/extension_pref_value_map.cc
@@ -18,6 +18,9 @@ struct ExtensionPrefValueMap::ExtensionEntry {
// Persistent extension controlled preferences for the incognito profile,
// empty for regular profile ExtensionPrefStore.
PrefValueMap incognito_profile_preferences_persistent;
+ // Session only extension controlled preferences for the incognito profile.
+ // These preferences are deleted when the incognito profile is destroyed.
+ PrefValueMap incognito_profile_preferences_session_only;
};
ExtensionPrefValueMap::ExtensionPrefValueMap() {
@@ -66,6 +69,25 @@ bool ExtensionPrefValueMap::CanExtensionControlPref(
return winner->second->install_time <= ext->second->install_time;
}
+void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
+ typedef std::set<std::string> KeySet;
+ KeySet deleted_keys;
+
+ ExtensionEntryMap::iterator i;
+ for (i = entries_.begin(); i != entries_.end(); ++i) {
+ PrefValueMap& inc_prefs =
+ i->second->incognito_profile_preferences_session_only;
+ PrefValueMap::iterator j;
+ for (j = inc_prefs.begin(); j != inc_prefs.end(); ++j)
+ deleted_keys.insert(j->first);
+ inc_prefs.Clear();
+ }
+
+ KeySet::iterator k;
+ for (k = deleted_keys.begin(); k != deleted_keys.end(); ++k)
+ NotifyPrefValueChanged(*k);
+}
+
bool ExtensionPrefValueMap::DoesExtensionControlPref(
const std::string& extension_id,
const std::string& pref_key,
@@ -125,6 +147,8 @@ PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
return &(i->second->regular_profile_preferences);
case extension_prefs_scope::kIncognitoPersistent:
return &(i->second->incognito_profile_preferences_persistent);
+ case extension_prefs_scope::kIncognitoSessionOnly:
+ return &(i->second->incognito_profile_preferences_session_only);
}
NOTREACHED();
return NULL;
@@ -140,6 +164,8 @@ const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
return &(i->second->regular_profile_preferences);
case extension_prefs_scope::kIncognitoPersistent:
return &(i->second->incognito_profile_preferences_persistent);
+ case extension_prefs_scope::kIncognitoSessionOnly:
+ return &(i->second->incognito_profile_preferences_session_only);
}
NOTREACHED();
return NULL;
@@ -158,6 +184,11 @@ void ExtensionPrefValueMap::GetExtensionControlledKeys(
entry.incognito_profile_preferences_persistent;
for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
out->insert(i->first);
+
+ const PrefValueMap& inc_prefs_session =
+ entry.incognito_profile_preferences_session_only;
+ for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
+ out->insert(i->first);
}
const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
@@ -171,11 +202,23 @@ const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
const Value* value = NULL;
const std::string& ext_id = winner->first;
+
+ // First search for incognito session only preferences.
if (incognito) {
const PrefValueMap* prefs = GetExtensionPrefValueMap(
+ ext_id, extension_prefs_scope::kIncognitoSessionOnly);
+ prefs->GetValue(key, &value);
+ }
+
+ // If no incognito session only preference exists, fall back to persistent
+ // incognito preference.
+ if (incognito && !value) {
+ const PrefValueMap* prefs = GetExtensionPrefValueMap(
ext_id, extension_prefs_scope::kIncognitoPersistent);
prefs->GetValue(key, &value);
}
+
+ // Finally consider a regular preference.
if (!value) {
const PrefValueMap* prefs = GetExtensionPrefValueMap(
ext_id, extension_prefs_scope::kRegular);
@@ -224,6 +267,15 @@ ExtensionPrefValueMap::GetEffectivePrefValueController(
if (from_incognito)
*from_incognito = true;
}
+
+ prefs = GetExtensionPrefValueMap(
+ ext_id, extension_prefs_scope::kIncognitoSessionOnly);
+ if (prefs->GetValue(key, &value)) {
+ winner = i;
+ winners_install_time = install_time;
+ if (from_incognito)
+ *from_incognito = true;
+ }
}
return winner;
}
diff --git a/chrome/browser/extensions/extension_pref_value_map.h b/chrome/browser/extensions/extension_pref_value_map.h
index 8b4db03..1328753 100644
--- a/chrome/browser/extensions/extension_pref_value_map.h
+++ b/chrome/browser/extensions/extension_pref_value_map.h
@@ -89,6 +89,9 @@ class ExtensionPrefValueMap {
const std::string& pref_key,
bool incognito) const;
+ // Removes all "incognito session only" preference values.
+ void ClearAllIncognitoSessionOnlyPreferences();
+
// Returns true if an extension identified by |extension_id| controls the
// preference. This means this extension has set a preference value and no
// other extension with higher precedence overrides it.
diff --git a/chrome/browser/extensions/extension_pref_value_map_unittest.cc b/chrome/browser/extensions/extension_pref_value_map_unittest.cc
index d4ac026..40bb9e8 100644
--- a/chrome/browser/extensions/extension_pref_value_map_unittest.cc
+++ b/chrome/browser/extensions/extension_pref_value_map_unittest.cc
@@ -281,22 +281,30 @@ TEST_F(ExtensionPrefValueMapTest, ReenableExt) {
struct OverrideIncognitoTestCase {
OverrideIncognitoTestCase(int val_ext1_regular,
- int val_ext1_incognito,
+ int val_ext1_incognito_pers,
+ int val_ext1_incognito_sess,
int val_ext2_regular,
- int val_ext2_incognito,
+ int val_ext2_incognito_pers,
+ int val_ext2_incognito_sess,
int effective_value_regular,
int effective_value_incognito)
: val_ext1_regular_(val_ext1_regular),
- val_ext1_incognito_(val_ext1_incognito),
+ val_ext1_incognito_pers_(val_ext1_incognito_pers),
+ val_ext1_incognito_sess_(val_ext1_incognito_sess),
val_ext2_regular_(val_ext2_regular),
- val_ext2_incognito_(val_ext2_incognito),
+ val_ext2_incognito_pers_(val_ext2_incognito_pers),
+ val_ext2_incognito_sess_(val_ext2_incognito_sess),
effective_value_regular_(effective_value_regular),
effective_value_incognito_(effective_value_incognito) {}
+ // pers. = persistent
+ // sess. = session only
int val_ext1_regular_; // pref value of extension 1
- int val_ext1_incognito_; // pref value of extension 1 incognito
+ int val_ext1_incognito_pers_; // pref value of extension 1 incognito pers.
+ int val_ext1_incognito_sess_; // pref value of extension 1 incognito sess.
int val_ext2_regular_; // pref value of extension 2
- int val_ext2_incognito_; // pref value of extension 2 incognito
+ int val_ext2_incognito_pers_; // pref value of extension 2 incognito pers.
+ int val_ext2_incognito_sess_; // pref value of extension 2 incognito sess.
int effective_value_regular_; // desired winner regular
int effective_value_incognito_; // desired winner incognito
};
@@ -314,7 +322,9 @@ TEST_P(ExtensionPrefValueMapTestIncognitoTests, OverrideIncognito) {
"val1",
"val2",
"val3",
- "val4"
+ "val4",
+ "val5",
+ "val6"
};
epvm_.RegisterExtension(kExt1, CreateTime(10), true);
@@ -323,17 +333,25 @@ TEST_P(ExtensionPrefValueMapTestIncognitoTests, OverrideIncognito) {
epvm_.SetExtensionPref(kExt1, kPref1, kRegular,
CreateVal(strings[test.val_ext1_regular_]));
}
- if (test.val_ext1_incognito_) {
+ if (test.val_ext1_incognito_pers_) {
epvm_.SetExtensionPref(kExt1, kPref1, kIncognitoPersistent,
- CreateVal(strings[test.val_ext1_incognito_]));
+ CreateVal(strings[test.val_ext1_incognito_pers_]));
+ }
+ if (test.val_ext1_incognito_sess_) {
+ epvm_.SetExtensionPref(kExt1, kPref1, kIncognitoSessionOnly,
+ CreateVal(strings[test.val_ext1_incognito_sess_]));
}
if (test.val_ext2_regular_) {
epvm_.SetExtensionPref(kExt2, kPref1, kRegular,
CreateVal(strings[test.val_ext2_regular_]));
}
- if (test.val_ext2_incognito_) {
+ if (test.val_ext2_incognito_pers_) {
epvm_.SetExtensionPref(kExt2, kPref1, kIncognitoPersistent,
- CreateVal(strings[test.val_ext2_incognito_]));
+ CreateVal(strings[test.val_ext2_incognito_pers_]));
+ }
+ if (test.val_ext2_incognito_sess_) {
+ epvm_.SetExtensionPref(kExt2, kPref1, kIncognitoSessionOnly,
+ CreateVal(strings[test.val_ext2_incognito_sess_]));
}
std::string actual;
EXPECT_EQ(strings[test.effective_value_regular_], GetValue(kPref1, false));
@@ -346,15 +364,20 @@ INSTANTIATE_TEST_CASE_P(
ExtensionPrefValueMapTestIncognitoTestsInstance,
ExtensionPrefValueMapTestIncognitoTests,
testing::Values(
- // e.g. (1, 0, 0, 4, 1, 4), means:
- // ext1 regular is set to "val1", ext2 incognito is set to "val4"
+ // e.g. (1, 0, 0, 0, 4, 0, 1, 4), means:
+ // ext1 regular is set to "val1", ext2 incognito persistent is set to
+ // "val4"
// --> the winning regular value is "val1", the winning incognito
// value is "val4".
- OverrideIncognitoTestCase(1, 0, 0, 0, 1, 1),
- OverrideIncognitoTestCase(1, 2, 0, 0, 1, 2),
- OverrideIncognitoTestCase(1, 0, 3, 0, 3, 3),
- OverrideIncognitoTestCase(1, 0, 0, 4, 1, 4),
- // The last 3 in the following line is intentional!
- OverrideIncognitoTestCase(1, 2, 3, 0, 3, 3),
- OverrideIncognitoTestCase(1, 2, 0, 4, 1, 4),
- OverrideIncognitoTestCase(1, 2, 3, 4, 3, 4)));
+ OverrideIncognitoTestCase(1, 0, 0, 0, 0, 0, 1, 1),
+ OverrideIncognitoTestCase(1, 2, 0, 0, 0, 0, 1, 2),
+ OverrideIncognitoTestCase(1, 0, 3, 0, 0, 0, 1, 3),
+ OverrideIncognitoTestCase(1, 0, 0, 4, 0, 0, 4, 4),
+ OverrideIncognitoTestCase(1, 0, 0, 0, 5, 0, 1, 5),
+ OverrideIncognitoTestCase(1, 0, 0, 0, 0, 6, 1, 6),
+ // The last 4 in the following line is intentional!
+ OverrideIncognitoTestCase(1, 2, 0, 4, 0, 0, 4, 4),
+ OverrideIncognitoTestCase(1, 2, 0, 0, 5, 0, 1, 5),
+ OverrideIncognitoTestCase(1, 2, 3, 0, 5, 0, 1, 5),
+ OverrideIncognitoTestCase(1, 2, 0, 3, 5, 0, 3, 5),
+ OverrideIncognitoTestCase(1, 2, 0, 3, 5, 6, 3, 6)));
diff --git a/chrome/browser/extensions/extension_preference_api.cc b/chrome/browser/extensions/extension_preference_api.cc
index 3dcde37..2759c89 100644
--- a/chrome/browser/extensions/extension_preference_api.cc
+++ b/chrome/browser/extensions/extension_preference_api.cc
@@ -40,6 +40,7 @@ const char kScope[] = "scope";
const char kLevelOfControl[] = "levelOfControl";
const char kRegular[] = "regular";
const char kIncognitoPersistent[] = "incognito_persistent";
+const char kIncognitoSessionOnly[] = "incognito_session_only";
const char kValue[] = "value";
const char kOnPrefChangeFormat[] =
@@ -48,6 +49,10 @@ const char kOnPrefChangeFormat[] =
const char kIncognitoErrorMessage[] =
"You do not have permission to access incognito preferences.";
+const char kIncognitoSessionOnlyErrorMessage[] =
+ "You cannot set a preference with scope 'incognito_session_only' when no "
+ "incognito window is open.";
+
const char kPermissionErrorMessage[] =
"You do not have permission to access the preference '%s'. "
"Be sure to declare in your manifest what permissions you need.";
@@ -118,6 +123,8 @@ bool StringToScope(const std::string& s, extension_prefs_scope::Scope* scope) {
*scope = extension_prefs_scope::kRegular;
else if (s == kIncognitoPersistent)
*scope = extension_prefs_scope::kIncognitoPersistent;
+ else if (s == kIncognitoSessionOnly)
+ *scope = extension_prefs_scope::kIncognitoSessionOnly;
else
return false;
return true;
@@ -367,8 +374,8 @@ bool SetPreferenceFunction::RunImpl() {
extension_prefs_scope::Scope scope;
EXTENSION_FUNCTION_VALIDATE(StringToScope(scope_str, &scope));
- // TODO(battre): add kIncognitoSessionOnly
- bool incognito = (scope == extension_prefs_scope::kIncognitoPersistent);
+ bool incognito = (scope == extension_prefs_scope::kIncognitoPersistent ||
+ scope == extension_prefs_scope::kIncognitoSessionOnly);
if (incognito) {
// Regular profiles can't access incognito unless include_incognito is true.
if (!profile()->IsOffTheRecord() && !include_incognito()) {
@@ -384,6 +391,12 @@ bool SetPreferenceFunction::RunImpl() {
}
}
+ if (scope == extension_prefs_scope::kIncognitoSessionOnly &&
+ !profile_->HasOffTheRecordProfile()) {
+ error_ = kIncognitoSessionOnlyErrorMessage;
+ return false;
+ }
+
std::string browser_pref;
std::string permission;
EXTENSION_FUNCTION_VALIDATE(
@@ -431,8 +444,8 @@ bool ClearPreferenceFunction::RunImpl() {
extension_prefs_scope::Scope scope;
EXTENSION_FUNCTION_VALIDATE(StringToScope(scope_str, &scope));
- // TODO(battre): add kIncognitoSessionOnly
- bool incognito = (scope == extension_prefs_scope::kIncognitoPersistent);
+ bool incognito = (scope == extension_prefs_scope::kIncognitoPersistent ||
+ scope == extension_prefs_scope::kIncognitoSessionOnly);
if (incognito) {
// We don't check incognito permissions here, as an extension should be
// always allowed to clear its own settings.
diff --git a/chrome/browser/extensions/extension_prefs_scope.h b/chrome/browser/extensions/extension_prefs_scope.h
index 6447234..f137f1b 100644
--- a/chrome/browser/extensions/extension_prefs_scope.h
+++ b/chrome/browser/extensions/extension_prefs_scope.h
@@ -17,7 +17,9 @@ enum Scope {
// Incognito profile; preference is persisted to disk and remains active
// after a browser restart.
kIncognitoPersistent,
- // TODO(battre): add kIncognitoSession
+ // Incognito profile; preference is kept in memory and deleted when the
+ // incognito session is terminated.
+ kIncognitoSessionOnly
};
} // extension_prefs_scope
diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc
index f386957..d2686fa 100644
--- a/chrome/browser/extensions/extension_prefs_unittest.cc
+++ b/chrome/browser/extensions/extension_prefs_unittest.cc
@@ -709,6 +709,16 @@ class ExtensionPrefsPreferencesBase : public ExtensionPrefsTest {
kIncognitoPersistent, val);
}
+ void InstallExtControlledPrefIncognitoSessionOnly(
+ Extension *ext,
+ const std::string& key,
+ Value* val) {
+ using namespace extension_prefs_scope;
+ EnsureExtensionInstalled(ext);
+ prefs()->SetExtensionControlledPref(ext->id(), key,
+ kIncognitoSessionOnly, val);
+ }
+
void InstallExtension(Extension *ext) {
EnsureExtensionInstalled(ext);
}
@@ -767,7 +777,7 @@ class ExtensionPrefsInstallOneExtension
TEST_F(ExtensionPrefsInstallOneExtension, ExtensionPrefsInstallOneExtension) {}
// Check that we do not forget persistent incognito values after a reload.
-class ExtensionPrefsInstallIncognito
+class ExtensionPrefsInstallIncognitoPersistent
: public ExtensionPrefsPreferencesBase {
public:
virtual void Initialize() {
@@ -788,7 +798,43 @@ class ExtensionPrefsInstallIncognito
EXPECT_EQ("val2", actual);
}
};
-TEST_F(ExtensionPrefsInstallIncognito, ExtensionPrefsInstallOneExtension) {}
+TEST_F(ExtensionPrefsInstallIncognitoPersistent,
+ ExtensionPrefsInstallOneExtension) {}
+
+// Check that we forget 'session only' incognito values after a reload.
+class ExtensionPrefsInstallIncognitoSessionOnly
+ : public ExtensionPrefsPreferencesBase {
+ public:
+ ExtensionPrefsInstallIncognitoSessionOnly() : iteration_(0) {}
+
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPrefIncognitoSessionOnly(
+ ext1_, kPref1, Value::CreateStringValue("val2"));
+ scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
+ std::string actual = incog_prefs->GetString(kPref1);
+ EXPECT_EQ("val2", actual);
+ }
+ virtual void Verify() {
+ // 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 session-only incognito values only
+ // during first run. Once the pref service was reloaded, all values shall be
+ // discarded.
+ 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_;
+ }
+ int iteration_;
+};
+TEST_F(ExtensionPrefsInstallIncognitoSessionOnly,
+ ExtensionPrefsInstallOneExtension) {}
class ExtensionPrefsUninstallExtension
: public ExtensionPrefsPreferencesBase {
@@ -852,7 +898,7 @@ class ExtensionPrefsNotifyWhenNeeded
Mock::VerifyAndClearExpectations(&observer);
Mock::VerifyAndClearExpectations(&incognito_observer);
- // Change only incognito value.
+ // Change only incognito persistent value.
EXPECT_CALL(observer, Observe(_, _, _)).Times(0);
EXPECT_CALL(incognito_observer, Observe(_, _, _));
InstallExtControlledPrefIncognito(ext1_, kPref1,
@@ -860,6 +906,14 @@ class ExtensionPrefsNotifyWhenNeeded
Mock::VerifyAndClearExpectations(&observer);
Mock::VerifyAndClearExpectations(&incognito_observer);
+ // Change only incognito session-only value.
+ EXPECT_CALL(observer, Observe(_, _, _)).Times(0);
+ EXPECT_CALL(incognito_observer, Observe(_, _, _));
+ InstallExtControlledPrefIncognito(ext1_, kPref1,
+ Value::CreateStringValue("chrome://newtab3"));
+ Mock::VerifyAndClearExpectations(&observer);
+ Mock::VerifyAndClearExpectations(&incognito_observer);
+
// Uninstall.
EXPECT_CALL(observer, Observe(_, _, _));
EXPECT_CALL(incognito_observer, Observe(_, _, _));
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 650901c..5d8b6ad 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -712,6 +712,7 @@ Profile* ProfileImpl::GetOffTheRecordProfile() {
void ProfileImpl::DestroyOffTheRecordProfile() {
off_the_record_profile_.reset();
+ extension_pref_value_map_->ClearAllIncognitoSessionOnlyPreferences();
}
bool ProfileImpl::HasOffTheRecordProfile() {
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 82645ba..b7cbc7b 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -5384,9 +5384,9 @@
},
"scope": {
"type": "string",
- "enum": ["regular", "incognito_persistent"],
+ "enum": ["regular", "incognito_persistent", "incognito_session_only"],
"optional": true,
- "description": "Where to set the preference (default: regular). 'regular' = preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere), 'incognito_persistent' = preference for incognito profile that sustains browser restarts (overrides regular preferences)."
+ "description": "Where to set the preference (default: regular). One of<br><var>regular</var>: preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere),<br><var>incognito_persistent</var>: preference for incognito profile that survives browser restarts (overrides regular preferences),<br><var>incognito_session_only</var>: preference for incognito profile that can only be set during an incognito session and is deleted when the incognito session ends (overrides regular and incognito_persistent preferences)."
}
}
},
@@ -5411,9 +5411,9 @@
"properties": {
"scope": {
"type": "string",
- "enum": ["regular", "incognito_persistent"],
+ "enum": ["regular", "incognito_persistent", "incognito_session_only"],
"optional": true,
- "description": "Where to set the preference (default: regular). 'regular' = preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere), 'incognito_persistent' = preference for incognito profile that sustains browser restarts (overrides regular preferences)."
+ "description": "Where to set the preference (default: regular). One of<br><var>regular</var>: preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere),<br><var>incognito_persistent</var>: preference for incognito profile that survives browser restarts (overrides regular preferences),<br><var>incognito_session_only</var>: preference for incognito profile that can only be set during an incognito session and is deleted when the incognito session ends (overrides regular and incognito_persistent preferences)."
}
}
},
diff --git a/chrome/common/extensions/docs/preferences.html b/chrome/common/extensions/docs/preferences.html
index bfd2ec6..b4be9f9 100644
--- a/chrome/common/extensions/docs/preferences.html
+++ b/chrome/common/extensions/docs/preferences.html
@@ -715,7 +715,7 @@ considering the preference rules. It is used by Chrome.
array of <span><span></span></span>
</span>
<span>string</span>
- <span>["regular", "incognito_persistent"]</span>
+ <span>["regular", "incognito_persistent", "incognito_session_only"]</span>
</span>
</span>
)
@@ -726,7 +726,7 @@ considering the preference rules. It is used by Chrome.
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>Where to set the preference (default: regular). 'regular' = preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere), 'incognito_persistent' = preference for incognito profile that sustains browser restarts (overrides regular preferences).</dd>
+ <dd>Where to set the preference (default: regular). One of<br><var>regular</var>: preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere),<br><var>incognito_persistent</var>: preference for incognito profile that survives browser restarts (overrides regular preferences),<br><var>incognito_session_only</var>: preference for incognito profile that can only be set during an incognito session and is deleted when the incognito session ends (overrides regular and incognito_persistent preferences).</dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
@@ -1577,7 +1577,7 @@ considering the preference rules. It is used by Chrome.
array of <span><span></span></span>
</span>
<span>string</span>
- <span>["regular", "incognito_persistent"]</span>
+ <span>["regular", "incognito_persistent", "incognito_session_only"]</span>
</span>
</span>
)
@@ -1588,7 +1588,7 @@ considering the preference rules. It is used by Chrome.
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>Where to set the preference (default: regular). 'regular' = preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere), 'incognito_persistent' = preference for incognito profile that sustains browser restarts (overrides regular preferences).</dd>
+ <dd>Where to set the preference (default: regular). One of<br><var>regular</var>: preference for regular profile (which is inherited by the incognito profile if not overridden elsewhere),<br><var>incognito_persistent</var>: preference for incognito profile that survives browser restarts (overrides regular preferences),<br><var>incognito_session_only</var>: preference for incognito profile that can only be set during an incognito session and is deleted when the incognito session ends (overrides regular and incognito_persistent preferences).</dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
diff --git a/chrome/test/data/extensions/api_test/content_settings/incognito/manifest.json b/chrome/test/data/extensions/api_test/content_settings/persistent_incognito/manifest.json
index 79541c3..79541c3 100644
--- a/chrome/test/data/extensions/api_test/content_settings/incognito/manifest.json
+++ b/chrome/test/data/extensions/api_test/content_settings/persistent_incognito/manifest.json
diff --git a/chrome/test/data/extensions/api_test/content_settings/incognito/test.html b/chrome/test/data/extensions/api_test/content_settings/persistent_incognito/test.html
index b16f8c0..098ed2a 100644
--- a/chrome/test/data/extensions/api_test/content_settings/incognito/test.html
+++ b/chrome/test/data/extensions/api_test/content_settings/persistent_incognito/test.html
@@ -1,6 +1,6 @@
<script>
// Content settings API test
-// Run with browser_tests --gtest_filter=ExtensionApiTest.IncognitoContentSettings
+// Run with browser_tests --gtest_filter=ExtensionApiTest.PersistentIncognitoContentSettings
var cs = chrome.experimental.contentSettings;
function expect(expected, message) {
diff --git a/chrome/test/data/extensions/api_test/content_settings/session_only_incognito/manifest.json b/chrome/test/data/extensions/api_test/content_settings/session_only_incognito/manifest.json
new file mode 100644
index 0000000..6c421de
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/content_settings/session_only_incognito/manifest.json
@@ -0,0 +1,7 @@
+{
+ "name" : "Content Settings API Test Extension (Incognito)",
+ "version" : "0.1",
+ "description" : "Content Settings API Test Extension (Incognito)",
+ "permissions": [ "experimental", "contentSettings", "tabs" ],
+ "background_page": "test.html"
+}
diff --git a/chrome/test/data/extensions/api_test/content_settings/session_only_incognito/test.html b/chrome/test/data/extensions/api_test/content_settings/session_only_incognito/test.html
new file mode 100644
index 0000000..3fac32a
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/content_settings/session_only_incognito/test.html
@@ -0,0 +1,82 @@
+<script>
+// Content settings API test
+// Run with browser_tests --gtest_filter=ExtensionApiTest.SessionOnlyIncognitoContentSettings
+
+var cs = chrome.experimental.contentSettings;
+function expect(expected, message) {
+ return chrome.test.callbackPass(function(value) {
+ chrome.test.assertNoLastError();
+ chrome.test.assertEq(expected, value, message);
+ });
+}
+chrome.test.runTests([
+ function getRegular() {
+ cs.misc.blockThirdPartyCookies.get(
+ {},
+ expect({ 'value': false,
+ 'levelOfControl': "ControllableByThisExtension" },
+ "third-party cookies should not be blocked"));
+ },
+ function getIncognito() {
+ cs.misc.blockThirdPartyCookies.get(
+ { 'incognito': true },
+ expect({ 'value': false,
+ 'incognitoSpecific': false,
+ 'levelOfControl': "ControllableByThisExtension" },
+ "third-party cookies should not be blocked in incognito mode"));
+ },
+ function set() {
+ cs.misc.blockThirdPartyCookies.set(
+ { 'scope': 'incognito_persistent', 'value': true },
+ chrome.test.callbackPass());
+ },
+ function getRegular2() {
+ cs.misc.blockThirdPartyCookies.get(
+ {},
+ expect({ 'value': false,
+ 'levelOfControl': "ControllableByThisExtension" },
+ "third-party cookies should not be blocked"));
+ },
+ function getIncognito2() {
+ cs.misc.blockThirdPartyCookies.get(
+ { 'incognito': true },
+ expect({ 'value': true,
+ 'incognitoSpecific': true,
+ 'levelOfControl': "ControlledByThisExtension" },
+ "third-party cookies should be blocked in incognito mode"));
+ },
+ // We cannot set session_only_persistent preferences if there is no incognito
+ // session.
+ function set2() {
+ cs.misc.blockThirdPartyCookies.set(
+ { 'scope': 'incognito_session_only', 'value': false },
+ chrome.test.callbackFail("You cannot set a preference with scope " +
+ "'incognito_session_only' when no incognito " +
+ "window is open."));
+ },
+ function openIncognito() {
+ chrome.windows.create({incognito: true}, chrome.test.callbackPass());
+ },
+ // session_only_persistent overrides incognito_persistent.
+ function set3() {
+ cs.misc.blockThirdPartyCookies.set(
+ { 'scope': 'incognito_session_only', 'value': false },
+ chrome.test.callbackPass());
+ },
+ function getRegular3() {
+ cs.misc.blockThirdPartyCookies.get(
+ {},
+ expect({ 'value': false,
+ 'levelOfControl': "ControllableByThisExtension" },
+ "third-party cookies should not be blocked"));
+ },
+ function getIncognito3() {
+ cs.misc.blockThirdPartyCookies.get(
+ { 'incognito': true },
+ expect({ 'value': false,
+ 'incognitoSpecific': true,
+ 'levelOfControl': "ControlledByThisExtension" },
+ "third-party cookies should be blocked in incognito mode"));
+ },
+]);
+</script>