| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_FEATURE_LIST_H_ | 5 #ifndef BASE_FEATURE_LIST_H_ |
| 6 #define BASE_FEATURE_LIST_H_ | 6 #define BASE_FEATURE_LIST_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> |
| 10 | 11 |
| 11 #include "base/base_export.h" | 12 #include "base/base_export.h" |
| 12 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 13 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 16 | 17 |
| 17 namespace base { | 18 namespace base { |
| 18 | 19 |
| 20 class FieldTrial; |
| 21 |
| 19 // Specifies whether a given feature is enabled or disabled by default. | 22 // Specifies whether a given feature is enabled or disabled by default. |
| 20 enum FeatureState { | 23 enum FeatureState { |
| 21 FEATURE_DISABLED_BY_DEFAULT, | 24 FEATURE_DISABLED_BY_DEFAULT, |
| 22 FEATURE_ENABLED_BY_DEFAULT, | 25 FEATURE_ENABLED_BY_DEFAULT, |
| 23 }; | 26 }; |
| 24 | 27 |
| 25 // The Feature struct is used to define the default state for a feature. See | 28 // The Feature struct is used to define the default state for a feature. See |
| 26 // comment below for more details. There must only ever be one struct instance | 29 // comment below for more details. There must only ever be one struct instance |
| 27 // for a given feature name - generally defined as a constant global variable or | 30 // for a given feature name - generally defined as a constant global variable or |
| 28 // file static. | 31 // file static. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 ~FeatureList(); | 79 ~FeatureList(); |
| 77 | 80 |
| 78 // Initializes feature overrides via command-line flags |enable_features| and | 81 // Initializes feature overrides via command-line flags |enable_features| and |
| 79 // |disable_features|, each of which is a comma-separated list of features to | 82 // |disable_features|, each of which is a comma-separated list of features to |
| 80 // enable or disable, respectively. If a feature appears on both lists, then | 83 // enable or disable, respectively. If a feature appears on both lists, then |
| 81 // it will be disabled. Must only be invoked during the initialization phase | 84 // it will be disabled. Must only be invoked during the initialization phase |
| 82 // (before FinalizeInitialization() has been called). | 85 // (before FinalizeInitialization() has been called). |
| 83 void InitializeFromCommandLine(const std::string& enable_features, | 86 void InitializeFromCommandLine(const std::string& enable_features, |
| 84 const std::string& disable_features); | 87 const std::string& disable_features); |
| 85 | 88 |
| 89 // Specifies whether a feature override enables or disables the feature. |
| 90 enum OverrideState { |
| 91 OVERRIDE_DISABLE_FEATURE, |
| 92 OVERRIDE_ENABLE_FEATURE, |
| 93 }; |
| 94 |
| 95 // Registers a field trial to override the enabled state of the specified |
| 96 // feature to |override_state|. Command-line overrides still take precedence |
| 97 // over field trials, so this will have no effect if the feature is being |
| 98 // overridden from the command-line. The associated field trial will be |
| 99 // activated when the feature state for this feature is queried. This should |
| 100 // be called during registration, after InitializeFromCommandLine() has been |
| 101 // called but before the instance is registered via SetInstance(). |
| 102 void RegisterFieldTrialOverride(const std::string& feature_name, |
| 103 OverrideState override_state, |
| 104 FieldTrial* field_trial); |
| 105 |
| 106 // Creates and associates a field trial for reporting purposes corresponding |
| 107 // to the command-line setting the feature state to |for_overridden_state|. |
| 108 // This is a no-op and returns null if the specified feature is not being |
| 109 // affected by a command-line override to the given state. Otherwise, it |
| 110 // creates a field trial with name |field_trial_name| and a single group named |
| 111 // |group_name| and returns it. The trial will be activated when the state of |
| 112 // the feature is queried. This should be called during registration, after |
| 113 // InitializeFromCommandLine() has been called but before the instance is |
| 114 // registered via SetInstance(). |
| 115 FieldTrial* AssociateReportingFieldTrial(const std::string& feature_name, |
| 116 OverrideState for_overridden_state, |
| 117 const std::string& field_trial_name, |
| 118 const std::string& group_name); |
| 119 |
| 86 // Returns whether the given |feature| is enabled. Must only be called after | 120 // Returns whether the given |feature| is enabled. Must only be called after |
| 87 // the singleton instance has been registered via SetInstance(). Additionally, | 121 // the singleton instance has been registered via SetInstance(). Additionally, |
| 88 // a feature with a given name must only have a single corresponding Feature | 122 // a feature with a given name must only have a single corresponding Feature |
| 89 // struct, which is checked in builds with DCHECKs enabled. | 123 // struct, which is checked in builds with DCHECKs enabled. |
| 90 static bool IsEnabled(const Feature& feature); | 124 static bool IsEnabled(const Feature& feature); |
| 91 | 125 |
| 92 // Returns the singleton instance of FeatureList. Will return null until an | 126 // Returns the singleton instance of FeatureList. Will return null until an |
| 93 // instance is registered via SetInstance(). | 127 // instance is registered via SetInstance(). |
| 94 static FeatureList* GetInstance(); | 128 static FeatureList* GetInstance(); |
| 95 | 129 |
| 96 // Registers the given |instance| to be the singleton feature list for this | 130 // Registers the given |instance| to be the singleton feature list for this |
| 97 // process. This should only be called once and |instance| must not be null. | 131 // process. This should only be called once and |instance| must not be null. |
| 98 static void SetInstance(scoped_ptr<FeatureList> instance); | 132 static void SetInstance(scoped_ptr<FeatureList> instance); |
| 99 | 133 |
| 100 // Clears the previously-registered singleton instance for tests. | 134 // Clears the previously-registered singleton instance for tests. |
| 101 static void ClearInstanceForTesting(); | 135 static void ClearInstanceForTesting(); |
| 102 | 136 |
| 103 private: | 137 private: |
| 104 FRIEND_TEST_ALL_PREFIXES(FeatureListTest, CheckFeatureIdentity); | 138 FRIEND_TEST_ALL_PREFIXES(FeatureListTest, CheckFeatureIdentity); |
| 105 | 139 |
| 106 // Specifies whether a feature override enables or disables the feature. | 140 struct OverrideEntry { |
| 107 enum OverrideState { | 141 // The overridden enable (on/off) state of the feature. |
| 108 OVERRIDE_DISABLE_FEATURE, | 142 const OverrideState overridden_state; |
| 109 OVERRIDE_ENABLE_FEATURE, | 143 |
| 144 // An optional associated field trial, which will be activated when the |
| 145 // state of the feature is queried for the first time. Weak pointer to the |
| 146 // FieldTrial object that is owned by the FieldTrialList singleton. |
| 147 base::FieldTrial* field_trial; |
| 148 |
| 149 // TODO(asvitkine): Expand this as more support is added. |
| 150 |
| 151 OverrideEntry(OverrideState overridden_state, FieldTrial* field_trial); |
| 110 }; | 152 }; |
| 111 | 153 |
| 112 // Finalizes the initialization state of the FeatureList, so that no further | 154 // Finalizes the initialization state of the FeatureList, so that no further |
| 113 // overrides can be registered. This is called by SetInstance() on the | 155 // overrides can be registered. This is called by SetInstance() on the |
| 114 // singleton feature list that is being registered. | 156 // singleton feature list that is being registered. |
| 115 void FinalizeInitialization(); | 157 void FinalizeInitialization(); |
| 116 | 158 |
| 117 // Returns whether the given |feature| is enabled. This is invoked by the | 159 // Returns whether the given |feature| is enabled. This is invoked by the |
| 118 // public FeatureList::IsEnabled() static function on the global singleton. | 160 // public FeatureList::IsEnabled() static function on the global singleton. |
| 119 // Requires the FeatureList to have already been fully initialized. | 161 // Requires the FeatureList to have already been fully initialized. |
| 120 bool IsFeatureEnabled(const Feature& feature); | 162 bool IsFeatureEnabled(const Feature& feature); |
| 121 | 163 |
| 122 // Registers an override for feature |feature_name|. The override specifies | 164 // Registers an override for feature |feature_name|. The override specifies |
| 123 // whether the feature should be on or off (via |overridden_state|), which | 165 // whether the feature should be on or off (via |overridden_state|), which |
| 124 // will take precedence over the feature's default state. | 166 // will take precedence over the feature's default state. If |field_trial| is |
| 125 void RegisterOverride(const std::string& feature_name, | 167 // not null, registers the specified field trial object to be associated with |
| 126 OverrideState overridden_state); | 168 // the feature, which will activate the field trial when the feature state is |
| 169 // queried. If an override is already registered for the given feature, it |
| 170 // will not be changed. Returns a pair<entry, bool>, where the bool indicates |
| 171 // whether the override was registered and entry is the entry in the map - |
| 172 // either the existing one or the one that was inserted. |
| 173 std::pair<const FeatureList::OverrideEntry&, bool> RegisterOverride( |
| 174 const std::string& feature_name, |
| 175 OverrideState overridden_state, |
| 176 FieldTrial* field_trial); |
| 127 | 177 |
| 128 // Verifies that there's only a single definition of a Feature struct for a | 178 // Verifies that there's only a single definition of a Feature struct for a |
| 129 // given feature name. Keeps track of the first seen Feature struct for each | 179 // given feature name. Keeps track of the first seen Feature struct for each |
| 130 // feature. Returns false when called on a Feature struct with a different | 180 // feature. Returns false when called on a Feature struct with a different |
| 131 // address than the first one it saw for that feature name. Used only from | 181 // address than the first one it saw for that feature name. Used only from |
| 132 // DCHECKs and tests. | 182 // DCHECKs and tests. |
| 133 bool CheckFeatureIdentity(const Feature& feature); | 183 bool CheckFeatureIdentity(const Feature& feature); |
| 134 | 184 |
| 135 struct OverrideEntry { | |
| 136 // The overridden enable (on/off) state of the feature. | |
| 137 const OverrideState overridden_state; | |
| 138 | |
| 139 // TODO(asvitkine): Expand this as more support is added. | |
| 140 | |
| 141 explicit OverrideEntry(OverrideState overridden_state); | |
| 142 }; | |
| 143 // Map from feature name to an OverrideEntry struct for the feature, if it | 185 // Map from feature name to an OverrideEntry struct for the feature, if it |
| 144 // exists. | 186 // exists. |
| 145 std::map<std::string, OverrideEntry> overrides_; | 187 std::map<std::string, OverrideEntry> overrides_; |
| 146 | 188 |
| 147 // Locked map that keeps track of seen features, to ensure a single feature is | 189 // Locked map that keeps track of seen features, to ensure a single feature is |
| 148 // only defined once. This verification is only done in builds with DCHECKs | 190 // only defined once. This verification is only done in builds with DCHECKs |
| 149 // enabled. | 191 // enabled. |
| 150 Lock feature_identity_tracker_lock_; | 192 Lock feature_identity_tracker_lock_; |
| 151 std::map<std::string, const Feature*> feature_identity_tracker_; | 193 std::map<std::string, const Feature*> feature_identity_tracker_; |
| 152 | 194 |
| 153 // Whether this object has been fully initialized. This gets set to true as a | 195 // Whether this object has been fully initialized. This gets set to true as a |
| 154 // result of FinalizeInitialization(). | 196 // result of FinalizeInitialization(). |
| 155 bool initialized_; | 197 bool initialized_; |
| 156 | 198 |
| 157 DISALLOW_COPY_AND_ASSIGN(FeatureList); | 199 DISALLOW_COPY_AND_ASSIGN(FeatureList); |
| 158 }; | 200 }; |
| 159 | 201 |
| 160 } // namespace base | 202 } // namespace base |
| 161 | 203 |
| 162 #endif // BASE_FEATURE_LIST_H_ | 204 #endif // BASE_FEATURE_LIST_H_ |
| OLD | NEW |