diff options
author | dbeam <dbeam@chromium.org> | 2015-04-20 08:34:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-20 15:35:25 +0000 |
commit | 155ac97a453b6faf109949ed5319a90e759af9d2 (patch) | |
tree | 57d3489b8539318126b535ac626733454cb91915 /components/content_settings | |
parent | 40ef9a95d8065eefbd57d6ef07eaa1e0dca2db4c (diff) | |
download | chromium_src-155ac97a453b6faf109949ed5319a90e759af9d2.zip chromium_src-155ac97a453b6faf109949ed5319a90e759af9d2.tar.gz chromium_src-155ac97a453b6faf109949ed5319a90e759af9d2.tar.bz2 |
Make DETECT_IMPORTANT_CONTENT the default Plugins content setting based
on the results of a FieldTrial (also flags).
Still respect the user's choice when they've explicitly chosen an
alternative (e.g. they chose to BLOCK all plugins).
R=tommycli@chromium.org,bauerb@chromium.org,jochen@chromium.org
TBR=markusheintz@chromium.org
BUG=476742
Review URL: https://codereview.chromium.org/1084123002
Cr-Commit-Position: refs/heads/master@{#325846}
Diffstat (limited to 'components/content_settings')
6 files changed, 237 insertions, 41 deletions
diff --git a/components/content_settings/core/browser/BUILD.gn b/components/content_settings/core/browser/BUILD.gn index 1f19608..5fcff79 100644 --- a/components/content_settings/core/browser/BUILD.gn +++ b/components/content_settings/core/browser/BUILD.gn @@ -34,12 +34,15 @@ static_library("browser") { "host_content_settings_map.cc", "host_content_settings_map.h", "local_shared_objects_counter.h", + "plugins_field_trial.cc", + "plugins_field_trial.h", ] deps = [ "//base", "//base:prefs", "//components/content_settings/core/common", + "//components/plugins/common", "//components/pref_registry:pref_registry", "//net", "//url", @@ -56,6 +59,7 @@ source_set("unit_tests") { "content_settings_provider_unittest.cc", "content_settings_rule_unittest.cc", "content_settings_utils_unittest.cc", + "plugins_field_trial_unittest.cc", ] deps = [ diff --git a/components/content_settings/core/browser/DEPS b/components/content_settings/core/browser/DEPS index dcf594c..0bc7443 100644 --- a/components/content_settings/core/browser/DEPS +++ b/components/content_settings/core/browser/DEPS @@ -1,5 +1,7 @@ include_rules = [ + "+components/content_settings/core/common", "+components/content_settings/core/test", + "+components/plugins/common", "+components/pref_registry", "+net/base", "+net/cookies", diff --git a/components/content_settings/core/browser/content_settings_default_provider.cc b/components/content_settings/core/browser/content_settings_default_provider.cc index 0af5197..d6246c7 100644 --- a/components/content_settings/core/browser/content_settings_default_provider.cc +++ b/components/content_settings/core/browser/content_settings_default_provider.cc @@ -16,12 +16,15 @@ #include "base/prefs/scoped_user_pref_update.h" #include "components/content_settings/core/browser/content_settings_rule.h" #include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/plugins_field_trial.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "url/gurl.h" +namespace content_settings { + namespace { struct DefaultContentSettingInfo { @@ -36,11 +39,10 @@ struct DefaultContentSettingInfo { // default content setting. This array must be kept in sync with the enum // |ContentSettingsType|. const DefaultContentSettingInfo kDefaultSettings[] = { - {prefs::kDefaultCookiesSetting, CONTENT_SETTING_ALLOW}, {prefs::kDefaultImagesSetting, CONTENT_SETTING_ALLOW}, {prefs::kDefaultJavaScriptSetting, CONTENT_SETTING_ALLOW}, - {prefs::kDefaultPluginsSetting, CONTENT_SETTING_ALLOW}, + {prefs::kDefaultPluginsSetting, CONTENT_SETTING_DEFAULT}, {prefs::kDefaultPopupsSetting, CONTENT_SETTING_BLOCK}, {prefs::kDefaultGeolocationSetting, CONTENT_SETTING_ASK}, {prefs::kDefaultNotificationsSetting, CONTENT_SETTING_ASK}, @@ -63,17 +65,20 @@ const DefaultContentSettingInfo kDefaultSettings[] = { {prefs::kDefaultProtectedMediaIdentifierSetting, CONTENT_SETTING_ASK}, #endif {prefs::kDefaultAppBannerSetting, CONTENT_SETTING_DEFAULT} - }; static_assert(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES, "kDefaultSettings should have CONTENT_SETTINGS_NUM_TYPES " "elements"); -} // namespace - -namespace content_settings { +ContentSetting GetDefaultValue(ContentSettingsType type) { + if (type == CONTENT_SETTINGS_TYPE_PLUGINS) + return PluginsFieldTrial::GetDefaultPluginsContentSetting(); + return kDefaultSettings[type].default_value; +} -namespace { +const char* GetPrefName(ContentSettingsType type) { + return kDefaultSettings[type].pref_name; +} class DefaultRuleIterator : public RuleIterator { public: @@ -116,10 +121,11 @@ void DefaultProvider::RegisterProfilePrefs( // TODO(msramek): The aggregate preference above is deprecated. Remove it // after two stable releases. for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { + ContentSettingsType type = static_cast<ContentSettingsType>(i); registry->RegisterIntegerPref( - kDefaultSettings[i].pref_name, - kDefaultSettings[i].default_value, - IsContentSettingsTypeSyncable(ContentSettingsType(i)) + GetPrefName(type), + GetDefaultValue(type), + IsContentSettingsTypeSyncable(type) ? user_prefs::PrefRegistrySyncable::SYNCABLE_PREF : user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); } @@ -159,57 +165,57 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultCookiesSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_COOKIES].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_COOKIES))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultImagesSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_IMAGES].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_IMAGES))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultJavaScriptSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_JAVASCRIPT].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_JAVASCRIPT))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultPluginsSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_PLUGINS].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_PLUGINS))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultPopupsSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_POPUPS].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_POPUPS))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultLocationSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_GEOLOCATION].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_GEOLOCATION))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultNotificationsSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultMouseCursorSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_MOUSELOCK].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_MOUSELOCK))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultMediaStreamSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_MEDIASTREAM].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_MEDIASTREAM))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultMIDISysExSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_MIDI_SYSEX].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_MIDI_SYSEX))), CONTENT_SETTING_NUM_SETTINGS); UMA_HISTOGRAM_ENUMERATION( "ContentSettings.DefaultPushMessagingSetting", IntToContentSetting(prefs_->GetInteger( - kDefaultSettings[CONTENT_SETTINGS_TYPE_PUSH_MESSAGING].pref_name)), + GetPrefName(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING))), CONTENT_SETTING_NUM_SETTINGS); pref_change_registrar_.Init(prefs_); @@ -217,8 +223,10 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) &DefaultProvider::OnPreferenceChanged, base::Unretained(this)); pref_change_registrar_.Add(prefs::kDefaultContentSettings, callback); - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) - pref_change_registrar_.Add(kDefaultSettings[i].pref_name, callback); + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { + ContentSettingsType type = static_cast<ContentSettingsType>(i); + pref_change_registrar_.Add(GetPrefName(type), callback); + } } DefaultProvider::~DefaultProvider() { @@ -308,23 +316,22 @@ void DefaultProvider::ShutdownOnUIThread() { void DefaultProvider::ReadDefaultSettings() { base::AutoLock lock(lock_); for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - ContentSettingsType content_type = ContentSettingsType(i); - ChangeSetting(content_type, ReadIndividualPref(content_type).get()); + ContentSettingsType type = static_cast<ContentSettingsType>(i); + ChangeSetting(type, ReadIndividualPref(type).get()); } } bool DefaultProvider::IsValueEmptyOrDefault(ContentSettingsType content_type, - base::Value* value) { - return (!value || - ValueToContentSetting(value) - == kDefaultSettings[content_type].default_value); + base::Value* value) { + if (!value) return true; + return ValueToContentSetting(value) == GetDefaultValue(content_type); } void DefaultProvider::ChangeSetting(ContentSettingsType content_type, base::Value* value) { if (!value) { - default_settings_[content_type].reset(ContentSettingToValue( - kDefaultSettings[content_type].default_value).release()); + default_settings_[content_type].reset( + ContentSettingToValue(GetDefaultValue(content_type)).release()); } else { default_settings_[content_type].reset(value->DeepCopy()); } @@ -333,14 +340,14 @@ void DefaultProvider::ChangeSetting(ContentSettingsType content_type, void DefaultProvider::WriteIndividualPref(ContentSettingsType content_type, base::Value* value) { if (IsValueEmptyOrDefault(content_type, value)) { - prefs_->ClearPref(kDefaultSettings[content_type].pref_name); + prefs_->ClearPref(GetPrefName(content_type)); return; } - int int_value = kDefaultSettings[content_type].default_value; + int int_value = GetDefaultValue(content_type); bool is_integer = value->GetAsInteger(&int_value); DCHECK(is_integer); - prefs_->SetInteger(kDefaultSettings[content_type].pref_name, int_value); + prefs_->SetInteger(GetPrefName(content_type), int_value); } void DefaultProvider::WriteDictionaryPref(ContentSettingsType content_type, @@ -410,8 +417,9 @@ void DefaultProvider::OnPreferenceChanged(const std::string& name) { ContentSettingsType content_type = CONTENT_SETTINGS_TYPE_DEFAULT; for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - if (kDefaultSettings[i].pref_name == name) { - content_type = ContentSettingsType(i); + ContentSettingsType type = static_cast<ContentSettingsType>(i); + if (GetPrefName(type) == name) { + content_type = type; break; } } @@ -449,7 +457,7 @@ void DefaultProvider::OnPreferenceChanged(const std::string& name) { scoped_ptr<base::Value> DefaultProvider::ReadIndividualPref( ContentSettingsType content_type) { - int int_value = prefs_->GetInteger(kDefaultSettings[content_type].pref_name); + int int_value = prefs_->GetInteger(GetPrefName(content_type)); return ContentSettingToValue(IntToContentSetting(int_value)).Pass(); } @@ -483,10 +491,10 @@ scoped_ptr<DefaultProvider::ValueMap> DefaultProvider::ReadDictionaryPref() { void DefaultProvider::ForceDefaultsToBeExplicit(ValueMap* value_map) { for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - ContentSettingsType type = ContentSettingsType(i); + ContentSettingsType type = static_cast<ContentSettingsType>(i); if (!(*value_map)[type].get()) { (*value_map)[type].reset(ContentSettingToValue( - kDefaultSettings[i].default_value).release()); + GetDefaultValue(type)).release()); } } } @@ -524,8 +532,8 @@ void DefaultProvider::MigrateDefaultSettings() { scoped_ptr<DefaultProvider::ValueMap> value_map = ReadDictionaryPref(); for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - ContentSettingsType content_type = ContentSettingsType(i); - WriteIndividualPref(content_type, (*value_map)[content_type].get()); + ContentSettingsType type = static_cast<ContentSettingsType>(i); + WriteIndividualPref(type, (*value_map)[type].get()); } prefs_->SetBoolean(prefs::kMigratedDefaultContentSettings, true); diff --git a/components/content_settings/core/browser/plugins_field_trial.cc b/components/content_settings/core/browser/plugins_field_trial.cc new file mode 100644 index 0000000..98cd97a --- /dev/null +++ b/components/content_settings/core/browser/plugins_field_trial.cc @@ -0,0 +1,49 @@ +// Copyright 2015 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 "components/content_settings/core/browser/plugins_field_trial.h" + +#include "base/command_line.h" +#include "base/metrics/field_trial.h" +#include "components/plugins/common/plugins_switches.h" + +namespace content_settings { + +// static +const char PluginsFieldTrial::kFieldTrialName[] = "ForcePluginPowerSaver"; + +// static +ContentSetting PluginsFieldTrial::EffectiveContentSetting( + ContentSettingsType type, + ContentSetting setting) { + if (type != CONTENT_SETTINGS_TYPE_PLUGINS) + return setting; + + // For Plugins, ASK is obsolete. Show as BLOCK to reflect actual behavior. + if (setting == ContentSetting::CONTENT_SETTING_ASK) + return ContentSetting::CONTENT_SETTING_BLOCK; + + return setting; +} + +// static +bool PluginsFieldTrial::IsPluginPowerSaverEnabled() { + const base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + if (cl->HasSwitch(plugins::switches::kDisablePluginPowerSaver)) + return false; + if (cl->HasSwitch(plugins::switches::kEnablePluginPowerSaver)) + return true; + + std::string group_name = base::FieldTrialList::FindFullName(kFieldTrialName); + return !group_name.empty() && group_name != "Disabled"; +} + +// static +ContentSetting PluginsFieldTrial::GetDefaultPluginsContentSetting() { + return IsPluginPowerSaverEnabled() ? + ContentSetting::CONTENT_SETTING_DETECT_IMPORTANT_CONTENT : + ContentSetting::CONTENT_SETTING_ALLOW; +} + +} // namespace content_settings diff --git a/components/content_settings/core/browser/plugins_field_trial.h b/components/content_settings/core/browser/plugins_field_trial.h new file mode 100644 index 0000000..ccc39df --- /dev/null +++ b/components/content_settings/core/browser/plugins_field_trial.h @@ -0,0 +1,36 @@ +// Copyright 2015 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 COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_CONTENT_SETTINGS_H_ +#define COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_CONTENT_SETTINGS_H_ + +#include "base/macros.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" + +namespace content_settings { + +// This class manages the Plugins field trials. +class PluginsFieldTrial { + public: + static const char kFieldTrialName[]; + + // Returns the effective content setting for plugins. Passes non-plugin + // content settings through without modification. + static ContentSetting EffectiveContentSetting(ContentSettingsType type, + ContentSetting setting); + + // Returns true if the Plugin Power Saver feature is enabled. + static bool IsPluginPowerSaverEnabled(); + + // Get the default plugins content setting based on field trials/flags. + static ContentSetting GetDefaultPluginsContentSetting(); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(PluginsFieldTrial); +}; + +} // namespace content_settings + +#endif // COMPONENTS_CONTENT_SETTINGS_CORE_BROWSER_CONTENT_SETTINGS_H_ diff --git a/components/content_settings/core/browser/plugins_field_trial_unittest.cc b/components/content_settings/core/browser/plugins_field_trial_unittest.cc new file mode 100644 index 0000000..052f8a5 --- /dev/null +++ b/components/content_settings/core/browser/plugins_field_trial_unittest.cc @@ -0,0 +1,97 @@ +// Copyright 2015 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 "components/content_settings/core/browser/plugins_field_trial.h" + +#include "base/command_line.h" +#include "base/macros.h" +#include "base/metrics/field_trial.h" +#include "base/test/mock_entropy_provider.h" +#include "components/content_settings/core/browser/content_settings_default_provider.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/plugins/common/plugins_switches.h" +#include "components/pref_registry/testing_pref_service_syncable.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content_settings { + +namespace { + +const auto& kFieldTrialName = PluginsFieldTrial::kFieldTrialName; + +void ForceFieldTrialGroup(const std::string& group_name) { + using base::FieldTrialList; + ASSERT_TRUE(FieldTrialList::CreateFieldTrial(kFieldTrialName, group_name)); +} + +} // namespace + +class PluginsFieldTrialTest : public testing::Test { + public: + PluginsFieldTrialTest() : field_trial_list_(new base::MockEntropyProvider) {} + + private: + base::FieldTrialList field_trial_list_; + + DISALLOW_COPY_AND_ASSIGN(PluginsFieldTrialTest); +}; + +TEST_F(PluginsFieldTrialTest, DisabledByDefault) { + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + ASSERT_FALSE(cl->HasSwitch(plugins::switches::kDisablePluginPowerSaver)); + ASSERT_FALSE(cl->HasSwitch(plugins::switches::kEnablePluginPowerSaver)); + ASSERT_FALSE(base::FieldTrialList::TrialExists(kFieldTrialName)); + EXPECT_FALSE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, FieldTrialEnabled) { + ForceFieldTrialGroup("Enabled"); + EXPECT_TRUE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, FieldTrialDisabled) { + ForceFieldTrialGroup("Disabled"); + EXPECT_FALSE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, SwitchEnabled) { + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + cl->AppendSwitch(plugins::switches::kEnablePluginPowerSaver); + EXPECT_TRUE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, SwitchDisabled) { + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + cl->AppendSwitch(plugins::switches::kDisablePluginPowerSaver); + EXPECT_FALSE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, SwitchOverridesFieldTrial1) { + ForceFieldTrialGroup("Disabled"); + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + cl->AppendSwitch(plugins::switches::kEnablePluginPowerSaver); + EXPECT_TRUE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, SwitchOverridesFieldTrial2) { + ForceFieldTrialGroup("Enabled"); + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + cl->AppendSwitch(plugins::switches::kDisablePluginPowerSaver); + EXPECT_FALSE(PluginsFieldTrial::IsPluginPowerSaverEnabled()); +} + +TEST_F(PluginsFieldTrialTest, NoPrefLeftBehind) { + ForceFieldTrialGroup("Enabled"); + user_prefs::TestingPrefServiceSyncable prefs; + { + DefaultProvider::RegisterProfilePrefs(prefs.registry()); + DefaultProvider default_provider(&prefs, false); + } + EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT, + prefs.GetInteger(prefs::kDefaultPluginsSetting)); + EXPECT_FALSE(prefs.HasPrefPath(prefs::kDefaultPluginsSetting)); +} + +} // namespace content_settings |