summaryrefslogtreecommitdiff
path: root/chromium/components/flags_ui
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/flags_ui
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/flags_ui')
-rw-r--r--chromium/components/flags_ui/BUILD.gn2
-rw-r--r--chromium/components/flags_ui/feature_entry.cc38
-rw-r--r--chromium/components/flags_ui/feature_entry.h87
-rw-r--r--chromium/components/flags_ui/feature_entry_macros.h50
-rw-r--r--chromium/components/flags_ui/flags_state.cc80
-rw-r--r--chromium/components/flags_ui/flags_state_unittest.cc43
-rw-r--r--chromium/components/flags_ui/flags_test_helpers.cc3
-rw-r--r--chromium/components/flags_ui/flags_ui_metrics.cc77
-rw-r--r--chromium/components/flags_ui/flags_ui_metrics.h35
-rw-r--r--chromium/components/flags_ui/pref_service_flags_storage.cc1
-rw-r--r--chromium/components/flags_ui/resources/flags.html6
-rw-r--r--chromium/components/flags_ui/resources/flags.js4
12 files changed, 282 insertions, 144 deletions
diff --git a/chromium/components/flags_ui/BUILD.gn b/chromium/components/flags_ui/BUILD.gn
index 7d37afbf8e8..b89290b6c6e 100644
--- a/chromium/components/flags_ui/BUILD.gn
+++ b/chromium/components/flags_ui/BUILD.gn
@@ -12,6 +12,8 @@ static_library("flags_ui") {
"flags_storage.h",
"flags_ui_constants.cc",
"flags_ui_constants.h",
+ "flags_ui_metrics.cc",
+ "flags_ui_metrics.h",
"flags_ui_pref_names.cc",
"flags_ui_pref_names.h",
"pref_service_flags_storage.cc",
diff --git a/chromium/components/flags_ui/feature_entry.cc b/chromium/components/flags_ui/feature_entry.cc
index 384393fa529..5298b138795 100644
--- a/chromium/components/flags_ui/feature_entry.cc
+++ b/chromium/components/flags_ui/feature_entry.cc
@@ -44,7 +44,21 @@ bool FeatureEntry::InternalNameMatches(const std::string& name) const {
return name.size() > internal_name_length + 1 &&
name[internal_name_length] == kMultiSeparatorChar &&
base::StringToInt(name.substr(internal_name_length + 1), &index) &&
- index >= 0 && index < num_options;
+ index >= 0 && index < NumOptions();
+ }
+}
+
+int FeatureEntry::NumOptions() const {
+ switch (type) {
+ case ENABLE_DISABLE_VALUE:
+ case FEATURE_VALUE:
+ return 3;
+ case MULTI_VALUE:
+ return choices.size();
+ case FEATURE_WITH_PARAMS_VALUE:
+ return 3 + feature.feature_variations.size();
+ default:
+ return 0;
}
}
@@ -53,7 +67,7 @@ std::string FeatureEntry::NameForOption(int index) const {
type == FeatureEntry::ENABLE_DISABLE_VALUE ||
type == FeatureEntry::FEATURE_VALUE ||
type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE);
- DCHECK_LT(index, num_options);
+ DCHECK_LT(index, NumOptions());
return std::string(internal_name) + testing::kMultiSeparator +
base::NumberToString(index);
}
@@ -63,7 +77,7 @@ base::string16 FeatureEntry::DescriptionForOption(int index) const {
type == FeatureEntry::ENABLE_DISABLE_VALUE ||
type == FeatureEntry::FEATURE_VALUE ||
type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE);
- DCHECK_LT(index, num_options);
+ DCHECK_LT(index, NumOptions());
const char* description = nullptr;
if (type == FeatureEntry::ENABLE_DISABLE_VALUE ||
type == FeatureEntry::FEATURE_VALUE) {
@@ -77,16 +91,16 @@ base::string16 FeatureEntry::DescriptionForOption(int index) const {
description = kGenericExperimentChoiceDefault;
} else if (index == 1) {
description = kGenericExperimentChoiceEnabled;
- } else if (index < num_options - 1) {
+ } else if (index < NumOptions() - 1) {
// First two options do not have variations params.
int variation_index = index - 2;
return base::ASCIIToUTF16(
base::StringPiece(kGenericExperimentChoiceEnabled)) +
base::ASCIIToUTF16(" ") +
base::ASCIIToUTF16(
- feature_variations[variation_index].description_text);
+ feature.feature_variations[variation_index].description_text);
} else {
- DCHECK_EQ(num_options - 1, index);
+ DCHECK_EQ(NumOptions() - 1, index);
description = kGenericExperimentChoiceDisabled;
}
} else {
@@ -97,7 +111,7 @@ base::string16 FeatureEntry::DescriptionForOption(int index) const {
const FeatureEntry::Choice& FeatureEntry::ChoiceForOption(int index) const {
DCHECK_EQ(FeatureEntry::MULTI_VALUE, type);
- DCHECK_LT(index, num_options);
+ DCHECK_LT(index, NumOptions());
return choices[index];
}
@@ -105,11 +119,11 @@ const FeatureEntry::Choice& FeatureEntry::ChoiceForOption(int index) const {
FeatureEntry::FeatureState FeatureEntry::StateForOption(int index) const {
DCHECK(type == FeatureEntry::FEATURE_VALUE ||
type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE);
- DCHECK_LT(index, num_options);
+ DCHECK_LT(index, NumOptions());
if (index == 0)
return FeatureEntry::FeatureState::DEFAULT;
- if (index == num_options - 1)
+ if (index == NumOptions() - 1)
return FeatureEntry::FeatureState::DISABLED;
return FeatureEntry::FeatureState::ENABLED;
}
@@ -118,14 +132,14 @@ const FeatureEntry::FeatureVariation* FeatureEntry::VariationForOption(
int index) const {
DCHECK(type == FeatureEntry::FEATURE_VALUE ||
type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE);
- DCHECK_LT(index, num_options);
+ DCHECK_LT(index, NumOptions());
if (type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE && index > 1 &&
- index < num_options - 1) {
+ index < NumOptions() - 1) {
// We have no variations for FEATURE_VALUE type. Option at |index|
// corresponds to variation at |index| - 2 as the list starts with "Default"
// and "Enabled" (with default parameters).
- return &feature_variations[index - 2];
+ return &feature.feature_variations[index - 2];
}
return nullptr;
}
diff --git a/chromium/components/flags_ui/feature_entry.h b/chromium/components/flags_ui/feature_entry.h
index 3e0cfc383bd..167618f45f4 100644
--- a/chromium/components/flags_ui/feature_entry.h
+++ b/chromium/components/flags_ui/feature_entry.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/containers/span.h"
#include "base/strings/string16.h"
namespace base {
@@ -27,7 +28,7 @@ extern const char kGenericExperimentChoiceAutomatic[];
// about_flags entries or deleted. Most feature entries should only be around
// for a few milestones, until their full launch.
struct FeatureEntry {
- enum Type {
+ enum Type : unsigned short {
// A feature with a single flag value.
//
// For new entries, it is recommended to instead use FEATURE_VALUE macro
@@ -72,8 +73,9 @@ struct FeatureEntry {
// passed from the server in a trial config). When set to Enabled, the
// feature is overriden to be enabled and empty set of parameters is used
// boiling down to the default behavior in the code.
- // TODO(crbug.com/805766): The resulting chrome://flags entries will not work on Chrome OS
- // devices (but will work in the CrOS-emulated build on Linux).
+ // TODO(crbug.com/805766): The resulting chrome://flags entries will not
+ // work on Chrome OS devices (but will work in the CrOS-emulated build on
+ // Linux).
FEATURE_WITH_PARAMS_VALUE,
// Corresponds to a command line switch where the value is treatead as a
@@ -140,52 +142,59 @@ struct FeatureEntry {
// The platforms the feature is available on.
// Needs to be more than a compile-time #ifdef because of profile sync.
- unsigned supported_platforms; // bitmask
+ unsigned short supported_platforms; // bitmask
// Type of entry.
Type type;
- // The commandline switch and value that are added when this flag is active.
- // This is different from |internal_name| so that the commandline flag can be
- // renamed without breaking the prefs file.
- // This is used if type is SINGLE_VALUE or ENABLE_DISABLE_VALUE.
- const char* command_line_switch;
-
- // Simple switches that have no value should use "" for command_line_value.
- const char* command_line_value;
-
- // For ENABLE_DISABLE_VALUE, the command line switch and value to explicitly
- // disable the feature.
- const char* disable_command_line_switch;
- const char* disable_command_line_value;
-
- // For FEATURE_VALUE or FEATURE_WITH_VARIATIONS_VALUE, the base::Feature this
- // entry corresponds to. The same feature must not be used in multiple
- // FeatureEntries.
- const base::Feature* feature;
-
- // Number of options to choose from. This is used if type is MULTI_VALUE,
- // ENABLE_DISABLE_VALUE, FEATURE_VALUE, or FEATURE_WITH_VARIATIONS_VALUE.
- int num_options;
-
- // This describes the options if type is MULTI_VALUE.
- const Choice* choices;
-
- // This describes the options if type is FEATURE_WITH_VARIATIONS_VALUE.
- // The first variation is the default "Enabled" variation, its description_id
- // is disregarded.
- const FeatureVariation* feature_variations;
-
- // The name of the FieldTrial in which the selected variation parameters
- // should be registered. This is used if type is
- // FEATURE_WITH_VARIATIONS_VALUE.
- const char* feature_trial_name;
+ union {
+ struct {
+ // The commandline switch and value that are added when this flag is
+ // active. This is different from |internal_name| so that the commandline
+ // flag can be renamed without breaking the prefs file. This is used if
+ // type is SINGLE_VALUE or ENABLE_DISABLE_VALUE.
+ const char* command_line_switch;
+
+ // Simple switches that have no value should use "" for
+ // command_line_value.
+ const char* command_line_value;
+
+ // For ENABLE_DISABLE_VALUE, the command line switch and value to
+ // explicitly disable the feature.
+ const char* disable_command_line_switch;
+ const char* disable_command_line_value;
+ } switches;
+
+ struct {
+ // For FEATURE_VALUE or FEATURE_WITH_VARIATIONS_VALUE, the base::Feature
+ // this entry corresponds to. The same feature must not be used in
+ // multiple FeatureEntries.
+ const base::Feature* feature;
+
+ // This describes the options if type is FEATURE_WITH_VARIATIONS_VALUE.
+ // The first variation is the default "Enabled" variation, its
+ // description_id is disregarded.
+ base::span<const FeatureVariation> feature_variations;
+
+ // The name of the FieldTrial in which the selected variation parameters
+ // should be registered. This is used if type is
+ // FEATURE_WITH_VARIATIONS_VALUE.
+ const char* feature_trial_name;
+ } feature;
+
+ // This describes the options if type is MULTI_VALUE.
+ base::span<const Choice> choices;
+ };
// Check whether internal |name| matches this FeatureEntry. Depending on the
// type of entry, this compared it to either |internal_name| or the values
// produced by NameForOption().
bool InternalNameMatches(const std::string& name) const;
+ // Number of options to choose from. This is used if type is MULTI_VALUE,
+ // ENABLE_DISABLE_VALUE, FEATURE_VALUE, or FEATURE_WITH_PARAMS_VALUE.
+ int NumOptions() const;
+
// Returns the name used in prefs for the option at the specified |index|.
// Only used for types that use |num_options|.
std::string NameForOption(int index) const;
diff --git a/chromium/components/flags_ui/feature_entry_macros.h b/chromium/components/flags_ui/feature_entry_macros.h
index 02bceb73118..132f094c5ec 100644
--- a/chromium/components/flags_ui/feature_entry_macros.h
+++ b/chromium/components/flags_ui/feature_entry_macros.h
@@ -10,35 +10,39 @@
// Macros to simplify specifying the type of FeatureEntry. Please refer to
// the comments on FeatureEntry::Type in feature_entry.h, which explain the
// different entry types and when they should be used.
-#define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \
- flags_ui::FeatureEntry::SINGLE_VALUE, command_line_switch, switch_value, \
- nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr
+#define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \
+ flags_ui::FeatureEntry::SINGLE_VALUE, { \
+ .switches = { command_line_switch, switch_value, nullptr, nullptr } \
+ }
#define SINGLE_VALUE_TYPE(command_line_switch) \
SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, "")
-#define ORIGIN_LIST_VALUE_TYPE(command_line_switch, switch_value) \
- flags_ui::FeatureEntry::ORIGIN_LIST_VALUE, command_line_switch, \
- switch_value, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr
+#define ORIGIN_LIST_VALUE_TYPE(command_line_switch, switch_value) \
+ flags_ui::FeatureEntry::ORIGIN_LIST_VALUE, { \
+ .switches = { command_line_switch, switch_value, nullptr, nullptr } \
+ }
#define SINGLE_DISABLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \
- flags_ui::FeatureEntry::SINGLE_DISABLE_VALUE, command_line_switch, \
- switch_value, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr
+ flags_ui::FeatureEntry::SINGLE_DISABLE_VALUE, { \
+ .switches = { command_line_switch, switch_value, nullptr, nullptr } \
+ }
#define SINGLE_DISABLE_VALUE_TYPE(command_line_switch) \
SINGLE_DISABLE_VALUE_TYPE_AND_VALUE(command_line_switch, "")
-#define ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, enable_value, \
- disable_switch, disable_value) \
- flags_ui::FeatureEntry::ENABLE_DISABLE_VALUE, enable_switch, enable_value, \
- disable_switch, disable_value, nullptr, 3, nullptr, nullptr, nullptr
+#define ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, enable_value, \
+ disable_switch, disable_value) \
+ flags_ui::FeatureEntry::ENABLE_DISABLE_VALUE, { \
+ .switches = { enable_switch, enable_value, disable_switch, disable_value } \
+ }
#define ENABLE_DISABLE_VALUE_TYPE(enable_switch, disable_switch) \
ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, "", disable_switch, "")
-#define MULTI_VALUE_TYPE(choices) \
- flags_ui::FeatureEntry::MULTI_VALUE, nullptr, nullptr, nullptr, nullptr, \
- nullptr, base::size(choices), choices, nullptr, nullptr
-#define FEATURE_VALUE_TYPE(feature) \
- flags_ui::FeatureEntry::FEATURE_VALUE, nullptr, nullptr, nullptr, nullptr, \
- &feature, 3, nullptr, nullptr, nullptr
-#define FEATURE_WITH_PARAMS_VALUE_TYPE(feature, feature_variations, \
- feature_trial) \
- flags_ui::FeatureEntry::FEATURE_WITH_PARAMS_VALUE, nullptr, nullptr, \
- nullptr, nullptr, &feature, 3 + base::size(feature_variations), nullptr, \
- feature_variations, feature_trial
+#define MULTI_VALUE_TYPE(choices_list) \
+ flags_ui::FeatureEntry::MULTI_VALUE, { .choices = choices_list }
+#define FEATURE_VALUE_TYPE(feature_entry) \
+ flags_ui::FeatureEntry::FEATURE_VALUE, { \
+ .feature = { &feature_entry, {}, nullptr } \
+ }
+#define FEATURE_WITH_PARAMS_VALUE_TYPE(feature_entry, feature_variations, \
+ feature_trial) \
+ flags_ui::FeatureEntry::FEATURE_WITH_PARAMS_VALUE, { \
+ .feature = { &feature_entry, feature_variations, feature_trial } \
+ }
#endif // COMPONENTS_FLAGS_UI_FEATURE_ENTRY_MACROS_H_
diff --git a/chromium/components/flags_ui/flags_state.cc b/chromium/components/flags_ui/flags_state.cc
index 5156abf5c1b..ed3dbdf768e 100644
--- a/chromium/components/flags_ui/flags_state.cc
+++ b/chromium/components/flags_ui/flags_state.cc
@@ -124,34 +124,25 @@ bool IsValidFeatureEntry(const FeatureEntry& e) {
case FeatureEntry::SINGLE_VALUE:
case FeatureEntry::SINGLE_DISABLE_VALUE:
case FeatureEntry::ORIGIN_LIST_VALUE:
- DCHECK_EQ(0, e.num_options);
- DCHECK(!e.choices);
return true;
case FeatureEntry::MULTI_VALUE:
- DCHECK_GT(e.num_options, 0);
- DCHECK(e.choices);
+ DCHECK_GT(e.choices.size(), 0u);
DCHECK(e.ChoiceForOption(0).command_line_switch);
DCHECK_EQ('\0', e.ChoiceForOption(0).command_line_switch[0]);
return true;
case FeatureEntry::ENABLE_DISABLE_VALUE:
- DCHECK_EQ(3, e.num_options);
- DCHECK(!e.choices);
- DCHECK(e.command_line_switch);
- DCHECK(e.command_line_value);
- DCHECK(e.disable_command_line_switch);
- DCHECK(e.disable_command_line_value);
+ DCHECK(e.switches.command_line_switch);
+ DCHECK(e.switches.command_line_value);
+ DCHECK(e.switches.disable_command_line_switch);
+ DCHECK(e.switches.disable_command_line_value);
return true;
case FeatureEntry::FEATURE_VALUE:
- DCHECK_EQ(3, e.num_options);
- DCHECK(!e.choices);
- DCHECK(e.feature);
+ DCHECK(e.feature.feature);
return true;
case FeatureEntry::FEATURE_WITH_PARAMS_VALUE:
- DCHECK_GT(e.num_options, 2);
- DCHECK(!e.choices);
- DCHECK(e.feature);
- DCHECK(e.feature_variations);
- DCHECK(e.feature_trial_name);
+ DCHECK(e.feature.feature);
+ DCHECK(e.feature.feature_variations.size());
+ DCHECK(e.feature.feature_trial_name);
return true;
}
NOTREACHED();
@@ -170,7 +161,7 @@ bool IsDefaultValue(const FeatureEntry& entry,
case FeatureEntry::ENABLE_DISABLE_VALUE:
case FeatureEntry::FEATURE_VALUE:
case FeatureEntry::FEATURE_WITH_PARAMS_VALUE:
- for (int i = 0; i < entry.num_options; ++i) {
+ for (int i = 0; i < entry.NumOptions(); ++i) {
if (enabled_entries.count(entry.NameForOption(i)) > 0)
return false;
}
@@ -189,7 +180,7 @@ std::unique_ptr<base::Value> CreateOptionsData(
entry.type == FeatureEntry::FEATURE_VALUE ||
entry.type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE);
auto result = std::make_unique<base::ListValue>();
- for (int i = 0; i < entry.num_options; ++i) {
+ for (int i = 0; i < entry.NumOptions(); ++i) {
auto value = std::make_unique<base::DictionaryValue>();
const std::string name = entry.NameForOption(i);
value->SetString("internal_name", name);
@@ -305,7 +296,7 @@ std::string GetCombinedOriginListValue(const FlagsStorage& flags_storage,
void DidModifyOriginListFlag(const FlagsStorage& flags_storage,
const FeatureEntry& entry) {
const std::string new_value = GetCombinedOriginListValue(
- flags_storage, entry.internal_name, entry.command_line_switch);
+ flags_storage, entry.internal_name, entry.switches.command_line_switch);
// Remove the switch if it exists.
base::CommandLine* current_cl = base::CommandLine::ForCurrentProcess();
@@ -314,7 +305,7 @@ void DidModifyOriginListFlag(const FlagsStorage& flags_storage,
for (const auto& it : switches) {
const auto& switch_name = it.first;
const auto& switch_value = it.second;
- if (switch_name != entry.command_line_switch) {
+ if (switch_name != entry.switches.command_line_switch) {
if (switch_value.empty()) {
new_cl.AppendSwitch(switch_name);
} else {
@@ -326,7 +317,7 @@ void DidModifyOriginListFlag(const FlagsStorage& flags_storage,
const std::string sanitized =
CombineAndSanitizeOriginLists(std::string(), new_value);
- current_cl->AppendSwitchASCII(entry.command_line_switch, sanitized);
+ current_cl->AppendSwitchASCII(entry.switches.command_line_switch, sanitized);
}
#endif
@@ -460,7 +451,7 @@ void FlagsState::SetFeatureEntryEnabled(FlagsStorage* flags_storage,
needs_restart_ |= enabled_entries.insert(e->NameForOption(0)).second;
} else {
// Find the currently enabled choice and disable it.
- for (int i = 0; i < e->num_options; ++i) {
+ for (int i = 0; i < e->NumOptions(); ++i) {
std::string choice_name = e->NameForOption(i);
if (enabled_entries.find(choice_name) != enabled_entries.end()) {
needs_restart_ = true;
@@ -564,13 +555,13 @@ std::vector<std::string> FlagsState::RegisterAllFeatureVariationParameters(
// First collect all the data for each trial.
for (const FeatureEntry& entry : feature_entries_) {
if (entry.type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE) {
- for (int j = 0; j < entry.num_options; ++j) {
+ for (int j = 0; j < entry.NumOptions(); ++j) {
if (entry.StateForOption(j) == FeatureEntry::FeatureState::ENABLED &&
enabled_entries.count(entry.NameForOption(j))) {
- std::string trial_name = entry.feature_trial_name;
+ std::string trial_name = entry.feature.feature_trial_name;
// The user has chosen to enable the feature by this option.
enabled_features_by_trial_name[trial_name].insert(
- entry.feature->name);
+ entry.feature.feature->name);
const FeatureEntry::FeatureVariation* variation =
entry.VariationForOption(j);
@@ -658,7 +649,7 @@ void FlagsState::GetFlagFeatureEntries(
data->SetString(
"origin_list_value",
GetCombinedOriginListValue(*flags_storage, entry.internal_name,
- entry.command_line_switch));
+ entry.switches.command_line_switch));
break;
case FeatureEntry::MULTI_VALUE:
case FeatureEntry::ENABLE_DISABLE_VALUE:
@@ -884,8 +875,9 @@ void FlagsState::GenerateFlagsToSwitchesMapping(
switch (entry.type) {
case FeatureEntry::SINGLE_VALUE:
case FeatureEntry::SINGLE_DISABLE_VALUE:
- AddSwitchMapping(entry.internal_name, entry.command_line_switch,
- entry.command_line_value, name_to_switch_map);
+ AddSwitchMapping(entry.internal_name,
+ entry.switches.command_line_switch,
+ entry.switches.command_line_value, name_to_switch_map);
break;
case FeatureEntry::ORIGIN_LIST_VALUE: {
@@ -893,15 +885,17 @@ void FlagsState::GenerateFlagsToSwitchesMapping(
// This is done to retain the existing list from the command line when
// the browser is restarted. Otherwise, the user provided list would
// overwrite the list provided from the command line.
- const std::string origin_list_value = GetCombinedOriginListValue(
- *flags_storage, entry.internal_name, entry.command_line_switch);
- AddSwitchMapping(entry.internal_name, entry.command_line_switch,
- origin_list_value, name_to_switch_map);
+ const std::string origin_list_value =
+ GetCombinedOriginListValue(*flags_storage, entry.internal_name,
+ entry.switches.command_line_switch);
+ AddSwitchMapping(entry.internal_name,
+ entry.switches.command_line_switch, origin_list_value,
+ name_to_switch_map);
break;
}
case FeatureEntry::MULTI_VALUE:
- for (int j = 0; j < entry.num_options; ++j) {
+ for (int j = 0; j < entry.NumOptions(); ++j) {
AddSwitchMapping(entry.NameForOption(j),
entry.ChoiceForOption(j).command_line_switch,
entry.ChoiceForOption(j).command_line_value,
@@ -912,22 +906,24 @@ void FlagsState::GenerateFlagsToSwitchesMapping(
case FeatureEntry::ENABLE_DISABLE_VALUE:
AddSwitchMapping(entry.NameForOption(0), std::string(), std::string(),
name_to_switch_map);
- AddSwitchMapping(entry.NameForOption(1), entry.command_line_switch,
- entry.command_line_value, name_to_switch_map);
- AddSwitchMapping(entry.NameForOption(2),
- entry.disable_command_line_switch,
- entry.disable_command_line_value, name_to_switch_map);
+ AddSwitchMapping(entry.NameForOption(1),
+ entry.switches.command_line_switch,
+ entry.switches.command_line_value, name_to_switch_map);
+ AddSwitchMapping(
+ entry.NameForOption(2), entry.switches.disable_command_line_switch,
+ entry.switches.disable_command_line_value, name_to_switch_map);
break;
case FeatureEntry::FEATURE_VALUE:
case FeatureEntry::FEATURE_WITH_PARAMS_VALUE:
- for (int j = 0; j < entry.num_options; ++j) {
+ for (int j = 0; j < entry.NumOptions(); ++j) {
FeatureEntry::FeatureState state = entry.StateForOption(j);
if (state == FeatureEntry::FeatureState::DEFAULT) {
AddFeatureMapping(entry.NameForOption(j), std::string(), false,
name_to_switch_map);
} else {
- AddFeatureMapping(entry.NameForOption(j), entry.feature->name,
+ AddFeatureMapping(entry.NameForOption(j),
+ entry.feature.feature->name,
state == FeatureEntry::FeatureState::ENABLED,
name_to_switch_map);
}
diff --git a/chromium/components/flags_ui/flags_state_unittest.cc b/chromium/components/flags_ui/flags_state_unittest.cc
index e793a6415b7..57db24ecc79 100644
--- a/chromium/components/flags_ui/flags_state_unittest.cc
+++ b/chromium/components/flags_ui/flags_state_unittest.cc
@@ -22,6 +22,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "components/flags_ui/feature_entry.h"
+#include "components/flags_ui/feature_entry_macros.h"
#include "components/flags_ui/flags_ui_pref_names.h"
#include "components/flags_ui/flags_ui_switches.h"
#include "components/flags_ui/pref_service_flags_storage.h"
@@ -109,47 +110,45 @@ const FeatureEntry::Choice kMultiChoices[] = {
static FeatureEntry kEntries[] = {
{kFlags1, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::SINGLE_VALUE, kSwitch1, "", nullptr, nullptr, nullptr, 0,
- nullptr, nullptr, nullptr},
+ SINGLE_VALUE_TYPE(kSwitch1)},
{kFlags2, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::SINGLE_VALUE, kSwitch2, kValueForSwitch2, nullptr, nullptr,
- nullptr, 0, nullptr, nullptr, nullptr},
+ SINGLE_VALUE_TYPE_AND_VALUE(kSwitch2, kValueForSwitch2)},
{kFlags3, kDummyName, kDummyDescription,
0, // This ends up enabling for an OS other than the current.
- FeatureEntry::SINGLE_VALUE, kSwitch3, "", nullptr, nullptr, nullptr, 0,
- nullptr, nullptr, nullptr},
+ SINGLE_VALUE_TYPE(kSwitch3)},
{kFlags4, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::MULTI_VALUE, "", "", "", "", nullptr,
- base::size(kMultiChoices), kMultiChoices, nullptr, nullptr},
+ MULTI_VALUE_TYPE(kMultiChoices)},
{kFlags5, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::ENABLE_DISABLE_VALUE, kSwitch1, kEnableDisableValue1,
- kSwitch2, kEnableDisableValue2, nullptr, 3, nullptr, nullptr, nullptr},
+ ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(kSwitch1,
+ kEnableDisableValue1,
+ kSwitch2,
+ kEnableDisableValue2)},
{kFlags6, kDummyName, kDummyDescription, 0,
- FeatureEntry::SINGLE_DISABLE_VALUE, kSwitch6, "", nullptr, nullptr,
- nullptr, 0, nullptr, nullptr, nullptr},
+ SINGLE_DISABLE_VALUE_TYPE(kSwitch6)},
{kFlags7, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::FEATURE_VALUE, nullptr, nullptr, nullptr, nullptr,
- &kTestFeature1, 3, nullptr, nullptr, nullptr},
+ FEATURE_VALUE_TYPE(kTestFeature1)},
{kFlags8, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::FEATURE_WITH_PARAMS_VALUE, nullptr, nullptr, nullptr,
- nullptr, &kTestFeature1, 4, nullptr, kTestVariations1, kTestTrial},
+ FEATURE_WITH_PARAMS_VALUE_TYPE(kTestFeature1,
+ kTestVariations1,
+ kTestTrial)},
{kFlags9, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::FEATURE_WITH_PARAMS_VALUE, nullptr, nullptr, nullptr,
- nullptr, &kTestFeature1, 4, nullptr, kTestVariations1, kTestTrial},
+ FEATURE_WITH_PARAMS_VALUE_TYPE(kTestFeature1,
+ kTestVariations1,
+ kTestTrial)},
{kFlags10, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::FEATURE_WITH_PARAMS_VALUE, nullptr, nullptr, nullptr,
- nullptr, &kTestFeature2, 4, nullptr, kTestVariations2, kTestTrial},
+ FEATURE_WITH_PARAMS_VALUE_TYPE(kTestFeature2,
+ kTestVariations2,
+ kTestTrial)},
{kFlags11, kDummyName, kDummyDescription,
0, // Ends up being mapped to the current platform.
- FeatureEntry::ORIGIN_LIST_VALUE, kStringSwitch, kValueForStringSwitch,
- nullptr, nullptr, nullptr /* feature */, 0, nullptr, nullptr, nullptr}};
+ ORIGIN_LIST_VALUE_TYPE(kStringSwitch, kValueForStringSwitch)}};
class FlagsStateTest : public ::testing::Test,
public flags_ui::FlagsState::Delegate {
diff --git a/chromium/components/flags_ui/flags_test_helpers.cc b/chromium/components/flags_ui/flags_test_helpers.cc
index 23a669a4a40..990e9bcb1b1 100644
--- a/chromium/components/flags_ui/flags_test_helpers.cc
+++ b/chromium/components/flags_ui/flags_test_helpers.cc
@@ -177,7 +177,8 @@ bool IsUnexpireFlagFor(const flags_ui::FeatureEntry& entry, int milestone) {
return false;
std::string expected_feature =
base::StringPrintf("UnexpireFlagsM%d", milestone);
- if (!entry.feature || entry.feature->name != expected_feature)
+ const auto* feature = entry.feature.feature;
+ if (!feature || feature->name != expected_feature)
return false;
return true;
}
diff --git a/chromium/components/flags_ui/flags_ui_metrics.cc b/chromium/components/flags_ui/flags_ui_metrics.cc
new file mode 100644
index 00000000000..5ff37150cd9
--- /dev/null
+++ b/chromium/components/flags_ui/flags_ui_metrics.cc
@@ -0,0 +1,77 @@
+// Copyright 2020 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/flags_ui/flags_ui_metrics.h"
+
+#include <set>
+#include <string>
+
+#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/metrics_hashes.h"
+#include "base/notreached.h"
+#include "base/strings/string_util.h"
+
+namespace flags_ui {
+
+namespace {
+
+// Records a set of feature switches (prefixed with "--").
+void ReportAboutFlagsHistogramSwitches(const std::string& uma_histogram_name,
+ const std::set<std::string>& switches) {
+ for (const std::string& flag : switches) {
+ int uma_id = testing::kBadSwitchFormatHistogramId;
+ if (base::StartsWith(flag, "--", base::CompareCase::SENSITIVE)) {
+ // Skip '--' before switch name.
+ std::string switch_name(flag.substr(2));
+
+ // Kill value, if any.
+ const size_t value_pos = switch_name.find('=');
+ if (value_pos != std::string::npos)
+ switch_name.resize(value_pos);
+
+ uma_id = GetSwitchUMAId(switch_name);
+ } else {
+ NOTREACHED() << "ReportAboutFlagsHistogram(): flag '" << flag
+ << "' has incorrect format.";
+ }
+ DVLOG(1) << "ReportAboutFlagsHistogram(): histogram='" << uma_histogram_name
+ << "' '" << flag << "', uma_id=" << uma_id;
+ base::UmaHistogramSparse(uma_histogram_name, uma_id);
+ }
+}
+
+// Records a set of FEATURE_VALUE_TYPE features (suffixed with ":enabled" or
+// "disabled", depending on their state).
+void ReportAboutFlagsHistogramFeatures(const std::string& uma_histogram_name,
+ const std::set<std::string>& features) {
+ for (const std::string& feature : features) {
+ int uma_id = GetSwitchUMAId(feature);
+ DVLOG(1) << "ReportAboutFlagsHistogram(): histogram='" << uma_histogram_name
+ << "' '" << feature << "', uma_id=" << uma_id;
+ base::UmaHistogramSparse(uma_histogram_name, uma_id);
+ }
+}
+
+} // namespace
+
+base::HistogramBase::Sample GetSwitchUMAId(const std::string& switch_name) {
+ return static_cast<base::HistogramBase::Sample>(
+ base::HashMetricName(switch_name));
+}
+
+void ReportAboutFlagsHistogram(const std::string& uma_histogram_name,
+ const std::set<std::string>& switches,
+ const std::set<std::string>& features) {
+ ReportAboutFlagsHistogramSwitches(uma_histogram_name, switches);
+ ReportAboutFlagsHistogramFeatures(uma_histogram_name, features);
+}
+
+namespace testing {
+
+const base::HistogramBase::Sample kBadSwitchFormatHistogramId = 0;
+
+} // namespace testing
+
+} // namespace flags_ui
diff --git a/chromium/components/flags_ui/flags_ui_metrics.h b/chromium/components/flags_ui/flags_ui_metrics.h
new file mode 100644
index 00000000000..792a32f0295
--- /dev/null
+++ b/chromium/components/flags_ui/flags_ui_metrics.h
@@ -0,0 +1,35 @@
+// Copyright 2020 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_FLAGS_UI_FLAGS_UI_METRICS_H_
+#define COMPONENTS_FLAGS_UI_FLAGS_UI_METRICS_H_
+
+#include <set>
+#include <string>
+
+#include "base/metrics/histogram_base.h"
+
+namespace flags_ui {
+
+// Returns the UMA id for the specified switch name.
+base::HistogramBase::Sample GetSwitchUMAId(const std::string& switch_name);
+
+// Sends stats (as UMA histogram) about a set of command line |flags| in
+// a histogram, with an enum value for each flag in |switches| and |features|,
+// based on the hash of the flag name.
+void ReportAboutFlagsHistogram(const std::string& uma_histogram_name,
+ const std::set<std::string>& switches,
+ const std::set<std::string>& features);
+
+namespace testing {
+
+// This value is reported as switch histogram ID if switch name has unknown
+// format.
+extern const base::HistogramBase::Sample kBadSwitchFormatHistogramId;
+
+} // namespace testing
+
+} // namespace flags_ui
+
+#endif // COMPONENTS_FLAGS_UI_FLAGS_UI_WITCHES_H_
diff --git a/chromium/components/flags_ui/pref_service_flags_storage.cc b/chromium/components/flags_ui/pref_service_flags_storage.cc
index 178293ab0da..3c57001d1d3 100644
--- a/chromium/components/flags_ui/pref_service_flags_storage.cc
+++ b/chromium/components/flags_ui/pref_service_flags_storage.cc
@@ -4,6 +4,7 @@
#include "components/flags_ui/pref_service_flags_storage.h"
+#include "base/logging.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/flags_ui/flags_ui_pref_names.h"
diff --git a/chromium/components/flags_ui/resources/flags.html b/chromium/components/flags_ui/resources/flags.html
index 52ae93a1b4d..191373be342 100644
--- a/chromium/components/flags_ui/resources/flags.html
+++ b/chromium/components/flags_ui/resources/flags.html
@@ -89,7 +89,7 @@
jsvalues="title: is_default ? '' : '$i18n{experiment-enabled}';
id:internal_name + '_name'"></h3>
<p>
- <span jsvalues=".innerHTML:description"></span> –
+ <span jsvalues=".textContent:description"></span> –
<span class="platforms" jscontent="supported_platforms.join(', ')"></span>
</p>
<div jsdisplay="origin_list_value!==null">
@@ -136,7 +136,7 @@
jsvalues="title: is_default ? '' : '$i18n{experiment-enabled}';
id:internal_name + '_name'"></h3>
<p>
- <span jsvalues=".innerHTML:description"></span> –
+ <span jsvalues=".textContent:description"></span> –
<span class="platforms" jscontent="supported_platforms.join(', ')"></span>
</p>
<div jsdisplay="origin_list_value!==null">
@@ -193,7 +193,7 @@
<h3 class="experiment-name"
jscontent="name"></h3>
<p>
- <span jsvalues=".innerHTML:description"></span>
+ <span jsvalues=".textContent:description"></span>
<span class="platforms" jscontent="supported_platforms.join(', ')"></span>
</p>
<a class="permalink"
diff --git a/chromium/components/flags_ui/resources/flags.js b/chromium/components/flags_ui/resources/flags.js
index 880dff21aba..7030f4a1ca4 100644
--- a/chromium/components/flags_ui/resources/flags.js
+++ b/chromium/components/flags_ui/resources/flags.js
@@ -184,9 +184,9 @@ function restartBrowser() {
* @param {string} text The text that should be announced.
*/
function announceStatus(text) {
- $('screen-reader-status-message').innerHTML = '';
+ $('screen-reader-status-message').textContent = '';
setTimeout(function() {
- $('screen-reader-status-message').innerHTML = text;
+ $('screen-reader-status-message').textContent = text;
}, 100);
}