blob: 21ad59df5a043b5b141c771ee2d7200391b508c1 [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"
17#include "base/macros.h"
18
19namespace base {
jkrcald1d20082016-07-14 15:04:2420class FeatureList;
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
37// Enumeration of OSs.
38enum {
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,
sdefresne0e566342015-11-24 08:55:4646};
47
48// A flag controlling the behavior of the |ConvertFlagsToSwitches| function -
49// whether it should add the sentinel switches around flags.
50enum SentinelsMode { kNoSentinels, kAddSentinels };
51
52// Differentiate between generic flags available on a per session base and flags
53// that influence the whole machine and can be said by the admin only. This flag
54// is relevant for ChromeOS for now only and dictates whether entries marked
55// with the |kOsCrOSOwnerOnly| label should be enabled in the UI or not.
noyauc8da0d22017-07-19 14:39:5256enum FlagAccess { kGeneralAccessFlagsOnly, kOwnerAccessToFlags };
sdefresne0e566342015-11-24 08:55:4657
58// Stores and encapsulates the little state that about:flags has.
59class FlagsState {
60 public:
61 FlagsState(const FeatureEntry* feature_entries, size_t num_feature_entries);
62 ~FlagsState();
63
jkrcal1383d1d2016-06-17 12:40:5664 // Reads the state from |flags_storage| and adds the command line flags
65 // belonging to the active feature entries to |command_line|. Features are
66 // appended via |enable_features_flag_name| and |disable_features_flag_name|.
sdefresne0e566342015-11-24 08:55:4667 void ConvertFlagsToSwitches(FlagsStorage* flags_storage,
68 base::CommandLine* command_line,
69 SentinelsMode sentinels,
70 const char* enable_features_flag_name,
71 const char* disable_features_flag_name);
asvitkinec1a0c4f2016-08-31 20:37:3972
Alexei Svitkine103faf82018-11-14 16:43:1573 // Reads the state from |flags_storage| and fills |switches| with the set of
74 // switches corresponding to enabled entries and |features| with the set of
75 // strings corresponding to enabled/disabled base::Feature states. Feature
76 // names are suffixed with ":enabled" or ":disabled" depending on their state.
77 void GetSwitchesAndFeaturesFromFlags(FlagsStorage* flags_storage,
78 std::set<std::string>* switches,
79 std::set<std::string>* features) const;
lawrencewu95059d1e2016-09-19 18:07:0280
sdefresne0e566342015-11-24 08:55:4681 bool IsRestartNeededToCommitChanges();
82 void SetFeatureEntryEnabled(FlagsStorage* flags_storage,
83 const std::string& internal_name,
84 bool enable);
Mustafa Emre Acerb3aa36a82018-05-22 21:44:0585
86 // Sets |value| as the command line switch for feature given by
87 // |internal_name|. |value| contains a list of origins (serialized form of
88 // url::Origin()) separated by whitespace and/or comma. Invalid values in this
89 // list are ignored.
90 void SetOriginListFlag(const std::string& internal_name,
91 const std::string& value,
92 FlagsStorage* flags_storage);
93
Jeremy Roman863386d2017-10-31 19:25:3894 void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list);
sdefresne0e566342015-11-24 08:55:4695 void ResetAllFlags(FlagsStorage* flags_storage);
96 void Reset();
97
jkrcald1d20082016-07-14 15:04:2498 // Registers variations parameter values selected for features in about:flags.
99 // The selected flags are retrieved from |flags_storage|, the registered
100 // variation parameters are connected to their corresponding features in
jkrcalbf073372016-07-29 07:21:31101 // |feature_list|. Returns the (possibly empty) comma separated list of
102 // additional variation ids to register in the MetricsService that come from
103 // variations selected using chrome://flags.
104 std::vector<std::string> RegisterAllFeatureVariationParameters(
105 FlagsStorage* flags_storage,
106 base::FeatureList* feature_list);
jkrcal1383d1d2016-06-17 12:40:56107
sdefresne0e566342015-11-24 08:55:46108 // Gets the list of feature entries. Entries that are available for the
109 // current platform are appended to |supported_entries|; all other entries are
110 // appended to |unsupported_entries|.
111 void GetFlagFeatureEntries(
112 FlagsStorage* flags_storage,
113 FlagAccess access,
114 base::ListValue* supported_entries,
115 base::ListValue* unsupported_entries,
116 base::Callback<bool(const FeatureEntry&)> skip_feature_entry);
117
118 // Returns the value for the current platform. This is one of the values
119 // defined by the OS enum above.
120 // This is exposed only for testing.
121 static int GetCurrentPlatform();
122
123 // Compares a set of switches of the two provided command line objects and
124 // returns true if they are the same and false otherwise.
125 // If |out_difference| is not NULL, it's filled with set_symmetric_difference
126 // between sets.
127 // Only switches between --flag-switches-begin and --flag-switches-end are
128 // compared. The embedder may use |extra_flag_sentinel_begin_flag_name| and
129 // |extra_sentinel_end_flag_name| to specify other delimiters, if supported.
130 static bool AreSwitchesIdenticalToCurrentCommandLine(
131 const base::CommandLine& new_cmdline,
132 const base::CommandLine& active_cmdline,
133 std::set<base::CommandLine::StringType>* out_difference,
134 const char* extra_flag_sentinel_begin_flag_name,
135 const char* extra_flag_sentinel_end_flag_name);
136
137 private:
asvitkinec1a0c4f2016-08-31 20:37:39138 // Keeps track of affected switches for each FeatureEntry, based on which
139 // choice is selected for it.
140 struct SwitchEntry;
141
sdefresne0e566342015-11-24 08:55:46142 // Adds mapping to |name_to_switch_map| to set the given switch name/value.
Alexei Svitkine103faf82018-11-14 16:43:15143 void AddSwitchMapping(
144 const std::string& key,
145 const std::string& switch_name,
146 const std::string& switch_value,
147 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
sdefresne0e566342015-11-24 08:55:46148
149 // Adds mapping to |name_to_switch_map| to toggle base::Feature |feature_name|
150 // to state |feature_state|.
151 void AddFeatureMapping(
152 const std::string& key,
153 const std::string& feature_name,
154 bool feature_state,
Alexei Svitkine103faf82018-11-14 16:43:15155 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
sdefresne0e566342015-11-24 08:55:46156
157 // Updates the switches in |command_line| by applying the modifications
158 // specified in |name_to_switch_map| for each entry in |enabled_entries|.
159 // |enable_features_flag_name| and |disable_features_flag_name| are switches
160 // used by the embedder to enable/disable features respectively if supported.
161 void AddSwitchesToCommandLine(
162 const std::set<std::string>& enabled_entries,
163 const std::map<std::string, SwitchEntry>& name_to_switch_map,
164 SentinelsMode sentinels,
165 base::CommandLine* command_line,
166 const char* enable_features_flag_name,
167 const char* disable_features_flag_name);
168
169 // Updates |command_line| by merging the value of the --enable-features= or
170 // --disable-features= list (per the |switch_name| param) with corresponding
171 // entries in |feature_switches| that have value |feature_state|. Keeps track
172 // of the changes by updating |appended_switches|.
173 void MergeFeatureCommandLineSwitch(
174 const std::map<std::string, bool>& feature_switches,
175 const char* switch_name,
176 bool feature_state,
177 base::CommandLine* command_line);
178
179 // Removes all entries from prefs::kEnabledLabsExperiments that are unknown,
180 // to prevent this list to become very long as entries are added and removed.
Alexei Svitkine103faf82018-11-14 16:43:15181 void SanitizeList(FlagsStorage* flags_storage) const;
sdefresne0e566342015-11-24 08:55:46182
183 void GetSanitizedEnabledFlags(FlagsStorage* flags_storage,
Alexei Svitkine103faf82018-11-14 16:43:15184 std::set<std::string>* result) const;
sdefresne0e566342015-11-24 08:55:46185
186 // Variant of GetSanitizedEnabledFlags that also removes any flags that aren't
187 // enabled on the current platform.
188 void GetSanitizedEnabledFlagsForCurrentPlatform(
189 FlagsStorage* flags_storage,
Alexei Svitkine103faf82018-11-14 16:43:15190 std::set<std::string>* result) const;
sdefresne0e566342015-11-24 08:55:46191
asvitkinec1a0c4f2016-08-31 20:37:39192 // Generates a flags to switches mapping based on the set of enabled flags
193 // from |flags_storage|. On output, |enabled_entries| will contain the
194 // internal names of enabled flags and |name_to_switch_map| will contain
195 // information on how they map to command-line flags or features.
196 void GenerateFlagsToSwitchesMapping(
197 FlagsStorage* flags_storage,
198 std::set<std::string>* enabled_entries,
Alexei Svitkine103faf82018-11-14 16:43:15199 std::map<std::string, SwitchEntry>* name_to_switch_map) const;
asvitkinec1a0c4f2016-08-31 20:37:39200
Mustafa Emre Acerb3aa36a82018-05-22 21:44:05201 // Called when the value of an entry with ORIGIN_LIST_VALUE is modified.
202 // Modifies the corresponding command line by adding or removing the switch
203 // based on the value of |enabled|.
204 void DidModifyOriginListFlag(const FeatureEntry& entry, bool enabled);
205
206 // Returns the FeatureEntry named |internal_name|. Returns null if no entry is
207 // matched.
208 const FeatureEntry* FindFeatureEntryByName(
209 const std::string& internal_name) const;
210
sdefresne0e566342015-11-24 08:55:46211 const FeatureEntry* feature_entries_;
212 size_t num_feature_entries_;
213
214 bool needs_restart_;
215 std::map<std::string, std::string> flags_switches_;
216
217 // Map from switch name to a set of string, that keeps track which strings
218 // were appended to existing (list value) switches.
219 std::map<std::string, std::set<std::string>> appended_switches_;
220
Mustafa Emre Acerb3aa36a82018-05-22 21:44:05221 // Map from switch name to switch value. Only filled for features with
222 // ORIGIN_LIST_VALUE type.
223 std::map<std::string, std::string> switch_values_;
224
sdefresne0e566342015-11-24 08:55:46225 DISALLOW_COPY_AND_ASSIGN(FlagsState);
226};
227
228} // namespace flags_ui
229
230#endif // COMPONENTS_FLAGS_UI_FLAGS_STATE_H_