This document outlines all the runtime configuration surfaces of Chromium, and discusses appropriate uses and standard patterns for each of them. Some of these are intended for use by users, some by developers, and some by system administrators.
Example: prefs::kAllowDinosaurEasterEgg aka “allow_dinosaur_easter_egg”
Prefs are implemented by registering them with a central pref service, usually via Profile::RegisterProfilePrefs. They store typed values, which persist across restarts and may be synced between browser instances via the Sync service. There are several pref stores, which are documented in detail in the prefs docs. They can be directly configured via enterprise policy.
These are implemented via creating a base::Feature anywhere. These can be enabled via server-side experimentation or via the command-line using “--enable-features”. Which features are in use is tracked by UMA metrics, and is visible in chrome://version as the “Variations” field. Do note that in release builds, only a series of hashes show up in chrome://version rather than the string names of the variations, but these hashes can be turned back into string names if needed. This is done by consulting the testing config for Chromium builds, or a Google-internal tool for Chrome builds.
Features are the best way to add runtime conditional behavior.
Example: switches::kIncognito aka “--incognito”
These are implemented by testing anywhere in the codebase for the presence or value of a switch in base::CommandLine::ForCurrentProcess. There is no centralized registry of switches and they can be used for essentially any purpose.
In general, switches are inferior to use of base::Feature, which has the same capabilities and low engineering overhead but ties into UMA reporting. New code should use base::Feature instead of switches. An exception to this is when the configuration value is a string, since features can't take an arbitrary string value.
These are implemented by adding an entry in about_flags.cc describing the flag, as well as metadata in flag-metadata. Flags have a name and description, and show up in chrome://flags. Flags also have an expiration milestone, after which they will be hidden from that UI and disabled, then later removed. Flags are backed by either a feature or a set of switches, which they enable at browser startup depending on the value of the flag.
Flags should usually be temporary, to allow for pre-launch testing of a feature. Permanent flags (those with expiration -1) should only be used when either:
“Users might need to turn the feature on/off” is not a sufficient justification for a permanent flag. If at all possible, we should design features such that users don't want or need to turn them off, but if we need to retain that choice, we should promote it to a full setting (see below) with translations and support. “Developers/QA might need to turn the feature on/off”, on the other hand, is justification for a permanent flag.
Example: “Show home button”
Settings are implemented in WebUI, and show up in chrome://settings or one of its subpages. They generally are bound to a pref which stores the value of that setting. These are comparatively expensive to add, since they require localization and some amount of UX involvement to figure out how to fit them into chrome://settings, plus documentation and support material. Many settings are implemented via prefs, but not all prefs correspond to settings; some are used for tracking internal browser state across restarts.
You should add a setting if end-users might want to change this behavior. A decent litmus test for whether something should be a flag or a setting is: “will someone who can't read or write code want to change this?”