Commit d1d20087 authored by jkrcal's avatar jkrcal Committed by Commit bot

Registering field trial for a feature overridden in chrome://flags.

Variation parameters can be overridden via chrome://flags. Internally, a
fresh trial group is created with the specified parameters. Previously,
the trial was not registered for the associated feature.

This CL registers the trial for the given feature.

BUG=625993

Review-Url: https://codereview.chromium.org/2129543002
Cr-Commit-Position: refs/heads/master@{#405496}
parent f870ab54
...@@ -2039,9 +2039,10 @@ void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage, ...@@ -2039,9 +2039,10 @@ void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage,
} }
void RegisterAllFeatureVariationParameters( void RegisterAllFeatureVariationParameters(
flags_ui::FlagsStorage* flags_storage) { flags_ui::FlagsStorage* flags_storage,
base::FeatureList* feature_list) {
FlagsStateSingleton::GetFlagsState()->RegisterAllFeatureVariationParameters( FlagsStateSingleton::GetFlagsState()->RegisterAllFeatureVariationParameters(
flags_storage); flags_storage, feature_list);
} }
bool AreSwitchesIdenticalToCurrentCommandLine( bool AreSwitchesIdenticalToCurrentCommandLine(
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/flags_ui/flags_state.h" #include "components/flags_ui/flags_state.h"
namespace base { namespace base {
class FeatureList;
class ListValue; class ListValue;
} }
...@@ -34,10 +35,13 @@ void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage, ...@@ -34,10 +35,13 @@ void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage,
base::CommandLine* command_line, base::CommandLine* command_line,
flags_ui::SentinelsMode sentinels); flags_ui::SentinelsMode sentinels);
// Registers variations parameter values stored in |flags_storage| (previously // Registers variations parameter values selected for features in about:flags.
// selected in about:flags). // The selected flags are retrieved from |flags_storage|, the registered
// variation parameters are connected to their corresponding features in
// |feature_list|.
void RegisterAllFeatureVariationParameters( void RegisterAllFeatureVariationParameters(
flags_ui::FlagsStorage* flags_storage); flags_ui::FlagsStorage* flags_storage,
base::FeatureList* feature_list);
// Compares a set of switches of the two provided command line objects and // Compares a set of switches of the two provided command line objects and
// returns true if they are the same and false otherwise. // returns true if they are the same and false otherwise.
......
...@@ -727,12 +727,14 @@ void ChromeBrowserMainParts::SetupMetricsAndFieldTrials() { ...@@ -727,12 +727,14 @@ void ChromeBrowserMainParts::SetupMetricsAndFieldTrials() {
metrics->AddSyntheticTrialObserver(provider); metrics->AddSyntheticTrialObserver(provider);
} }
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
// Associate parameters chosen in about:flags and create trial/group for them. // Associate parameters chosen in about:flags and create trial/group for them.
flags_ui::PrefServiceFlagsStorage flags_storage( flags_ui::PrefServiceFlagsStorage flags_storage(
g_browser_process->local_state()); g_browser_process->local_state());
about_flags::RegisterAllFeatureVariationParameters(&flags_storage); about_flags::RegisterAllFeatureVariationParameters(&flags_storage,
feature_list.get());
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
feature_list->InitializeFromCommandLine( feature_list->InitializeFromCommandLine(
command_line->GetSwitchValueASCII(switches::kEnableFeatures), command_line->GetSwitchValueASCII(switches::kEnableFeatures),
command_line->GetSwitchValueASCII(switches::kDisableFeatures)); command_line->GetSwitchValueASCII(switches::kDisableFeatures));
......
...@@ -197,7 +197,7 @@ base::Value* CreateOptionsData(const FeatureEntry& entry, ...@@ -197,7 +197,7 @@ base::Value* CreateOptionsData(const FeatureEntry& entry,
// been created (e.g. via command-line switches that take precedence over // been created (e.g. via command-line switches that take precedence over
// about:flags). In the trial, the function creates a new constant group called // about:flags). In the trial, the function creates a new constant group called
// |kTrialGroupAboutFlags|. // |kTrialGroupAboutFlags|.
void RegisterFeatureVariationParameters( base::FieldTrial* RegisterFeatureVariationParameters(
const std::string& feature_trial_name, const std::string& feature_trial_name,
const FeatureEntry::FeatureVariation* feature_variation) { const FeatureEntry::FeatureVariation* feature_variation) {
std::map<std::string, std::string> params; std::map<std::string, std::string> params;
...@@ -211,18 +211,19 @@ void RegisterFeatureVariationParameters( ...@@ -211,18 +211,19 @@ void RegisterFeatureVariationParameters(
bool success = variations::AssociateVariationParams( bool success = variations::AssociateVariationParams(
feature_trial_name, internal::kTrialGroupAboutFlags, params); feature_trial_name, internal::kTrialGroupAboutFlags, params);
if (success) { if (!success)
// Successful association also means that no group is created and selected return nullptr;
// for the trial, yet. Thus, create the trial to select the group. This way, // Successful association also means that no group is created and selected
// the parameters cannot get overwritten in later phases (such as from the // for the trial, yet. Thus, create the trial to select the group. This way,
// server). // the parameters cannot get overwritten in later phases (such as from the
base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( // server).
feature_trial_name, internal::kTrialGroupAboutFlags); base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
if (!trial) { feature_trial_name, internal::kTrialGroupAboutFlags);
DLOG(WARNING) << "Could not create the trial " << feature_trial_name if (!trial) {
<< " with group " << internal::kTrialGroupAboutFlags; DLOG(WARNING) << "Could not create the trial " << feature_trial_name
} << " with group " << internal::kTrialGroupAboutFlags;
} }
return trial;
} }
} // namespace } // namespace
...@@ -436,7 +437,8 @@ void FlagsState::Reset() { ...@@ -436,7 +437,8 @@ void FlagsState::Reset() {
} }
void FlagsState::RegisterAllFeatureVariationParameters( void FlagsState::RegisterAllFeatureVariationParameters(
FlagsStorage* flags_storage) { FlagsStorage* flags_storage,
base::FeatureList* feature_list) {
std::set<std::string> enabled_entries; std::set<std::string> enabled_entries;
GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, &enabled_entries); GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, &enabled_entries);
...@@ -448,20 +450,16 @@ void FlagsState::RegisterAllFeatureVariationParameters( ...@@ -448,20 +450,16 @@ void FlagsState::RegisterAllFeatureVariationParameters(
e.VariationForOption(j); e.VariationForOption(j);
if (e.StateForOption(j) == FeatureEntry::FeatureState::ENABLED && if (e.StateForOption(j) == FeatureEntry::FeatureState::ENABLED &&
enabled_entries.count(e.NameForOption(j))) { enabled_entries.count(e.NameForOption(j))) {
// If the option is enabled by the user, register it. // If the option is selected by the user & has variation, register it.
RegisterFeatureVariationParameters(e.feature_trial_name, variation); base::FieldTrial* field_trial = RegisterFeatureVariationParameters(
// TODO(jkrcal) The code does not associate the feature with the field e.feature_trial_name, variation);
// trial |e.feature_trial_name|. The reason is that features
// overridden in chrome://flags are translated to command-line flags if (!field_trial)
// and thus treated earlier in the initialization. The fix requires continue;
// larger changes. As a result: feature_list->RegisterFieldTrialOverride(
// - the API calls to variations::GetVariationParamValueByFeature and e.feature->name,
// to variations::GetVariationParamsByFeature do not work; and base::FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE,
// - the API call to base::FeatureList::IsEnabled does not mark the field_trial);
// field trial as active (and the trial does not appear in UMA).
// If the code calls variations::GetVariationParamValue or
// variations::GetVariationParams providing the trial name, everything
// should work fine.
} }
} }
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/macros.h" #include "base/macros.h"
namespace base { namespace base {
class FeatureList;
class ListValue; class ListValue;
} }
...@@ -80,9 +81,12 @@ class FlagsState { ...@@ -80,9 +81,12 @@ class FlagsState {
void ResetAllFlags(FlagsStorage* flags_storage); void ResetAllFlags(FlagsStorage* flags_storage);
void Reset(); void Reset();
// Registers variations parameter values stored in |flags_storage| (previously // Registers variations parameter values selected for features in about:flags.
// selected in about:flags). // The selected flags are retrieved from |flags_storage|, the registered
void RegisterAllFeatureVariationParameters(FlagsStorage* flags_storage); // variation parameters are connected to their corresponding features in
// |feature_list|.
void RegisterAllFeatureVariationParameters(FlagsStorage* flags_storage,
base::FeatureList* feature_list);
// Gets the list of feature entries. Entries that are available for the // Gets the list of feature entries. Entries that are available for the
// current platform are appended to |supported_entries|; all other entries are // current platform are appended to |supported_entries|; all other entries are
......
...@@ -267,10 +267,13 @@ TEST_F(FlagsStateTest, ConvertFlagsToSwitches) { ...@@ -267,10 +267,13 @@ TEST_F(FlagsStateTest, ConvertFlagsToSwitches) {
TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) { TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) {
const FeatureEntry& entry = kEntries[7]; const FeatureEntry& entry = kEntries[7];
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
// Select the "Default" variation. // Select the "Default" variation.
flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(0), flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(0),
true); true);
flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_); flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_,
feature_list.get());
// No value should be associated. // No value should be associated.
EXPECT_EQ("", variations::GetVariationParamValue(kTestTrial, kTestParam)); EXPECT_EQ("", variations::GetVariationParamValue(kTestTrial, kTestParam));
// The trial should not be created. // The trial should not be created.
...@@ -281,7 +284,8 @@ TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) { ...@@ -281,7 +284,8 @@ TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) {
flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(1), flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(1),
true); true);
flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_); flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_,
feature_list.get());
// No value should be associated as this is the default option. // No value should be associated as this is the default option.
EXPECT_EQ("", EXPECT_EQ("",
variations::GetVariationParamValue(kTestTrial, kTestParam)); variations::GetVariationParamValue(kTestTrial, kTestParam));
...@@ -295,7 +299,8 @@ TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) { ...@@ -295,7 +299,8 @@ TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) {
// Select the only one variation. // Select the only one variation.
flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(2), flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(2),
true); true);
flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_); flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_,
feature_list.get());
// Associating for the second time should not change the value. // Associating for the second time should not change the value.
EXPECT_EQ("", EXPECT_EQ("",
variations::GetVariationParamValue(kTestTrial, kTestParam)); variations::GetVariationParamValue(kTestTrial, kTestParam));
...@@ -303,13 +308,26 @@ TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) { ...@@ -303,13 +308,26 @@ TEST_F(FlagsStateTest, RegisterAllFeatureVariationParameters) {
TEST_F(FlagsStateTest, RegisterAllFeatureVariationParametersNonDefault) { TEST_F(FlagsStateTest, RegisterAllFeatureVariationParametersNonDefault) {
const FeatureEntry& entry = kEntries[7]; const FeatureEntry& entry = kEntries[7];
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
// Select the only one variation. // Select the only one variation.
flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(2), flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForOption(2),
true); true);
flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_); flags_state_->RegisterAllFeatureVariationParameters(&flags_storage_,
feature_list.get());
// Set the feature_list as the main instance so that
// variations::GetVariationParamValueByFeature below works.
base::FeatureList::ClearInstanceForTesting();
base::FeatureList::SetInstance(std::move(feature_list));
// The param should have the value predefined in this variation. // The param should have the value predefined in this variation.
EXPECT_EQ(kTestParamValue, EXPECT_EQ(kTestParamValue,
variations::GetVariationParamValue(kTestTrial, kTestParam)); variations::GetVariationParamValue(kTestTrial, kTestParam));
// The value should be associated also via the name of the feature.
EXPECT_EQ(kTestParamValue, variations::GetVariationParamValueByFeature(
kTestFeature2, kTestParam));
} }
base::CommandLine::StringType CreateSwitch(const std::string& value) { base::CommandLine::StringType CreateSwitch(const std::string& value) {
......
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