sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 1 | // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef COMPONENTS_FLAGS_UI_FEATURE_ENTRY_H_ |
| 6 | #define COMPONENTS_FLAGS_UI_FEATURE_ENTRY_H_ |
| 7 | |
| 8 | #include <string> |
| 9 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 10 | #include "base/containers/span.h" |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 11 | |
| 12 | namespace base { |
| 13 | struct Feature; |
| 14 | } |
| 15 | |
| 16 | namespace flags_ui { |
| 17 | |
Elaine Chien | 2f0fe01 | 2021-03-01 19:06:10 | [diff] [blame] | 18 | extern const char kMultiSeparatorChar; |
| 19 | |
vabr | 0215a8e | 2017-03-28 12:47:34 | [diff] [blame] | 20 | // Generic experiment choice option names. |
| 21 | extern const char kGenericExperimentChoiceDefault[]; |
| 22 | extern const char kGenericExperimentChoiceEnabled[]; |
| 23 | extern const char kGenericExperimentChoiceDisabled[]; |
| 24 | extern const char kGenericExperimentChoiceAutomatic[]; |
| 25 | |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 26 | // FeatureEntry is used to describe an experimental feature. |
| 27 | // |
| 28 | // Note that features should eventually be either turned on by default with no |
| 29 | // about_flags entries or deleted. Most feature entries should only be around |
| 30 | // for a few milestones, until their full launch. |
| 31 | struct FeatureEntry { |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 32 | enum Type : unsigned short { |
asvitkine | f8b7390 | 2016-10-11 16:18:16 | [diff] [blame] | 33 | // A feature with a single flag value. |
| 34 | // |
| 35 | // For new entries, it is recommended to instead use FEATURE_VALUE macro |
| 36 | // that is backed by a base::Feature struct. See base/feature_list.h. |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 37 | SINGLE_VALUE, |
| 38 | |
asvitkine | f8b7390 | 2016-10-11 16:18:16 | [diff] [blame] | 39 | // A default enabled feature with a single flag value to disable it. |
| 40 | // |
| 41 | // For new entries, it is recommended to instead use FEATURE_VALUE macro |
| 42 | // that is backed by a base::Feature struct. See base/feature_list.h. |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 43 | SINGLE_DISABLE_VALUE, |
| 44 | |
| 45 | // The feature has multiple values only one of which is ever enabled. |
| 46 | // The first of the values should correspond to a deactivated state for this |
| 47 | // feature (i.e. no command line option). For MULTI_VALUE entries, the |
| 48 | // command_line of the FeatureEntry is not used. If the experiment is |
| 49 | // enabled the command line of the selected Choice is enabled. |
| 50 | MULTI_VALUE, |
| 51 | |
| 52 | // The feature has three possible values: Default, Enabled and Disabled. |
asvitkine | f8b7390 | 2016-10-11 16:18:16 | [diff] [blame] | 53 | // This allows the Default group to have its own logic to determine if the |
| 54 | // feature is on. |
| 55 | // |
| 56 | // For new entries, it is recommended to instead use FEATURE_VALUE macro |
| 57 | // that is backed by a base::Feature struct. See base/feature_list.h. |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 58 | ENABLE_DISABLE_VALUE, |
| 59 | |
| 60 | // Corresponds to a base::Feature, per base/feature_list.h. The entry will |
| 61 | // have three states: Default, Enabled, Disabled. When not specified or set |
| 62 | // to Default, the normal default value of the feature is used. |
asvitkine | f8b7390 | 2016-10-11 16:18:16 | [diff] [blame] | 63 | // |
| 64 | // This is recommended for all new entries, since it provides a uniform way |
| 65 | // to specify features in the codebase along with their default state, as |
| 66 | // well as the ability enable/disable via run server-side experiments. |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 67 | FEATURE_VALUE, |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 68 | |
| 69 | // Corresponds to a base::Feature and additional options [O_1, ..., O_n] |
jkrcal | 531f3675 | 2017-03-22 13:44:25 | [diff] [blame] | 70 | // that specify field trial params. Each of the options can specify a set |
| 71 | // of field trial params. The entry will have n+3 states: Default, Enabled, |
| 72 | // Enabled V_1, ..., Enabled: V_n, Disabled. When set to Default, the normal |
| 73 | // default values of the feature and of the parameters are used (possibly |
| 74 | // passed from the server in a trial config). When set to Enabled, the |
| 75 | // feature is overriden to be enabled and empty set of parameters is used |
| 76 | // boiling down to the default behavior in the code. |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 77 | // TODO(crbug.com/805766): The resulting chrome://flags entries will not |
| 78 | // work on Chrome OS devices (but will work in the CrOS-emulated build on |
| 79 | // Linux). |
jkrcal | 531f3675 | 2017-03-22 13:44:25 | [diff] [blame] | 80 | FEATURE_WITH_PARAMS_VALUE, |
Mustafa Emre Acer | b3aa36a8 | 2018-05-22 21:44:05 | [diff] [blame] | 81 | |
cfredric | faee997 | 2021-10-08 19:24:11 | [diff] [blame] | 82 | // Corresponds to a command line switch where the value is treated as a list |
| 83 | // of url::Origins. (Lists will not be reordered.) Default state is |
| 84 | // disabled like SINGLE_VALUE. |
| 85 | ORIGIN_LIST_VALUE, |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 86 | }; |
| 87 | |
| 88 | // Describes state of a feature. |
| 89 | enum FeatureState { |
| 90 | // The state of the feature is not overridden by the user. |
| 91 | DEFAULT, |
| 92 | // The feature is enabled by the user. |
| 93 | ENABLED, |
| 94 | // The feature is disabled by the user. |
| 95 | DISABLED, |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 96 | }; |
| 97 | |
| 98 | // Used for MULTI_VALUE types to describe one of the possible values the user |
| 99 | // can select. |
| 100 | struct Choice { |
vabr | 0215a8e | 2017-03-28 12:47:34 | [diff] [blame] | 101 | // The message containing the choice name. |
| 102 | const char* description; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 103 | |
| 104 | // Command line switch and value to enabled for this choice. |
| 105 | const char* command_line_switch; |
| 106 | // Simple switches that have no value should use "" for command_line_value. |
| 107 | const char* command_line_value; |
| 108 | }; |
| 109 | |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 110 | // Configures one parameter for FEATURE_WITH_PARAMS_VALUE. |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 111 | struct FeatureParam { |
| 112 | const char* param_name; |
| 113 | const char* param_value; |
| 114 | }; |
| 115 | |
| 116 | // Specified one variation (list of parameter values) for |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 117 | // FEATURE_WITH_PARAMS_VALUE. |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 118 | struct FeatureVariation { |
| 119 | // Text that denotes the variation in chrome://flags. For each variation, |
| 120 | // the user is shown an option labeled "Enabled <description_text>" (with |
| 121 | // the exception of the first option labeled "Enabled" to make clear it is |
| 122 | // the default one). No need for description_id, chrome://flags should not |
| 123 | // get translated. The other parts here use ids for historical reasons and |
| 124 | // can realistically also be moved to direct description_texts. |
| 125 | const char* description_text; |
| 126 | const FeatureParam* params; |
| 127 | int num_params; |
jkrcal | bf07337 | 2016-07-29 07:21:31 | [diff] [blame] | 128 | // A variation id number in the format of |
Ben Goldberger | 72533cd | 2020-07-21 16:11:38 | [diff] [blame] | 129 | // VariationsIdsProvider::ForceVariationIds() or nullptr if you do |
Alexei Svitkine | 105f942e | 2018-02-17 02:53:48 | [diff] [blame] | 130 | // not need to set any variation_id for this feature variation. |
jkrcal | bf07337 | 2016-07-29 07:21:31 | [diff] [blame] | 131 | const char* variation_id; |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 132 | }; |
| 133 | |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 134 | // The internal name of the feature entry. This is never shown to the user. |
| 135 | // It _is_ however stored in the prefs file, so you shouldn't change the |
| 136 | // name of existing flags. |
| 137 | const char* internal_name; |
| 138 | |
vabr | 0215a8e | 2017-03-28 12:47:34 | [diff] [blame] | 139 | // The feature's name. |
| 140 | const char* visible_name; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 141 | |
vabr | 0215a8e | 2017-03-28 12:47:34 | [diff] [blame] | 142 | // The feature's description. |
| 143 | const char* visible_description; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 144 | |
| 145 | // The platforms the feature is available on. |
| 146 | // Needs to be more than a compile-time #ifdef because of profile sync. |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 147 | unsigned short supported_platforms; // bitmask |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 148 | |
| 149 | // Type of entry. |
| 150 | Type type; |
| 151 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 152 | union { |
| 153 | struct { |
| 154 | // The commandline switch and value that are added when this flag is |
| 155 | // active. This is different from |internal_name| so that the commandline |
| 156 | // flag can be renamed without breaking the prefs file. This is used if |
| 157 | // type is SINGLE_VALUE or ENABLE_DISABLE_VALUE. |
| 158 | const char* command_line_switch; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 159 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 160 | // Simple switches that have no value should use "" for |
| 161 | // command_line_value. |
| 162 | const char* command_line_value; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 163 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 164 | // For ENABLE_DISABLE_VALUE, the command line switch and value to |
| 165 | // explicitly disable the feature. |
| 166 | const char* disable_command_line_switch; |
| 167 | const char* disable_command_line_value; |
| 168 | } switches; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 169 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 170 | struct { |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 171 | // For FEATURE_VALUE or FEATURE_WITH_PARAMS_VALUE, the base::Feature |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 172 | // this entry corresponds to. The same feature must not be used in |
| 173 | // multiple FeatureEntries. |
| 174 | const base::Feature* feature; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 175 | |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 176 | // This describes the options if type is FEATURE_WITH_PARAMS_VALUE. |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 177 | // The first variation is the default "Enabled" variation, its |
| 178 | // description_id is disregarded. |
| 179 | base::span<const FeatureVariation> feature_variations; |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 180 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 181 | // The name of the FieldTrial in which the selected variation parameters |
| 182 | // should be registered. This is used if type is |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 183 | // FEATURE_WITH_PARAMS_VALUE. |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 184 | const char* feature_trial_name; |
| 185 | } feature; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 186 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 187 | // This describes the options if type is MULTI_VALUE. |
| 188 | base::span<const Choice> choices; |
| 189 | }; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 190 | |
Alexei Svitkine | ea9e3961 | 2018-11-14 21:28:03 | [diff] [blame] | 191 | // Check whether internal |name| matches this FeatureEntry. Depending on the |
| 192 | // type of entry, this compared it to either |internal_name| or the values |
| 193 | // produced by NameForOption(). |
| 194 | bool InternalNameMatches(const std::string& name) const; |
| 195 | |
Jeremy Roman | 3908697 | 2020-06-15 17:55:43 | [diff] [blame] | 196 | // Number of options to choose from. This is used if type is MULTI_VALUE, |
| 197 | // ENABLE_DISABLE_VALUE, FEATURE_VALUE, or FEATURE_WITH_PARAMS_VALUE. |
| 198 | int NumOptions() const; |
| 199 | |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 200 | // Returns the name used in prefs for the option at the specified |index|. |
| 201 | // Only used for types that use |num_options|. |
| 202 | std::string NameForOption(int index) const; |
| 203 | |
| 204 | // Returns the human readable description for the option at |index|. |
| 205 | // Only used for types that use |num_options|. |
Jan Wilken Dörrie | fa241ba | 2021-03-11 17:57:01 | [diff] [blame] | 206 | std::u16string DescriptionForOption(int index) const; |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 207 | |
| 208 | // Returns the choice for the option at |index|. Only applicable for type |
| 209 | // FEATURE_MULTI. |
| 210 | const FeatureEntry::Choice& ChoiceForOption(int index) const; |
| 211 | |
| 212 | // Returns the state of the feature at |index|. Only applicable for types |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 213 | // FEATURE_VALUE and FEATURE_WITH_PARAMS_VALUE. |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 214 | FeatureEntry::FeatureState StateForOption(int index) const; |
| 215 | |
| 216 | // Returns the variation for the option at |index| or nullptr if there is no |
| 217 | // variation associated at |index|. Only applicable for types FEATURE_VALUE |
Lei Zhang | 6453d7e | 2021-08-09 17:47:47 | [diff] [blame] | 218 | // and FEATURE_WITH_PARAMS_VALUE. |
jkrcal | 1383d1d | 2016-06-17 12:40:56 | [diff] [blame] | 219 | const FeatureEntry::FeatureVariation* VariationForOption(int index) const; |
Hidehiko Abe | f49b7d0 | 2022-01-28 19:08:10 | [diff] [blame] | 220 | |
| 221 | // Returns true if the entry is considered as valid. |
| 222 | // See the implenetation for the details of what is valid. |
| 223 | bool IsValid() const; |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 224 | }; |
| 225 | |
| 226 | namespace testing { |
| 227 | |
| 228 | // Separator used for multi values. Multi values are represented in prefs as |
| 229 | // name-of-experiment + kMultiSeparator + selected_index. |
| 230 | extern const char kMultiSeparator[]; |
| 231 | |
Alexei Svitkine | 105f942e | 2018-02-17 02:53:48 | [diff] [blame] | 232 | } // namespace testing |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 233 | |
Alexei Svitkine | 105f942e | 2018-02-17 02:53:48 | [diff] [blame] | 234 | } // namespace flags_ui |
sdefresne | 246c564 | 2015-11-16 21:47:29 | [diff] [blame] | 235 | |
| 236 | #endif // COMPONENTS_FLAGS_UI_FEATURE_ENTRY_H_ |