1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
// Copyright 2015 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_STATE_H_
#define COMPONENTS_FLAGS_UI_FLAGS_STATE_H_
#include <stddef.h>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/macros.h"
namespace base {
class ListValue;
}
namespace flags_ui {
// Internal functionality exposed for tests.
namespace internal {
// The trial group selected when feature variation parameters are registered via
// FlagsState::RegisterFeatureVariationParameters().
extern const char kTrialGroupAboutFlags[];
} // namespace internal
struct FeatureEntry;
class FlagsStorage;
struct SwitchEntry;
// Enumeration of flag filters.
enum {
kOsMac = 1 << 0,
kOsWin = 1 << 1,
kOsLinux = 1 << 2,
kOsCrOS = 1 << 3,
kOsAndroid = 1 << 4,
kOsCrOSOwnerOnly = 1 << 5,
kOsIos = 1 << 6,
kDeprecated = 1 << 7,
kOsFuchsia = 1 << 8,
// Flags marked with this are internal to the flags system. Never set this on
// a manually-added flag.
kFlagInfrastructure = 1 << 9,
};
// A flag controlling the behavior of the |ConvertFlagsToSwitches| function -
// whether it should add the sentinel switches around flags.
enum SentinelsMode { kNoSentinels, kAddSentinels };
// Differentiate between generic flags available on a per session base and flags
// that influence the whole machine and can be said by the admin only. This flag
// is relevant for ChromeOS for now only and dictates whether entries marked
// with the |kOsCrOSOwnerOnly| label should be enabled in the UI or not.
enum FlagAccess { kGeneralAccessFlagsOnly, kOwnerAccessToFlags };
// Stores and encapsulates the little state that about:flags has.
class FlagsState {
public:
// This delegate is used for embedders to configure the behavior of
// FlagsState. The delegate is optional.
class Delegate {
public:
// Returns whether |entry| should be excluded from the sets of
// switches/features generated by ConvertFlagsToSwitches().
virtual bool ShouldExcludeFlag(const FlagsStorage* state,
const FeatureEntry& entry);
protected:
Delegate();
virtual ~Delegate();
Delegate(const Delegate&) = delete;
Delegate& operator=(const Delegate&) = delete;
};
// The delegate may be nullptr.
FlagsState(base::span<const FeatureEntry> feature_entries,
Delegate* delegate);
~FlagsState();
// Reads the state from |flags_storage| and adds the command line flags
// belonging to the active feature entries to |command_line|. Features are
// appended via |enable_features_flag_name| and |disable_features_flag_name|.
void ConvertFlagsToSwitches(FlagsStorage* flags_storage,
base::CommandLine* command_line,
SentinelsMode sentinels,
const char* enable_features_flag_name,
const char* disable_features_flag_name);
// Reads the state from |flags_storage| and fills |switches| with the set of
// switches corresponding to enabled entries and |features| with the set of
// strings corresponding to enabled/disabled base::Feature states. Feature
// names are suffixed with ":enabled" or ":disabled" depending on their state.
void GetSwitchesAndFeaturesFromFlags(FlagsStorage* flags_storage,
std::set<std::string>* switches,
std::set<std::string>* features) const;
bool IsRestartNeededToCommitChanges();
void SetFeatureEntryEnabled(FlagsStorage* flags_storage,
const std::string& internal_name,
bool enable);
// Sets |value| as the command line switch for feature given by
// |internal_name|. |value| contains a list of origins (serialized form of
// url::Origin()) separated by whitespace and/or comma. Invalid values in this
// list are ignored.
void SetOriginListFlag(const std::string& internal_name,
const std::string& value,
FlagsStorage* flags_storage);
void RemoveFlagsSwitches(base::CommandLine::SwitchMap* switch_list);
void ResetAllFlags(FlagsStorage* flags_storage);
void Reset();
// Registers variations parameter values selected for features in about:flags.
// The selected flags are retrieved from |flags_storage|, the registered
// variation parameters are connected to their corresponding features in
// |feature_list|. Returns the (possibly empty) comma separated list of
// additional variation ids to register in the MetricsService that come from
// variations selected using chrome://flags.
std::vector<std::string> RegisterAllFeatureVariationParameters(
FlagsStorage* flags_storage,
base::FeatureList* feature_list);
// Gets the list of feature entries. Entries that are available for the
// current platform are appended to |supported_entries|; all other entries are
// appended to |unsupported_entries|.
//
// |skip_feature_entry| is called once for each feature in |feature_entries_|,
// and entry data for a feature is only included in the output data if the
// callback returns |false| for the entry.
void GetFlagFeatureEntries(
FlagsStorage* flags_storage,
FlagAccess access,
base::ListValue* supported_entries,
base::ListValue* unsupported_entries,
base::RepeatingCallback<bool(const FeatureEntry&)> skip_feature_entry);
// Returns the value for the current platform. This is one of the values
// defined by the OS enum above.
// This is exposed only for testing.
static int GetCurrentPlatform();
// Compares a set of switches of the two provided command line objects and
// returns true if they are the same and false otherwise.
// If |out_difference| is not NULL, it's filled with set_symmetric_difference
// between sets.
// Only switches between --flag-switches-begin and --flag-switches-end are
// compared. The embedder may use |extra_flag_sentinel_begin_flag_name| and
// |extra_sentinel_end_flag_name| to specify other delimiters, if supported.
static bool AreSwitchesIdenticalToCurrentCommandLine(
const base::CommandLine& new_cmdline,
const base::CommandLine& active_cmdline,
std::set<base::CommandLine::StringType>* out_difference,
const char* extra_flag_sentinel_begin_flag_name,
const char* extra_flag_sentinel_end_flag_name);
private:
// Keeps track of affected switches for each FeatureEntry, based on which
// choice is selected for it.
struct SwitchEntry;
// Adds mapping to |name_to_switch_map| to set the given switch name/value.
void AddSwitchMapping(
const std::string& key,
const std::string& switch_name,
const std::string& switch_value,
std::map<std::string, SwitchEntry>* name_to_switch_map) const;
// Adds mapping to |name_to_switch_map| to toggle base::Feature |feature_name|
// to state |feature_state|.
void AddFeatureMapping(
const std::string& key,
const std::string& feature_name,
bool feature_state,
std::map<std::string, SwitchEntry>* name_to_switch_map) const;
// Updates the switches in |command_line| by applying the modifications
// specified in |name_to_switch_map| for each entry in |enabled_entries|.
// |enable_features_flag_name| and |disable_features_flag_name| are switches
// used by the embedder to enable/disable features respectively if supported.
void AddSwitchesToCommandLine(
const std::set<std::string>& enabled_entries,
const std::map<std::string, SwitchEntry>& name_to_switch_map,
SentinelsMode sentinels,
base::CommandLine* command_line,
const char* enable_features_flag_name,
const char* disable_features_flag_name);
// Updates |command_line| by merging the value of the --enable-features= or
// --disable-features= list (per the |switch_name| param) with corresponding
// entries in |feature_switches| that have value |feature_state|. Keeps track
// of the changes by updating |appended_switches|.
void MergeFeatureCommandLineSwitch(
const std::map<std::string, bool>& feature_switches,
const char* switch_name,
bool feature_state,
base::CommandLine* command_line);
// Sanitizes |enabled_entries| to only contain entries that are defined in the
// |feature_entries_| and whose |supported_platforms| matches |platform_mask|.
// Pass -1 to |platform_mask| to not do platform filtering.
std::set<std::string> SanitizeList(
const FlagsStorage* storage,
const std::set<std::string>& enabled_entries,
int platform_mask) const;
// Gets sanitized entries from |flags_storage|, filtering out any entries that
// don't exist in |feature_entries_|, and updates |flags_storage|.
void GetSanitizedEnabledFlags(FlagsStorage* flags_storage,
std::set<std::string>* result) const;
// Variant of GetSanitizedEnabledFlags that also removes any flags that aren't
// enabled on the current platform.
void GetSanitizedEnabledFlagsForCurrentPlatform(
FlagsStorage* flags_storage,
std::set<std::string>* result) const;
// Generates a flags to switches mapping based on the set of enabled flags
// from |flags_storage|. On output, |enabled_entries| will contain the
// internal names of enabled flags and |name_to_switch_map| will contain
// information on how they map to command-line flags or features.
void GenerateFlagsToSwitchesMapping(
FlagsStorage* flags_storage,
std::set<std::string>* enabled_entries,
std::map<std::string, SwitchEntry>* name_to_switch_map) const;
// Returns the FeatureEntry named |internal_name|. Returns null if no entry is
// matched.
const FeatureEntry* FindFeatureEntryByName(
const std::string& internal_name) const;
// Returns whether there is a FeatureEntry named by |name| in
// |feature_entries_| that:
// a) Is supported on this |platform_mask|, and
// b) Is not excluded by |exclude_predicate_|, if it is set (i.e. for which
// |exclude_predicate_| returns false).
bool IsSupportedFeature(const FlagsStorage* storage,
const std::string& name,
int platform_mask) const;
const base::span<const FeatureEntry> feature_entries_;
bool needs_restart_;
std::map<std::string, std::string> flags_switches_;
// Map from switch name to a set of string, that keeps track which strings
// were appended to existing (list value) switches.
std::map<std::string, std::set<std::string>> appended_switches_;
// Delegate used for embedders to control display and application of flags.
// May be null.
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(FlagsState);
};
} // namespace flags_ui
#endif // COMPONENTS_FLAGS_UI_FLAGS_STATE_H_
|