blob: 507cda7b534dba47c77bff7afc62e2865c61f666 [file] [log] [blame]
sdefresne0e566342015-11-24 08:55:461// 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_FLAGS_STATE_H_
6#define COMPONENTS_FLAGS_UI_FLAGS_STATE_H_
7
avibc5337b2015-12-25 23:16:338#include <stddef.h>
9
sdefresne0e566342015-11-24 08:55:4610#include <map>
11#include <set>
12#include <string>
jkrcalbf073372016-07-29 07:21:3113#include <vector>
sdefresne0e566342015-11-24 08:55:4614
Elly Fong-Jonesc3e9aea2019-10-24 19:44:1915#include "base/callback.h"
sdefresne0e566342015-11-24 08:55:4616#include "base/command_line.h"
Elly Fong-Jones3cd75282019-11-12 20:26:5017#include "base/containers/span.h"
Elly Fong-Jonesd488661c2019-07-31 21:53:2618#include "base/feature_list.h"
sdefresne0e566342015-11-24 08:55:4619#include "base/macros.h"
Morten Stenshorne7afa5802021-07-15 10:04:4320#include "base/values.h"
sdefresne0e566342015-11-24 08:55:4621
22namespace flags_ui {
23
jkrcal1383d1d2016-06-17 12:40:5624// Internal functionality exposed for tests.
25namespace internal {
26// The trial group selected when feature variation parameters are registered via
27// FlagsState::RegisterFeatureVariationParameters().
28extern const char kTrialGroupAboutFlags[];
29} // namespace internal
30
sdefresne0e566342015-11-24 08:55:4631struct FeatureEntry;
32class FlagsStorage;
33struct SwitchEntry;
34
Yann Dagobaa08aa2019-07-29 20:52:3735// Enumeration of flag filters.
sdefresne0e566342015-11-24 08:55:4636enum {
37 kOsMac = 1 << 0,
38 kOsWin = 1 << 1,
39 kOsLinux = 1 << 2,
40 kOsCrOS = 1 << 3,
41 kOsAndroid = 1 << 4,
sdefresneabf860062015-11-26 09:45:2242 kOsCrOSOwnerOnly = 1 << 5,
43 kOsIos = 1 << 6,
Yann Dago78028712019-09-04 15:23:5444 kDeprecated = 1 << 7,
Wez04eb259f2019-09-16 19:41:5945 kOsFuchsia = 1 << 8,
Elly Fong-Jones4054f142020-04-17 17:12:3346
47 // Flags marked with this are internal to the flags system. Never set this on
48 // a manually-added flag.
49 kFlagInfrastructure = 1 << 9,
sdefresne0e566342015-11-24 08:55:4650};
51
52// A flag controlling the behavior of the |ConvertFlagsToSwitches| function -
53// whether it should add the sentinel switches around flags.
54enum SentinelsMode { kNoSentinels, kAddSentinels };
55
56// Differentiate between generic flags available on a per session base and flags
57// that influence the whole machine and can be said by the admin only. This flag
58// is relevant for ChromeOS for now only and dictates whether entries marked
59// with the |kOsCrOSOwnerOnly| label should be enabled in the UI or not.
noyauc8da0d22017-07-19 14:39:5260enum FlagAccess { kGeneralAccessFlagsOnly, kOwnerAccessToFlags };
sdefresne0e566342015-11-24 08:55:4661
62// Stores and encapsulates the little state that about:flags has.
63class FlagsState {
64 public:
Elly Fong-Jones3cd75282019-11-12 20:26:5065 // This delegate is used for embedders to configure the behavior of
66 // FlagsState. The delegate is optional.
67 class Delegate {
68 public:
69 // Returns whether |entry| should be excluded from the sets of
70 // switches/features generated by ConvertFlagsToSwitches().
Elly Fong-Jonesf8a4aa42020-08-04 15:53:3071 virtual bool ShouldExcludeFlag(const FlagsStorage* state,
72 const FeatureEntry& entry);
Elly Fong-Jones3cd75282019-11-12 20:26:5073
74 protected:
75 Delegate();
76 virtual ~Delegate();
77
78 Delegate(const Delegate&) = delete;
79 Delegate& operator=(const Delegate&) = delete;
80 };
81
82 // The delegate may be nullptr.
83 FlagsState(base::span<const FeatureEntry> feature_entries,
84 Delegate* delegate);
sdefresne0e566342015-11-24 08:55:4685 ~FlagsState();
86
jkrcal1383d1d2016-06-17 12:40:5687 // Reads the state from |flags_storage| and adds the command line flags
88 // belonging to the active feature entries to |command_line|. Features are
89 // appended via |enable_features_flag_name| and |disable_features_flag_name|.
sdefresne0e566342015-11-24 08:55:4690 void ConvertFlagsToSwitches(FlagsStorage* flags_storage,
91 base::CommandLine* command_line,
92 SentinelsMode sentinels,
93 const char* enable_features_flag_name,
94 const char* disable_features_flag_name);
asvitkinec1a0c4f2016-08-31 20:37:3995
Elaine Chien29fce992020-12-01 17:44:3496 // Returns the FeatureEntry named |internal_name|. Returns null if no entry is
97 // matched.
98 const FeatureEntry* FindFeatureEntryByName(
99 const std::string& internal_name) const;
100
101 // Gets sanitized entries from |flags_storage|, filtering out any entries that
102 // don't exist in |feature_entries_|, and updates |flags_storage|.
103 void GetSanitizedEnabledFlags(FlagsStorage* flags_storage,
104 std::set<std::string>* result) const;
105
Alexei Svitkine103faf82018-11-14 16:43:15106 // Reads the state from |flags_storage| and fills |switches| with the set of
107 // switches corresponding to enabled entries and |features| with the set of
108 // strings corresponding to enabled/disabled base::Feature states. Feature
109 // names are suffixed with ":enabled" or ":disabled" depending on their state.
110 void GetSwitchesAndFeaturesFromFlags(FlagsStorage* flags_storage,
111 std::set<std::string>* switches,
112 std::set<std::string>* features) const;
lawrencewu95059d1e2016-09-19 18:07:02113
sdefresne0e566342015-11-24 08:55:46114 bool IsRestartNeededToCommitChanges();
115 void SetFeatureEntryEnabled(FlagsStorage* flags_storage,
116 const std::string& internal_name,
117 bool enable);
Mustafa Emre Acerb3aa36a82018-05-22 21:44:05118
119 // Sets |value| as the command line switch for feature given by
120 // |internal_name|. |value| contains a list of origins (serialized form of
121 // url::Origin()) separated by whitespace and/or comma. Invalid values in this
122 // list are ignored.
123 void SetOriginListFlag(const std::string& internal_name,
124 const std::string& value,
125 FlagsStorage* flags_storage);
126
Jeremy Roman863386d2017-10-31 19:25:38127 void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list);
sdefresne0e566342015-11-24 08:55:46128 void ResetAllFlags(FlagsStorage* flags_storage);
129 void Reset();
130
jkrcald1d20082016-07-14 15:04:24131 // Registers variations parameter values selected for features in about:flags.
132 // The selected flags are retrieved from |flags_storage|, the registered
133 // variation parameters are connected to their corresponding features in
jkrcalbf073372016-07-29 07:21:31134 // |feature_list|. Returns the (possibly empty) comma separated list of
135 // additional variation ids to register in the MetricsService that come from
136 // variations selected using chrome://flags.
137 std::vector<std::string> RegisterAllFeatureVariationParameters(
138 FlagsStorage* flags_storage,
139 base::FeatureList* feature_list);
jkrcal1383d1d2016-06-17 12:40:56140
sdefresne0e566342015-11-24 08:55:46141 // Gets the list of feature entries. Entries that are available for the
142 // current platform are appended to |supported_entries|; all other entries are
143 // appended to |unsupported_entries|.
Ken Rockot6fc4e282019-12-20 21:07:16144 //
145 // |skip_feature_entry| is called once for each feature in |feature_entries_|,
146 // and entry data for a feature is only included in the output data if the
147 // callback returns |false| for the entry.
sdefresne0e566342015-11-24 08:55:46148 void GetFlagFeatureEntries(
149 FlagsStorage* flags_storage,
150 FlagAccess access,
Morten Stenshorne7afa5802021-07-15 10:04:43151 base::Value::ListStorage& supported_entries,
152 base::Value::ListStorage& unsupported_entries,
Ken Rockot6fc4e282019-12-20 21:07:16153 base::RepeatingCallback<bool(const FeatureEntry&)> skip_feature_entry);
sdefresne0e566342015-11-24 08:55:46154
155 // Returns the value for the current platform. This is one of the values
156 // defined by the OS enum above.
157 // This is exposed only for testing.
Peter Kasting2bd21a152021-06-15 17:20:03158 static unsigned short GetCurrentPlatform();
sdefresne0e566342015-11-24 08:55:46159
sdefresne0e566342015-11-24 08:55:46160 private:
asvitkinec1a0c4f2016-08-31 20:37:39161 // Keeps track of affected switches for each FeatureEntry, based on which
162 // choice is selected for it.
163 struct SwitchEntry;
164
sdefresne0e566342015-11-24 08:55:46165 // Adds mapping to |name_to_switch_map| to set the given switch name/value.
Alexei Svitkine103faf82018-11-14 16:43:15166 void AddSwitchMapping(
167 const std::string& key,
168 const std::string& switch_name,
169 const std::string& switch_value,
170 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
sdefresne0e566342015-11-24 08:55:46171
172 // Adds mapping to |name_to_switch_map| to toggle base::Feature |feature_name|
173 // to state |feature_state|.
174 void AddFeatureMapping(
175 const std::string& key,
176 const std::string& feature_name,
177 bool feature_state,
Alexei Svitkine103faf82018-11-14 16:43:15178 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
sdefresne0e566342015-11-24 08:55:46179
180 // Updates the switches in |command_line| by applying the modifications
181 // specified in |name_to_switch_map| for each entry in |enabled_entries|.
182 // |enable_features_flag_name| and |disable_features_flag_name| are switches
183 // used by the embedder to enable/disable features respectively if supported.
184 void AddSwitchesToCommandLine(
185 const std::set<std::string>& enabled_entries,
186 const std::map<std::string, SwitchEntry>& name_to_switch_map,
187 SentinelsMode sentinels,
188 base::CommandLine* command_line,
189 const char* enable_features_flag_name,
190 const char* disable_features_flag_name);
191
192 // Updates |command_line| by merging the value of the --enable-features= or
193 // --disable-features= list (per the |switch_name| param) with corresponding
194 // entries in |feature_switches| that have value |feature_state|. Keeps track
195 // of the changes by updating |appended_switches|.
196 void MergeFeatureCommandLineSwitch(
197 const std::map<std::string, bool>& feature_switches,
198 const char* switch_name,
199 bool feature_state,
200 base::CommandLine* command_line);
201
Alexei Svitkineea9e39612018-11-14 21:28:03202 // Sanitizes |enabled_entries| to only contain entries that are defined in the
203 // |feature_entries_| and whose |supported_platforms| matches |platform_mask|.
204 // Pass -1 to |platform_mask| to not do platform filtering.
205 std::set<std::string> SanitizeList(
Elly Fong-Jonesf8a4aa42020-08-04 15:53:30206 const FlagsStorage* storage,
Alexei Svitkineea9e39612018-11-14 21:28:03207 const std::set<std::string>& enabled_entries,
208 int platform_mask) const;
sdefresne0e566342015-11-24 08:55:46209
sdefresne0e566342015-11-24 08:55:46210
211 // Variant of GetSanitizedEnabledFlags that also removes any flags that aren't
212 // enabled on the current platform.
213 void GetSanitizedEnabledFlagsForCurrentPlatform(
214 FlagsStorage* flags_storage,
Alexei Svitkine103faf82018-11-14 16:43:15215 std::set<std::string>* result) const;
sdefresne0e566342015-11-24 08:55:46216
asvitkinec1a0c4f2016-08-31 20:37:39217 // Generates a flags to switches mapping based on the set of enabled flags
218 // from |flags_storage|. On output, |enabled_entries| will contain the
219 // internal names of enabled flags and |name_to_switch_map| will contain
220 // information on how they map to command-line flags or features.
Oleg Maximenko2fda7992021-08-10 09:31:41221 // When |enabled_entries| is empty |name_to_switch_map| won't be filled.
asvitkinec1a0c4f2016-08-31 20:37:39222 void GenerateFlagsToSwitchesMapping(
223 FlagsStorage* flags_storage,
224 std::set<std::string>* enabled_entries,
Alexei Svitkine103faf82018-11-14 16:43:15225 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
asvitkinec1a0c4f2016-08-31 20:37:39226
Mustafa Emre Acerb3aa36a82018-05-22 21:44:05227
Elly Fong-Jonesc3e9aea2019-10-24 19:44:19228 // Returns whether there is a FeatureEntry named by |name| in
229 // |feature_entries_| that:
230 // a) Is supported on this |platform_mask|, and
231 // b) Is not excluded by |exclude_predicate_|, if it is set (i.e. for which
232 // |exclude_predicate_| returns false).
Elly Fong-Jonesf8a4aa42020-08-04 15:53:30233 bool IsSupportedFeature(const FlagsStorage* storage,
234 const std::string& name,
235 int platform_mask) const;
Elly Fong-Jonesc3e9aea2019-10-24 19:44:19236
Elly Fong-Jones3cd75282019-11-12 20:26:50237 const base::span<const FeatureEntry> feature_entries_;
sdefresne0e566342015-11-24 08:55:46238
239 bool needs_restart_;
240 std::map<std::string, std::string> flags_switches_;
241
242 // Map from switch name to a set of string, that keeps track which strings
243 // were appended to existing (list value) switches.
244 std::map<std::string, std::set<std::string>> appended_switches_;
245
Elly Fong-Jones3cd75282019-11-12 20:26:50246 // Delegate used for embedders to control display and application of flags.
247 // May be null.
248 Delegate* delegate_;
Elly Fong-Jonesc3e9aea2019-10-24 19:44:19249
sdefresne0e566342015-11-24 08:55:46250 DISALLOW_COPY_AND_ASSIGN(FlagsState);
251};
252
253} // namespace flags_ui
254
255#endif // COMPONENTS_FLAGS_UI_FLAGS_STATE_H_