| 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 #include "base/feature_list.h" | 5 #include "base/feature_list.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 // serialization. This function checks that the strings are ASCII (since they | 28 // serialization. This function checks that the strings are ASCII (since they |
| 29 // are used in command-line API functions that require ASCII) and whether there | 29 // are used in command-line API functions that require ASCII) and whether there |
| 30 // are any reserved characters present, returning true if the string is valid. | 30 // are any reserved characters present, returning true if the string is valid. |
| 31 // Only called in DCHECKs. | 31 // Only called in DCHECKs. |
| 32 bool IsValidFeatureOrFieldTrialName(const std::string& name) { | 32 bool IsValidFeatureOrFieldTrialName(const std::string& name) { |
| 33 return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos; | 33 return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos; |
| 34 } | 34 } |
| 35 | 35 |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 FeatureList::FeatureList() : initialized_(false) {} | 38 FeatureList::FeatureList() |
| 39 : initialized_(false), |
| 40 initialized_from_command_line_(false) { |
| 41 } |
| 39 | 42 |
| 40 FeatureList::~FeatureList() {} | 43 FeatureList::~FeatureList() {} |
| 41 | 44 |
| 42 void FeatureList::InitializeFromCommandLine( | 45 void FeatureList::InitializeFromCommandLine( |
| 43 const std::string& enable_features, | 46 const std::string& enable_features, |
| 44 const std::string& disable_features) { | 47 const std::string& disable_features) { |
| 45 DCHECK(!initialized_); | 48 DCHECK(!initialized_); |
| 46 | 49 |
| 47 // Process disabled features first, so that disabled ones take precedence over | 50 // Process disabled features first, so that disabled ones take precedence over |
| 48 // enabled ones (since RegisterOverride() uses insert()). | 51 // enabled ones (since RegisterOverride() uses insert()). |
| 49 RegisterOverridesFromCommandLine(disable_features, OVERRIDE_DISABLE_FEATURE); | 52 RegisterOverridesFromCommandLine(disable_features, OVERRIDE_DISABLE_FEATURE); |
| 50 RegisterOverridesFromCommandLine(enable_features, OVERRIDE_ENABLE_FEATURE); | 53 RegisterOverridesFromCommandLine(enable_features, OVERRIDE_ENABLE_FEATURE); |
| 54 |
| 55 initialized_from_command_line_ = true; |
| 51 } | 56 } |
| 52 | 57 |
| 53 bool FeatureList::IsFeatureOverriddenFromCommandLine( | 58 bool FeatureList::IsFeatureOverriddenFromCommandLine( |
| 54 const std::string& feature_name, | 59 const std::string& feature_name, |
| 55 OverrideState state) const { | 60 OverrideState state) const { |
| 56 auto it = overrides_.find(feature_name); | 61 auto it = overrides_.find(feature_name); |
| 57 return it != overrides_.end() && it->second.overridden_state == state && | 62 return it != overrides_.end() && it->second.overridden_state == state && |
| 58 !it->second.overridden_by_field_trial; | 63 !it->second.overridden_by_field_trial; |
| 59 } | 64 } |
| 60 | 65 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 return GetInstance()->IsFeatureEnabled(feature); | 136 return GetInstance()->IsFeatureEnabled(feature); |
| 132 } | 137 } |
| 133 | 138 |
| 134 // static | 139 // static |
| 135 std::vector<std::string> FeatureList::SplitFeatureListString( | 140 std::vector<std::string> FeatureList::SplitFeatureListString( |
| 136 const std::string& input) { | 141 const std::string& input) { |
| 137 return SplitString(input, ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); | 142 return SplitString(input, ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); |
| 138 } | 143 } |
| 139 | 144 |
| 140 // static | 145 // static |
| 141 void FeatureList::InitializeInstance() { | 146 void FeatureList::InitializeInstance(const std::string& enable_features, |
| 142 if (g_instance) | 147 const std::string& disable_features) { |
| 143 return; | 148 // We want to initialize a new instance here to support command-line features |
| 144 SetInstance(make_scoped_ptr(new FeatureList)); | 149 // in testing better. For example, we initialize a dummy instance in |
| 150 // base/test/test_suite.cc, and override it in content/browser/ |
| 151 // browser_main_loop.cc. |
| 152 // On the other hand, we want to avoid re-initialization from command line. |
| 153 // For example, we initialize an instance in chrome/browser/ |
| 154 // chrome_browser_main.cc and do not override it in content/browser/ |
| 155 // browser_main_loop.cc. |
| 156 if (g_instance) { |
| 157 if (g_instance->initialized_from_command_line_) |
| 158 return; |
| 159 |
| 160 delete g_instance; |
| 161 g_instance = nullptr; |
| 162 } |
| 163 |
| 164 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| 165 feature_list->InitializeFromCommandLine(enable_features, disable_features); |
| 166 base::FeatureList::SetInstance(std::move(feature_list)); |
| 145 } | 167 } |
| 146 | 168 |
| 147 // static | 169 // static |
| 148 FeatureList* FeatureList::GetInstance() { | 170 FeatureList* FeatureList::GetInstance() { |
| 149 return g_instance; | 171 return g_instance; |
| 150 } | 172 } |
| 151 | 173 |
| 152 // static | 174 // static |
| 153 void FeatureList::SetInstance(scoped_ptr<FeatureList> instance) { | 175 void FeatureList::SetInstance(scoped_ptr<FeatureList> instance) { |
| 154 DCHECK(!g_instance); | 176 DCHECK(!g_instance); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 return it->second == &feature; | 266 return it->second == &feature; |
| 245 } | 267 } |
| 246 | 268 |
| 247 FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state, | 269 FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state, |
| 248 FieldTrial* field_trial) | 270 FieldTrial* field_trial) |
| 249 : overridden_state(overridden_state), | 271 : overridden_state(overridden_state), |
| 250 field_trial(field_trial), | 272 field_trial(field_trial), |
| 251 overridden_by_field_trial(field_trial != nullptr) {} | 273 overridden_by_field_trial(field_trial != nullptr) {} |
| 252 | 274 |
| 253 } // namespace base | 275 } // namespace base |
| OLD | NEW |