base::FeatureList::IsEnabled(kMyFeature)
const base::Feature kMyFeature {
"MyFeature", base::FEATURE_ENABLED_BY_DEFAULT
};Hi chromium-dev,I'd like to announce a new API in base/ intended to replace the current practice of --enable-foo and --disable-foo style switches for enabling and disabling features. The new base/feature_list.h API simplifies code to test for the state of a feature to:base::FeatureList::IsEnabled(kMyFeature)
… which can greatly simplify the logic that otherwise may need to have multiple conditionals checking CommandLine and FieldTrial states.The new API allows expressing the default state of a Feature in a structured way, as part of its definition, while still allowing the state to be overridden through the command-line or with a FieldTrial. This is done by defining a base::Feature struct in the codebase for each feature:const base::Feature kMyFeature {
"MyFeature", base::FEATURE_ENABLED_BY_DEFAULT
};(The above entry can live in a standard location analogous to e.g. chrome_switches.[cc|h] or content_switches.[cc|h] - i.e. chrome_features.cc or content_features.cc, but can live within a component.)For each feature, you can turn it on or off from the command-line via:--enable-features=MyFeature--disable-features=MyFeatureSo you don't need to add your own --enable-foo and --disable-foo switches when using the new API. The above flags also support passing a comma-separated list of feature names. This is also supported for chrome://flags, where you can use the FEATURE_VALUE_TYPE() macro to define your entry.Finally, the other benefit of FeatureList is integration with VariationsService, which allows having a server-side FieldTrial override the default state of a feature. Besides experimentation, this is also useful as a kill switch mechanism for your feature, if needed. (This still
requires a browser restart to take effect; I'm planning to later expand this support to allow runtime killing of specific features that opt-in to that functionality, but that's not implemented yet.)So, going forward if you see yourself adding something that requires --enable-foo and --disable-foo flags, considering using base/feature_list.h instead, as eventually we'd like to get to a point where all of this is done through FeatureList. Also, if you'd like to help migrate existing flags to FeatureList API, all help is appreciated!
---Alexei
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
On Tue, Nov 24, 2015 at 10:53 AM, Alexei Svitkine <asvi...@chromium.org> wrote:Hi chromium-dev,I'd like to announce a new API in base/ intended to replace the current practice of --enable-foo and --disable-foo style switches for enabling and disabling features. The new base/feature_list.h API simplifies code to test for the state of a feature to:base::FeatureList::IsEnabled(kMyFeature)
… which can greatly simplify the logic that otherwise may need to have multiple conditionals checking CommandLine and FieldTrial states.The new API allows expressing the default state of a Feature in a structured way, as part of its definition, while still allowing the state to be overridden through the command-line or with a FieldTrial. This is done by defining a base::Feature struct in the codebase for each feature:const base::Feature kMyFeature {
"MyFeature", base::FEATURE_ENABLED_BY_DEFAULT
};(The above entry can live in a standard location analogous to e.g. chrome_switches.[cc|h] or content_switches.[cc|h] - i.e. chrome_features.cc or content_features.cc, but can live within a component.)For each feature, you can turn it on or off from the command-line via:--enable-features=MyFeature--disable-features=MyFeatureSo you don't need to add your own --enable-foo and --disable-foo switches when using the new API. The above flags also support passing a comma-separated list of feature names. This is also supported for chrome://flags, where you can use the FEATURE_VALUE_TYPE() macro to define your entry.Finally, the other benefit of FeatureList is integration with VariationsService, which allows having a server-side FieldTrial override the default state of a feature. Besides experimentation, this is also useful as a kill switch mechanism for your feature, if needed. (This stillIs this state surfaced somewhere so users can report what features their browser instance is using when making bug reports?
requires a browser restart to take effect; I'm planning to later expand this support to allow runtime killing of specific features that opt-in to that functionality, but that's not implemented yet.)So, going forward if you see yourself adding something that requires --enable-foo and --disable-foo flags, considering using base/feature_list.h instead, as eventually we'd like to get to a point where all of this is done through FeatureList. Also, if you'd like to help migrate existing flags to FeatureList API, all help is appreciated!How does this work with ChromeOS guest mode? There's a whitelist of command-line flags, so the enable/disable features flags need to be whitelisted to allow features to be overridden in guest mode: https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/chromeos/login/chrome_restart_request.cc Otherwise you get different behaviour there which we don't usually want for graphics-related stuff. But maybe there should be a per-feature whitelist for guest mode as well?
--
It would be nice to see how this differs from what we do with RuntimeEnabledFeatures in Blink and if we can change this base/ API to be usable in blink. For starters it seems like this isn't very low overhead, it uses a std::map (why not a hash_map?) so you end up doing a lot of work per feature check. Blink code generates member fields so checking for a feature is an inline boolean read.Can we do code generation like we do in blink instead? That would make this faster and we could probably use the same infrastructure in blink.
-Alexei
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
It would be nice to see how this differs from what we do with RuntimeEnabledFeatures in Blink and if we can change this base/ API to be usable in blink. For starters it seems like this isn't very low overhead, it uses a std::map (why not a hash_map?) so you end up doing a lot of work per feature check. Blink code generates member fields so checking for a feature is an inline boolean read.Can we do code generation like we do in blink instead? That would make this faster and we could probably use the same infrastructure in blink.
What about flags that need to be passed to sub-processes (for example [1])? Do you plan to support this via FeatureList?
On Tue, Nov 24, 2015 at 2:27 PM, Elliott Sprehn <esp...@chromium.org> wrote:It would be nice to see how this differs from what we do with RuntimeEnabledFeatures in Blink and if we can change this base/ API to be usable in blink. For starters it seems like this isn't very low overhead, it uses a std::map (why not a hash_map?) so you end up doing a lot of work per feature check. Blink code generates member fields so checking for a feature is an inline boolean read.Can we do code generation like we do in blink instead? That would make this faster and we could probably use the same infrastructure in blink.The new API is meant to replace the use of base/command_line.h and base/metrics/field_trial.h APIs. Both of these have similar performance characteristics as the new API (i.e. both do a look up in a map and FieldTrial actually uses a lock, whereas the new API doesn't need to since overrides are set up while we're still in single process mode).So, it is not any worse (and in fact slightly better since it's a single lookup vs. possibly multiple) than the previous alternatives for chrome code.I'm skeptical that we need the complexity of code-generation. If something is really performance critical (e.g. being used in a tight loop), it's probably worth querying the API once and using a cached variable for the state.