Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(606)

Side by Side Diff: base/metrics/feature_list.h

Issue 1278403003: Initial implementation of FeatureList in base/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/metrics/BUILD.gn ('k') | base/metrics/feature_list.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // 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 BASE_METRICS_FEATURE_LIST_H_
6 #define BASE_METRICS_FEATURE_LIST_H_
7
8 #include <map>
9 #include <string>
10
11 #include "base/base_export.h"
12 #include "base/basictypes.h"
13 #include "base/containers/scoped_ptr_map.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/synchronization/lock.h"
16
17 namespace base {
18
19 // The Feature struct is used to define the default state for a feature. See
20 // comment below for more details. There must only ever be one struct instance
21 // for a given feature name - generally defined as a global variable.
22 struct BASE_EXPORT Feature {
23 // The name of the feagture.
rkaplow 2015/08/30 19:36:22 feature
Alexei Svitkine (slow) 2015/08/31 16:21:01 Done.
24 const char* const name;
25
26 // The default state (i.e. enabled or disabled) for this feature.
27 const bool default_state;
Ilya Sherman 2015/09/01 03:55:25 Let's use an enum rather than a bool. "default_st
28 };
29
30 // The FeatureList class is used to determine whether a given feature is on or
31 // off. It provides an authoritative answer, taking into account command-line
32 // overrides and experimental control.
33 //
34 // The basic use case is for any feature that can be toggled (e.g. through
35 // command-line or an experiment) to have a defined Feature struct, e.g.:
36 //
37 // struct base::Feature kMyGreatFeature {
38 // "MyGreatFeature", true
39 // };
40 //
41 // Then, client code that wishes to query the state of the feature would check:
42 //
43 // if (base::FeatureList::IsEnabled(kMyGreatFeature)) {
rkaplow 2015/08/30 19:36:22 super minor nit but for even for sample syntax I w
Alexei Svitkine (slow) 2015/08/31 16:21:01 Done.
44 //
45 // Behind the scenes, the above call would take into account any command-line
46 // flags to enable or disable the feature, any experiments that may control it
rkaplow 2015/08/30 19:36:22 I would make it clear here the ordering of priorit
Alexei Svitkine (slow) 2015/08/31 16:21:01 Done.
47 // and finally its default state, to determine whether the feature is on.
48 //
49 // After initial initialization (which should be done single-threaded), the
50 // FeatureList API is thread safe.
51 //
52 // Note: This class is a singleton, but does not use base/memory/singleton.h in
53 // order to have control over its initialization sequence. Specifically, the
54 // intended use is to create an instance of this class and fully initialize it,
55 // before setting it as the singleton for a process, via SetInstance().
56 class BASE_EXPORT FeatureList {
57 public:
58 FeatureList();
59 ~FeatureList();
60
61 // Initializes feature overrides via command-line flags |enable_features| and
62 // |disable_features|, each of which is a comma-separated list of features to
63 // enable or disable, respectively. If a feature appears on both lists, then
64 // it will be disabled. Must only be invoked during initialization phase
65 // (before FinalizeInitialization() has been called).
66 void InitializeFromCommandLine(const std::string& enable_features,
67 const std::string& disable_features);
68
69 // Finalizes the initialization state of the FeatureList instance, so that no
70 // further overrides can be registered. For the singleton feature list, this
71 // gets called when it is registered via SetInstance().
72 void FinalizeInitialization();
73
74 // Returns whether the given |feature| is enabled. This is member function is
75 // normally called through the static IsEnabled() function, which corresponds
76 // to GeInstance()->IsFeatureEnabled(). Must only be called on a FeatureList
77 // that has been fully initialized (FinalizeInitialization() called).
78 bool IsFeatureEnabled(const Feature& feature);
rkaplow 2015/08/30 19:36:22 can this be private?
Alexei Svitkine (slow) 2015/08/31 16:21:01 I don't think there's a problem with it being publ
79
80 // Returns whether the given |feature| is enabled. Must only be called after
81 // the singleton instance has been registered via SetInstance(). Additionally,
82 // a feature with a given name must only have a single corresponding Feature
83 // struct, which is checked for in debug builds.
84 static bool IsEnabled(const Feature& feature);
85
86 // Returns the singleton instance of FeatureList. Will return null until an
87 // instance is registered via SetInstance().
88 static FeatureList* GetInstance();
89
90 // Registers the given |instance| to be the singleton feature list for this
91 // process. This should only be called once and |instance| must not be null.
92 static void SetInstance(scoped_ptr<FeatureList> instance);
93
94 // Clears the previously-registered singleton instance for tests.
95 static void ClearInstanceForTesting();
96
97 private:
98 FRIEND_TEST_ALL_PREFIXES(FeatureListTest, CheckFeatureIdentity);
Ilya Sherman 2015/09/01 03:55:25 Please use a mechanism that exposes a more narrow
99
100 // Registers an override for feature |feature_name|. The override specifies
101 // whether the feature should be on or off (via |overridden_state|), which
102 // will take precedence over the feature's default state.
103 void RegisterOverride(const std::string& feature_name, bool overriden_state);
104
105 // Checks whether |feature| has the same address as any previously seen
106 // Feature structs with the same name. Used only from DCHECKs and tests.
107 bool CheckFeatureIdentity(const Feature& feature);
108
109 struct OverrideEntry {
110 // The overridden enable (on/off) state of the feature.
111 bool overriden_state;
112
113 // TODO(asvitkine): Expand this as more support is added.
114
115 explicit OverrideEntry(bool overriden_state);
116 };
117 // Map from feature name to an OverrideEntry struct for the feature, if it
118 // exists. A ScopedPtrMap<> is used because OverrideEntry will later expand
119 // to hold additional non-copyable fields.
120 ScopedPtrMap<std::string, scoped_ptr<OverrideEntry>> overrides_;
121
122 // Locked map that keeps track of seen features, to ensure a single feature is
123 // only defined once. This verification is only done in builds with DCHECKs
124 // enabled.
125 Lock feature_identity_tracker_lock_;
126 std::map<std::string, const Feature*> feature_identity_tracker_;
127
128 // Whether this object has been fully initialized. This gets set to true as a
129 // result of FinalizeInitialization().
130 bool initialized_;
131
132 DISALLOW_COPY_AND_ASSIGN(FeatureList);
133 };
134
135 } // namespace base
136
137 #endif // BASE_METRICS_FEATURE_LIST_H_
OLDNEW
« no previous file with comments | « base/metrics/BUILD.gn ('k') | base/metrics/feature_list.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698