xref: /aosp_15_r20/external/libchrome/base/feature_list.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_FEATURE_LIST_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_FEATURE_LIST_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <map>
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker #include <string>
11*635a8641SAndroid Build Coastguard Worker #include <vector>
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/metrics/persistent_memory_allocator.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker namespace base {
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker class FieldTrial;
23*635a8641SAndroid Build Coastguard Worker 
24*635a8641SAndroid Build Coastguard Worker // Specifies whether a given feature is enabled or disabled by default.
25*635a8641SAndroid Build Coastguard Worker enum FeatureState {
26*635a8641SAndroid Build Coastguard Worker   FEATURE_DISABLED_BY_DEFAULT,
27*635a8641SAndroid Build Coastguard Worker   FEATURE_ENABLED_BY_DEFAULT,
28*635a8641SAndroid Build Coastguard Worker };
29*635a8641SAndroid Build Coastguard Worker 
30*635a8641SAndroid Build Coastguard Worker // The Feature struct is used to define the default state for a feature. See
31*635a8641SAndroid Build Coastguard Worker // comment below for more details. There must only ever be one struct instance
32*635a8641SAndroid Build Coastguard Worker // for a given feature name - generally defined as a constant global variable or
33*635a8641SAndroid Build Coastguard Worker // file static. It should never be used as a constexpr as it breaks
34*635a8641SAndroid Build Coastguard Worker // pointer-based identity lookup.
35*635a8641SAndroid Build Coastguard Worker struct BASE_EXPORT Feature {
36*635a8641SAndroid Build Coastguard Worker   // The name of the feature. This should be unique to each feature and is used
37*635a8641SAndroid Build Coastguard Worker   // for enabling/disabling features via command line flags and experiments.
38*635a8641SAndroid Build Coastguard Worker   // It is strongly recommended to use CamelCase style for feature names, e.g.
39*635a8641SAndroid Build Coastguard Worker   // "MyGreatFeature".
40*635a8641SAndroid Build Coastguard Worker   const char* const name;
41*635a8641SAndroid Build Coastguard Worker 
42*635a8641SAndroid Build Coastguard Worker   // The default state (i.e. enabled or disabled) for this feature.
43*635a8641SAndroid Build Coastguard Worker   const FeatureState default_state;
44*635a8641SAndroid Build Coastguard Worker };
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_CONFIGURABLE
47*635a8641SAndroid Build Coastguard Worker // DCHECKs have been built-in, and are configurable at run-time to be fatal, or
48*635a8641SAndroid Build Coastguard Worker // not, via a DcheckIsFatal feature. We define the Feature here since it is
49*635a8641SAndroid Build Coastguard Worker // checked in FeatureList::SetInstance(). See https://crbug.com/596231.
50*635a8641SAndroid Build Coastguard Worker extern BASE_EXPORT const Feature kDCheckIsFatalFeature;
51*635a8641SAndroid Build Coastguard Worker #endif  // DCHECK_IS_CONFIGURABLE
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker // The FeatureList class is used to determine whether a given feature is on or
54*635a8641SAndroid Build Coastguard Worker // off. It provides an authoritative answer, taking into account command-line
55*635a8641SAndroid Build Coastguard Worker // overrides and experimental control.
56*635a8641SAndroid Build Coastguard Worker //
57*635a8641SAndroid Build Coastguard Worker // The basic use case is for any feature that can be toggled (e.g. through
58*635a8641SAndroid Build Coastguard Worker // command-line or an experiment) to have a defined Feature struct, e.g.:
59*635a8641SAndroid Build Coastguard Worker //
60*635a8641SAndroid Build Coastguard Worker //   const base::Feature kMyGreatFeature {
61*635a8641SAndroid Build Coastguard Worker //     "MyGreatFeature", base::FEATURE_ENABLED_BY_DEFAULT
62*635a8641SAndroid Build Coastguard Worker //   };
63*635a8641SAndroid Build Coastguard Worker //
64*635a8641SAndroid Build Coastguard Worker // Then, client code that wishes to query the state of the feature would check:
65*635a8641SAndroid Build Coastguard Worker //
66*635a8641SAndroid Build Coastguard Worker //   if (base::FeatureList::IsEnabled(kMyGreatFeature)) {
67*635a8641SAndroid Build Coastguard Worker //     // Feature code goes here.
68*635a8641SAndroid Build Coastguard Worker //   }
69*635a8641SAndroid Build Coastguard Worker //
70*635a8641SAndroid Build Coastguard Worker // Behind the scenes, the above call would take into account any command-line
71*635a8641SAndroid Build Coastguard Worker // flags to enable or disable the feature, any experiments that may control it
72*635a8641SAndroid Build Coastguard Worker // and finally its default state (in that order of priority), to determine
73*635a8641SAndroid Build Coastguard Worker // whether the feature is on.
74*635a8641SAndroid Build Coastguard Worker //
75*635a8641SAndroid Build Coastguard Worker // Features can be explicitly forced on or off by specifying a list of comma-
76*635a8641SAndroid Build Coastguard Worker // separated feature names via the following command-line flags:
77*635a8641SAndroid Build Coastguard Worker //
78*635a8641SAndroid Build Coastguard Worker //   --enable-features=Feature5,Feature7
79*635a8641SAndroid Build Coastguard Worker //   --disable-features=Feature1,Feature2,Feature3
80*635a8641SAndroid Build Coastguard Worker //
81*635a8641SAndroid Build Coastguard Worker // To enable/disable features in a test, do NOT append --enable-features or
82*635a8641SAndroid Build Coastguard Worker // --disable-features to the command-line directly. Instead, use
83*635a8641SAndroid Build Coastguard Worker // ScopedFeatureList. See base/test/scoped_feature_list.h for details.
84*635a8641SAndroid Build Coastguard Worker //
85*635a8641SAndroid Build Coastguard Worker // After initialization (which should be done single-threaded), the FeatureList
86*635a8641SAndroid Build Coastguard Worker // API is thread safe.
87*635a8641SAndroid Build Coastguard Worker //
88*635a8641SAndroid Build Coastguard Worker // Note: This class is a singleton, but does not use base/memory/singleton.h in
89*635a8641SAndroid Build Coastguard Worker // order to have control over its initialization sequence. Specifically, the
90*635a8641SAndroid Build Coastguard Worker // intended use is to create an instance of this class and fully initialize it,
91*635a8641SAndroid Build Coastguard Worker // before setting it as the singleton for a process, via SetInstance().
92*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT FeatureList {
93*635a8641SAndroid Build Coastguard Worker  public:
94*635a8641SAndroid Build Coastguard Worker   FeatureList();
95*635a8641SAndroid Build Coastguard Worker   ~FeatureList();
96*635a8641SAndroid Build Coastguard Worker 
97*635a8641SAndroid Build Coastguard Worker   // Initializes feature overrides via command-line flags |enable_features| and
98*635a8641SAndroid Build Coastguard Worker   // |disable_features|, each of which is a comma-separated list of features to
99*635a8641SAndroid Build Coastguard Worker   // enable or disable, respectively. If a feature appears on both lists, then
100*635a8641SAndroid Build Coastguard Worker   // it will be disabled. If a list entry has the format "FeatureName<TrialName"
101*635a8641SAndroid Build Coastguard Worker   // then this initialization will also associate the feature state override
102*635a8641SAndroid Build Coastguard Worker   // with the named field trial, if it exists. If a feature name is prefixed
103*635a8641SAndroid Build Coastguard Worker   // with the '*' character, it will be created with OVERRIDE_USE_DEFAULT -
104*635a8641SAndroid Build Coastguard Worker   // which is useful for associating with a trial while using the default state.
105*635a8641SAndroid Build Coastguard Worker   // Must only be invoked during the initialization phase (before
106*635a8641SAndroid Build Coastguard Worker   // FinalizeInitialization() has been called).
107*635a8641SAndroid Build Coastguard Worker   void InitializeFromCommandLine(const std::string& enable_features,
108*635a8641SAndroid Build Coastguard Worker                                  const std::string& disable_features);
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker   // Initializes feature overrides through the field trial allocator, which
111*635a8641SAndroid Build Coastguard Worker   // we're using to store the feature names, their override state, and the name
112*635a8641SAndroid Build Coastguard Worker   // of the associated field trial.
113*635a8641SAndroid Build Coastguard Worker   void InitializeFromSharedMemory(PersistentMemoryAllocator* allocator);
114*635a8641SAndroid Build Coastguard Worker 
115*635a8641SAndroid Build Coastguard Worker   // Specifies whether a feature override enables or disables the feature.
116*635a8641SAndroid Build Coastguard Worker   enum OverrideState {
117*635a8641SAndroid Build Coastguard Worker     OVERRIDE_USE_DEFAULT,
118*635a8641SAndroid Build Coastguard Worker     OVERRIDE_DISABLE_FEATURE,
119*635a8641SAndroid Build Coastguard Worker     OVERRIDE_ENABLE_FEATURE,
120*635a8641SAndroid Build Coastguard Worker   };
121*635a8641SAndroid Build Coastguard Worker 
122*635a8641SAndroid Build Coastguard Worker   // Returns true if the state of |feature_name| has been overridden via
123*635a8641SAndroid Build Coastguard Worker   // |InitializeFromCommandLine()|.
124*635a8641SAndroid Build Coastguard Worker   bool IsFeatureOverriddenFromCommandLine(const std::string& feature_name,
125*635a8641SAndroid Build Coastguard Worker                                           OverrideState state) const;
126*635a8641SAndroid Build Coastguard Worker 
127*635a8641SAndroid Build Coastguard Worker   // Associates a field trial for reporting purposes corresponding to the
128*635a8641SAndroid Build Coastguard Worker   // command-line setting the feature state to |for_overridden_state|. The trial
129*635a8641SAndroid Build Coastguard Worker   // will be activated when the state of the feature is first queried. This
130*635a8641SAndroid Build Coastguard Worker   // should be called during registration, after InitializeFromCommandLine() has
131*635a8641SAndroid Build Coastguard Worker   // been called but before the instance is registered via SetInstance().
132*635a8641SAndroid Build Coastguard Worker   void AssociateReportingFieldTrial(const std::string& feature_name,
133*635a8641SAndroid Build Coastguard Worker                                     OverrideState for_overridden_state,
134*635a8641SAndroid Build Coastguard Worker                                     FieldTrial* field_trial);
135*635a8641SAndroid Build Coastguard Worker 
136*635a8641SAndroid Build Coastguard Worker   // Registers a field trial to override the enabled state of the specified
137*635a8641SAndroid Build Coastguard Worker   // feature to |override_state|. Command-line overrides still take precedence
138*635a8641SAndroid Build Coastguard Worker   // over field trials, so this will have no effect if the feature is being
139*635a8641SAndroid Build Coastguard Worker   // overridden from the command-line. The associated field trial will be
140*635a8641SAndroid Build Coastguard Worker   // activated when the feature state for this feature is queried. This should
141*635a8641SAndroid Build Coastguard Worker   // be called during registration, after InitializeFromCommandLine() has been
142*635a8641SAndroid Build Coastguard Worker   // called but before the instance is registered via SetInstance().
143*635a8641SAndroid Build Coastguard Worker   void RegisterFieldTrialOverride(const std::string& feature_name,
144*635a8641SAndroid Build Coastguard Worker                                   OverrideState override_state,
145*635a8641SAndroid Build Coastguard Worker                                   FieldTrial* field_trial);
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker   // Loops through feature overrides and serializes them all into |allocator|.
148*635a8641SAndroid Build Coastguard Worker   void AddFeaturesToAllocator(PersistentMemoryAllocator* allocator);
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker   // Returns comma-separated lists of feature names (in the same format that is
151*635a8641SAndroid Build Coastguard Worker   // accepted by InitializeFromCommandLine()) corresponding to features that
152*635a8641SAndroid Build Coastguard Worker   // have been overridden - either through command-line or via FieldTrials. For
153*635a8641SAndroid Build Coastguard Worker   // those features that have an associated FieldTrial, the output entry will be
154*635a8641SAndroid Build Coastguard Worker   // of the format "FeatureName<TrialName", where "TrialName" is the name of the
155*635a8641SAndroid Build Coastguard Worker   // FieldTrial. Features that have overrides with OVERRIDE_USE_DEFAULT will be
156*635a8641SAndroid Build Coastguard Worker   // added to |enable_overrides| with a '*' character prefix. Must be called
157*635a8641SAndroid Build Coastguard Worker   // only after the instance has been initialized and registered.
158*635a8641SAndroid Build Coastguard Worker   void GetFeatureOverrides(std::string* enable_overrides,
159*635a8641SAndroid Build Coastguard Worker                            std::string* disable_overrides);
160*635a8641SAndroid Build Coastguard Worker 
161*635a8641SAndroid Build Coastguard Worker   // Like GetFeatureOverrides(), but only returns overrides that were specified
162*635a8641SAndroid Build Coastguard Worker   // explicitly on the command-line, omitting the ones from field trials.
163*635a8641SAndroid Build Coastguard Worker   void GetCommandLineFeatureOverrides(std::string* enable_overrides,
164*635a8641SAndroid Build Coastguard Worker                                       std::string* disable_overrides);
165*635a8641SAndroid Build Coastguard Worker 
166*635a8641SAndroid Build Coastguard Worker   // Returns whether the given |feature| is enabled. Must only be called after
167*635a8641SAndroid Build Coastguard Worker   // the singleton instance has been registered via SetInstance(). Additionally,
168*635a8641SAndroid Build Coastguard Worker   // a feature with a given name must only have a single corresponding Feature
169*635a8641SAndroid Build Coastguard Worker   // struct, which is checked in builds with DCHECKs enabled.
170*635a8641SAndroid Build Coastguard Worker   static bool IsEnabled(const Feature& feature);
171*635a8641SAndroid Build Coastguard Worker 
172*635a8641SAndroid Build Coastguard Worker   // Returns the field trial associated with the given |feature|. Must only be
173*635a8641SAndroid Build Coastguard Worker   // called after the singleton instance has been registered via SetInstance().
174*635a8641SAndroid Build Coastguard Worker   static FieldTrial* GetFieldTrial(const Feature& feature);
175*635a8641SAndroid Build Coastguard Worker 
176*635a8641SAndroid Build Coastguard Worker   // Splits a comma-separated string containing feature names into a vector. The
177*635a8641SAndroid Build Coastguard Worker   // resulting pieces point to parts of |input|.
178*635a8641SAndroid Build Coastguard Worker   static std::vector<base::StringPiece> SplitFeatureListString(
179*635a8641SAndroid Build Coastguard Worker       base::StringPiece input);
180*635a8641SAndroid Build Coastguard Worker 
181*635a8641SAndroid Build Coastguard Worker   // Initializes and sets an instance of FeatureList with feature overrides via
182*635a8641SAndroid Build Coastguard Worker   // command-line flags |enable_features| and |disable_features| if one has not
183*635a8641SAndroid Build Coastguard Worker   // already been set from command-line flags. Returns true if an instance did
184*635a8641SAndroid Build Coastguard Worker   // not previously exist. See InitializeFromCommandLine() for more details
185*635a8641SAndroid Build Coastguard Worker   // about |enable_features| and |disable_features| parameters.
186*635a8641SAndroid Build Coastguard Worker   static bool InitializeInstance(const std::string& enable_features,
187*635a8641SAndroid Build Coastguard Worker                                  const std::string& disable_features);
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   // Returns the singleton instance of FeatureList. Will return null until an
190*635a8641SAndroid Build Coastguard Worker   // instance is registered via SetInstance().
191*635a8641SAndroid Build Coastguard Worker   static FeatureList* GetInstance();
192*635a8641SAndroid Build Coastguard Worker 
193*635a8641SAndroid Build Coastguard Worker   // Registers the given |instance| to be the singleton feature list for this
194*635a8641SAndroid Build Coastguard Worker   // process. This should only be called once and |instance| must not be null.
195*635a8641SAndroid Build Coastguard Worker   // Note: If you are considering using this for the purposes of testing, take
196*635a8641SAndroid Build Coastguard Worker   // a look at using base/test/scoped_feature_list.h instead.
197*635a8641SAndroid Build Coastguard Worker   static void SetInstance(std::unique_ptr<FeatureList> instance);
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker   // Clears the previously-registered singleton instance for tests and returns
200*635a8641SAndroid Build Coastguard Worker   // the old instance.
201*635a8641SAndroid Build Coastguard Worker   // Note: Most tests should never call this directly. Instead consider using
202*635a8641SAndroid Build Coastguard Worker   // base::test::ScopedFeatureList.
203*635a8641SAndroid Build Coastguard Worker   static std::unique_ptr<FeatureList> ClearInstanceForTesting();
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker   // Sets a given (initialized) |instance| to be the singleton feature list,
206*635a8641SAndroid Build Coastguard Worker   // for testing. Existing instance must be null. This is primarily intended
207*635a8641SAndroid Build Coastguard Worker   // to support base::test::ScopedFeatureList helper class.
208*635a8641SAndroid Build Coastguard Worker   static void RestoreInstanceForTesting(std::unique_ptr<FeatureList> instance);
209*635a8641SAndroid Build Coastguard Worker 
210*635a8641SAndroid Build Coastguard Worker  private:
211*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FeatureListTest, CheckFeatureIdentity);
212*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FeatureListTest,
213*635a8641SAndroid Build Coastguard Worker                            StoreAndRetrieveFeaturesFromSharedMemory);
214*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FeatureListTest,
215*635a8641SAndroid Build Coastguard Worker                            StoreAndRetrieveAssociatedFeaturesFromSharedMemory);
216*635a8641SAndroid Build Coastguard Worker 
217*635a8641SAndroid Build Coastguard Worker   struct OverrideEntry {
218*635a8641SAndroid Build Coastguard Worker     // The overridden enable (on/off) state of the feature.
219*635a8641SAndroid Build Coastguard Worker     const OverrideState overridden_state;
220*635a8641SAndroid Build Coastguard Worker 
221*635a8641SAndroid Build Coastguard Worker     // An optional associated field trial, which will be activated when the
222*635a8641SAndroid Build Coastguard Worker     // state of the feature is queried for the first time. Weak pointer to the
223*635a8641SAndroid Build Coastguard Worker     // FieldTrial object that is owned by the FieldTrialList singleton.
224*635a8641SAndroid Build Coastguard Worker     base::FieldTrial* field_trial;
225*635a8641SAndroid Build Coastguard Worker 
226*635a8641SAndroid Build Coastguard Worker     // Specifies whether the feature's state is overridden by |field_trial|.
227*635a8641SAndroid Build Coastguard Worker     // If it's not, and |field_trial| is not null, it means it is simply an
228*635a8641SAndroid Build Coastguard Worker     // associated field trial for reporting purposes (and |overridden_state|
229*635a8641SAndroid Build Coastguard Worker     // came from the command-line).
230*635a8641SAndroid Build Coastguard Worker     const bool overridden_by_field_trial;
231*635a8641SAndroid Build Coastguard Worker 
232*635a8641SAndroid Build Coastguard Worker     // TODO(asvitkine): Expand this as more support is added.
233*635a8641SAndroid Build Coastguard Worker 
234*635a8641SAndroid Build Coastguard Worker     // Constructs an OverrideEntry for the given |overridden_state|. If
235*635a8641SAndroid Build Coastguard Worker     // |field_trial| is not null, it implies that |overridden_state| comes from
236*635a8641SAndroid Build Coastguard Worker     // the trial, so |overridden_by_field_trial| will be set to true.
237*635a8641SAndroid Build Coastguard Worker     OverrideEntry(OverrideState overridden_state, FieldTrial* field_trial);
238*635a8641SAndroid Build Coastguard Worker   };
239*635a8641SAndroid Build Coastguard Worker 
240*635a8641SAndroid Build Coastguard Worker   // Finalizes the initialization state of the FeatureList, so that no further
241*635a8641SAndroid Build Coastguard Worker   // overrides can be registered. This is called by SetInstance() on the
242*635a8641SAndroid Build Coastguard Worker   // singleton feature list that is being registered.
243*635a8641SAndroid Build Coastguard Worker   void FinalizeInitialization();
244*635a8641SAndroid Build Coastguard Worker 
245*635a8641SAndroid Build Coastguard Worker   // Returns whether the given |feature| is enabled. This is invoked by the
246*635a8641SAndroid Build Coastguard Worker   // public FeatureList::IsEnabled() static function on the global singleton.
247*635a8641SAndroid Build Coastguard Worker   // Requires the FeatureList to have already been fully initialized.
248*635a8641SAndroid Build Coastguard Worker   bool IsFeatureEnabled(const Feature& feature);
249*635a8641SAndroid Build Coastguard Worker 
250*635a8641SAndroid Build Coastguard Worker   // Returns the field trial associated with the given |feature|. This is
251*635a8641SAndroid Build Coastguard Worker   // invoked by the public FeatureList::GetFieldTrial() static function on the
252*635a8641SAndroid Build Coastguard Worker   // global singleton. Requires the FeatureList to have already been fully
253*635a8641SAndroid Build Coastguard Worker   // initialized.
254*635a8641SAndroid Build Coastguard Worker   base::FieldTrial* GetAssociatedFieldTrial(const Feature& feature);
255*635a8641SAndroid Build Coastguard Worker 
256*635a8641SAndroid Build Coastguard Worker   // For each feature name in comma-separated list of strings |feature_list|,
257*635a8641SAndroid Build Coastguard Worker   // registers an override with the specified |overridden_state|. Also, will
258*635a8641SAndroid Build Coastguard Worker   // associate an optional named field trial if the entry is of the format
259*635a8641SAndroid Build Coastguard Worker   // "FeatureName<TrialName".
260*635a8641SAndroid Build Coastguard Worker   void RegisterOverridesFromCommandLine(const std::string& feature_list,
261*635a8641SAndroid Build Coastguard Worker                                         OverrideState overridden_state);
262*635a8641SAndroid Build Coastguard Worker 
263*635a8641SAndroid Build Coastguard Worker   // Registers an override for feature |feature_name|. The override specifies
264*635a8641SAndroid Build Coastguard Worker   // whether the feature should be on or off (via |overridden_state|), which
265*635a8641SAndroid Build Coastguard Worker   // will take precedence over the feature's default state. If |field_trial| is
266*635a8641SAndroid Build Coastguard Worker   // not null, registers the specified field trial object to be associated with
267*635a8641SAndroid Build Coastguard Worker   // the feature, which will activate the field trial when the feature state is
268*635a8641SAndroid Build Coastguard Worker   // queried. If an override is already registered for the given feature, it
269*635a8641SAndroid Build Coastguard Worker   // will not be changed.
270*635a8641SAndroid Build Coastguard Worker   void RegisterOverride(StringPiece feature_name,
271*635a8641SAndroid Build Coastguard Worker                         OverrideState overridden_state,
272*635a8641SAndroid Build Coastguard Worker                         FieldTrial* field_trial);
273*635a8641SAndroid Build Coastguard Worker 
274*635a8641SAndroid Build Coastguard Worker   // Implementation of GetFeatureOverrides() with a parameter that specifies
275*635a8641SAndroid Build Coastguard Worker   // whether only command-line enabled overrides should be emitted. See that
276*635a8641SAndroid Build Coastguard Worker   // function's comments for more details.
277*635a8641SAndroid Build Coastguard Worker   void GetFeatureOverridesImpl(std::string* enable_overrides,
278*635a8641SAndroid Build Coastguard Worker                                std::string* disable_overrides,
279*635a8641SAndroid Build Coastguard Worker                                bool command_line_only);
280*635a8641SAndroid Build Coastguard Worker 
281*635a8641SAndroid Build Coastguard Worker   // Verifies that there's only a single definition of a Feature struct for a
282*635a8641SAndroid Build Coastguard Worker   // given feature name. Keeps track of the first seen Feature struct for each
283*635a8641SAndroid Build Coastguard Worker   // feature. Returns false when called on a Feature struct with a different
284*635a8641SAndroid Build Coastguard Worker   // address than the first one it saw for that feature name. Used only from
285*635a8641SAndroid Build Coastguard Worker   // DCHECKs and tests.
286*635a8641SAndroid Build Coastguard Worker   bool CheckFeatureIdentity(const Feature& feature);
287*635a8641SAndroid Build Coastguard Worker 
288*635a8641SAndroid Build Coastguard Worker   // Map from feature name to an OverrideEntry struct for the feature, if it
289*635a8641SAndroid Build Coastguard Worker   // exists.
290*635a8641SAndroid Build Coastguard Worker   std::map<std::string, OverrideEntry> overrides_;
291*635a8641SAndroid Build Coastguard Worker 
292*635a8641SAndroid Build Coastguard Worker   // Locked map that keeps track of seen features, to ensure a single feature is
293*635a8641SAndroid Build Coastguard Worker   // only defined once. This verification is only done in builds with DCHECKs
294*635a8641SAndroid Build Coastguard Worker   // enabled.
295*635a8641SAndroid Build Coastguard Worker   Lock feature_identity_tracker_lock_;
296*635a8641SAndroid Build Coastguard Worker   std::map<std::string, const Feature*> feature_identity_tracker_;
297*635a8641SAndroid Build Coastguard Worker 
298*635a8641SAndroid Build Coastguard Worker   // Whether this object has been fully initialized. This gets set to true as a
299*635a8641SAndroid Build Coastguard Worker   // result of FinalizeInitialization().
300*635a8641SAndroid Build Coastguard Worker   bool initialized_ = false;
301*635a8641SAndroid Build Coastguard Worker 
302*635a8641SAndroid Build Coastguard Worker   // Whether this object has been initialized from command line.
303*635a8641SAndroid Build Coastguard Worker   bool initialized_from_command_line_ = false;
304*635a8641SAndroid Build Coastguard Worker 
305*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(FeatureList);
306*635a8641SAndroid Build Coastguard Worker };
307*635a8641SAndroid Build Coastguard Worker 
308*635a8641SAndroid Build Coastguard Worker }  // namespace base
309*635a8641SAndroid Build Coastguard Worker 
310*635a8641SAndroid Build Coastguard Worker #endif  // BASE_FEATURE_LIST_H_
311