blob: 1a8db5fcb0da0f77676c63b5c6b6f7a97c07262d [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
15#include "base/callback_forward.h"
16#include "base/command_line.h"
Elly Fong-Jonesd488661c2019-07-31 21:53:2617#include "base/feature_list.h"
sdefresne0e566342015-11-24 08:55:4618#include "base/macros.h"
19
20namespace base {
sdefresne0e566342015-11-24 08:55:4621class ListValue;
22}
23
24namespace flags_ui {
25
jkrcal1383d1d2016-06-17 12:40:5626// Internal functionality exposed for tests.
27namespace internal {
28// The trial group selected when feature variation parameters are registered via
29// FlagsState::RegisterFeatureVariationParameters().
30extern const char kTrialGroupAboutFlags[];
31} // namespace internal
32
sdefresne0e566342015-11-24 08:55:4633struct FeatureEntry;
34class FlagsStorage;
35struct SwitchEntry;
36
Yann Dagobaa08aa2019-07-29 20:52:3737// Enumeration of flag filters.
sdefresne0e566342015-11-24 08:55:4638enum {
39 kOsMac = 1 << 0,
40 kOsWin = 1 << 1,
41 kOsLinux = 1 << 2,
42 kOsCrOS = 1 << 3,
43 kOsAndroid = 1 << 4,
sdefresneabf860062015-11-26 09:45:2244 kOsCrOSOwnerOnly = 1 << 5,
45 kOsIos = 1 << 6,
Yann Dago78028712019-09-04 15:23:5446 kDeprecated = 1 << 7,
sdefresne0e566342015-11-24 08:55:4647};
48
sdefresne0e566342015-11-24 08:55:4649// A flag controlling the behavior of the |ConvertFlagsToSwitches| function -
50// whether it should add the sentinel switches around flags.
51enum SentinelsMode { kNoSentinels, kAddSentinels };
52
53// Differentiate between generic flags available on a per session base and flags
54// that influence the whole machine and can be said by the admin only. This flag
55// is relevant for ChromeOS for now only and dictates whether entries marked
56// with the |kOsCrOSOwnerOnly| label should be enabled in the UI or not.
noyauc8da0d22017-07-19 14:39:5257enum FlagAccess { kGeneralAccessFlagsOnly, kOwnerAccessToFlags };
sdefresne0e566342015-11-24 08:55:4658
59// Stores and encapsulates the little state that about:flags has.
60class FlagsState {
61 public:
62 FlagsState(const FeatureEntry* feature_entries, size_t num_feature_entries);
63 ~FlagsState();
64
jkrcal1383d1d2016-06-17 12:40:5665 // Reads the state from |flags_storage| and adds the command line flags
66 // belonging to the active feature entries to |command_line|. Features are
67 // appended via |enable_features_flag_name| and |disable_features_flag_name|.
sdefresne0e566342015-11-24 08:55:4668 void ConvertFlagsToSwitches(FlagsStorage* flags_storage,
69 base::CommandLine* command_line,
70 SentinelsMode sentinels,
71 const char* enable_features_flag_name,
72 const char* disable_features_flag_name);
asvitkinec1a0c4f2016-08-31 20:37:3973
Alexei Svitkine103faf82018-11-14 16:43:1574 // Reads the state from |flags_storage| and fills |switches| with the set of
75 // switches corresponding to enabled entries and |features| with the set of
76 // strings corresponding to enabled/disabled base::Feature states. Feature
77 // names are suffixed with ":enabled" or ":disabled" depending on their state.
78 void GetSwitchesAndFeaturesFromFlags(FlagsStorage* flags_storage,
79 std::set<std::string>* switches,
80 std::set<std::string>* features) const;
lawrencewu95059d1e2016-09-19 18:07:0281
sdefresne0e566342015-11-24 08:55:4682 bool IsRestartNeededToCommitChanges();
83 void SetFeatureEntryEnabled(FlagsStorage* flags_storage,
84 const std::string& internal_name,
85 bool enable);
Mustafa Emre Acerb3aa36a82018-05-22 21:44:0586
87 // Sets |value| as the command line switch for feature given by
88 // |internal_name|. |value| contains a list of origins (serialized form of
89 // url::Origin()) separated by whitespace and/or comma. Invalid values in this
90 // list are ignored.
91 void SetOriginListFlag(const std::string& internal_name,
92 const std::string& value,
93 FlagsStorage* flags_storage);
94
Jeremy Roman863386d2017-10-31 19:25:3895 void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list);
sdefresne0e566342015-11-24 08:55:4696 void ResetAllFlags(FlagsStorage* flags_storage);
97 void Reset();
98
jkrcald1d20082016-07-14 15:04:2499 // Registers variations parameter values selected for features in about:flags.
100 // The selected flags are retrieved from |flags_storage|, the registered
101 // variation parameters are connected to their corresponding features in
jkrcalbf073372016-07-29 07:21:31102 // |feature_list|. Returns the (possibly empty) comma separated list of
103 // additional variation ids to register in the MetricsService that come from
104 // variations selected using chrome://flags.
105 std::vector<std::string> RegisterAllFeatureVariationParameters(
106 FlagsStorage* flags_storage,
107 base::FeatureList* feature_list);
jkrcal1383d1d2016-06-17 12:40:56108
sdefresne0e566342015-11-24 08:55:46109 // Gets the list of feature entries. Entries that are available for the
110 // current platform are appended to |supported_entries|; all other entries are
111 // appended to |unsupported_entries|.
112 void GetFlagFeatureEntries(
113 FlagsStorage* flags_storage,
114 FlagAccess access,
115 base::ListValue* supported_entries,
116 base::ListValue* unsupported_entries,
117 base::Callback<bool(const FeatureEntry&)> skip_feature_entry);
118
119 // Returns the value for the current platform. This is one of the values
120 // defined by the OS enum above.
121 // This is exposed only for testing.
122 static int GetCurrentPlatform();
123
124 // Compares a set of switches of the two provided command line objects and
125 // returns true if they are the same and false otherwise.
126 // If |out_difference| is not NULL, it's filled with set_symmetric_difference
127 // between sets.
128 // Only switches between --flag-switches-begin and --flag-switches-end are
129 // compared. The embedder may use |extra_flag_sentinel_begin_flag_name| and
130 // |extra_sentinel_end_flag_name| to specify other delimiters, if supported.
131 static bool AreSwitchesIdenticalToCurrentCommandLine(
132 const base::CommandLine& new_cmdline,
133 const base::CommandLine& active_cmdline,
134 std::set<base::CommandLine::StringType>* out_difference,
135 const char* extra_flag_sentinel_begin_flag_name,
136 const char* extra_flag_sentinel_end_flag_name);
137
138 private:
asvitkinec1a0c4f2016-08-31 20:37:39139 // Keeps track of affected switches for each FeatureEntry, based on which
140 // choice is selected for it.
141 struct SwitchEntry;
142
sdefresne0e566342015-11-24 08:55:46143 // Adds mapping to |name_to_switch_map| to set the given switch name/value.
Alexei Svitkine103faf82018-11-14 16:43:15144 void AddSwitchMapping(
145 const std::string& key,
146 const std::string& switch_name,
147 const std::string& switch_value,
148 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
sdefresne0e566342015-11-24 08:55:46149
150 // Adds mapping to |name_to_switch_map| to toggle base::Feature |feature_name|
151 // to state |feature_state|.
152 void AddFeatureMapping(
153 const std::string& key,
154 const std::string& feature_name,
155 bool feature_state,
Alexei Svitkine103faf82018-11-14 16:43:15156 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
sdefresne0e566342015-11-24 08:55:46157
158 // Updates the switches in |command_line| by applying the modifications
159 // specified in |name_to_switch_map| for each entry in |enabled_entries|.
160 // |enable_features_flag_name| and |disable_features_flag_name| are switches
161 // used by the embedder to enable/disable features respectively if supported.
162 void AddSwitchesToCommandLine(
163 const std::set<std::string>& enabled_entries,
164 const std::map<std::string, SwitchEntry>& name_to_switch_map,
165 SentinelsMode sentinels,
166 base::CommandLine* command_line,
167 const char* enable_features_flag_name,
168 const char* disable_features_flag_name);
169
170 // Updates |command_line| by merging the value of the --enable-features= or
171 // --disable-features= list (per the |switch_name| param) with corresponding
172 // entries in |feature_switches| that have value |feature_state|. Keeps track
173 // of the changes by updating |appended_switches|.
174 void MergeFeatureCommandLineSwitch(
175 const std::map<std::string, bool>& feature_switches,
176 const char* switch_name,
177 bool feature_state,
178 base::CommandLine* command_line);
179
Alexei Svitkineea9e39612018-11-14 21:28:03180 // Sanitizes |enabled_entries| to only contain entries that are defined in the
181 // |feature_entries_| and whose |supported_platforms| matches |platform_mask|.
182 // Pass -1 to |platform_mask| to not do platform filtering.
183 std::set<std::string> SanitizeList(
184 const std::set<std::string>& enabled_entries,
185 int platform_mask) const;
sdefresne0e566342015-11-24 08:55:46186
Alexei Svitkineea9e39612018-11-14 21:28:03187 // Gets sanitized entries from |flags_storage|, filtering out any entries that
188 // don't exist in |feature_entries_|, and updates |flags_storage|.
sdefresne0e566342015-11-24 08:55:46189 void GetSanitizedEnabledFlags(FlagsStorage* flags_storage,
Alexei Svitkine103faf82018-11-14 16:43:15190 std::set<std::string>* result) const;
sdefresne0e566342015-11-24 08:55:46191
192 // Variant of GetSanitizedEnabledFlags that also removes any flags that aren't
193 // enabled on the current platform.
194 void GetSanitizedEnabledFlagsForCurrentPlatform(
195 FlagsStorage* flags_storage,
Alexei Svitkine103faf82018-11-14 16:43:15196 std::set<std::string>* result) const;
sdefresne0e566342015-11-24 08:55:46197
asvitkinec1a0c4f2016-08-31 20:37:39198 // Generates a flags to switches mapping based on the set of enabled flags
199 // from |flags_storage|. On output, |enabled_entries| will contain the
200 // internal names of enabled flags and |name_to_switch_map| will contain
201 // information on how they map to command-line flags or features.
202 void GenerateFlagsToSwitchesMapping(
203 FlagsStorage* flags_storage,
204 std::set<std::string>* enabled_entries,
Alexei Svitkine103faf82018-11-14 16:43:15205 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
asvitkinec1a0c4f2016-08-31 20:37:39206
Mustafa Emre Acerb3aa36a82018-05-22 21:44:05207 // Returns the FeatureEntry named |internal_name|. Returns null if no entry is
208 // matched.
209 const FeatureEntry* FindFeatureEntryByName(
210 const std::string& internal_name) const;
211
sdefresne0e566342015-11-24 08:55:46212 const FeatureEntry* feature_entries_;
213 size_t num_feature_entries_;
214
215 bool needs_restart_;
216 std::map<std::string, std::string> flags_switches_;
217
218 // Map from switch name to a set of string, that keeps track which strings
219 // were appended to existing (list value) switches.
220 std::map<std::string, std::set<std::string>> appended_switches_;
221
sdefresne0e566342015-11-24 08:55:46222 DISALLOW_COPY_AND_ASSIGN(FlagsState);
223};
224
225} // namespace flags_ui
226
227#endif // COMPONENTS_FLAGS_UI_FLAGS_STATE_H_