diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/flags_ui | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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.gn | 2 | ||||
-rw-r--r-- | chromium/components/flags_ui/feature_entry.cc | 38 | ||||
-rw-r--r-- | chromium/components/flags_ui/feature_entry.h | 87 | ||||
-rw-r--r-- | chromium/components/flags_ui/feature_entry_macros.h | 50 | ||||
-rw-r--r-- | chromium/components/flags_ui/flags_state.cc | 80 | ||||
-rw-r--r-- | chromium/components/flags_ui/flags_state_unittest.cc | 43 | ||||
-rw-r--r-- | chromium/components/flags_ui/flags_test_helpers.cc | 3 | ||||
-rw-r--r-- | chromium/components/flags_ui/flags_ui_metrics.cc | 77 | ||||
-rw-r--r-- | chromium/components/flags_ui/flags_ui_metrics.h | 35 | ||||
-rw-r--r-- | chromium/components/flags_ui/pref_service_flags_storage.cc | 1 | ||||
-rw-r--r-- | chromium/components/flags_ui/resources/flags.html | 6 | ||||
-rw-r--r-- | chromium/components/flags_ui/resources/flags.js | 4 |
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); } |