blob: 92105de686bcfd03b7df0ac250e70a044a7e6036 [file] [log] [blame] [view]
Yashar Dabiran91ea4a872019-02-19 15:46:291# Runtime Enabled Features
2## Overview
Sina Firoozabadia2ee3d82023-04-07 18:48:563Runtime flags enable Blink to control access to new features. Features that are hidden behind a runtime flag are known as Runtime Enabled Features. It is a requirement of the Blink Launch Process to implement new web exposed features behind a runtime flag until an Intent To Ship has been approved. Additionally, all changes with non-trivial compatibility risk [should be guarded](/docs/flag_guarding_guidelines.md) by a Runtime Enabled Feature (or other base::Feature) so that they can be disabled quickly.
Yashar Dabiran91ea4a872019-02-19 15:46:294
5## Adding A Runtime Enabled Feature
Fergal Dalye56556b2022-07-07 19:48:366Runtime Enabled Features are defined in runtime_enabled_features.json5 in alphabetical order. Add your feature's flag to [runtime_enabled_features.json5] and the rest will be generated for you automatically.
Yashar Dabiran91ea4a872019-02-19 15:46:297
Vladimir Levin826ce072024-01-24 17:42:168Please add a descriptive comment, including a link to the spec or the chromestatus.com entry if either one is available. This allows readers to easily find more context about the feature.
9
Yashar Dabiran91ea4a872019-02-19 15:46:2910Example:
11```js
12{
Vladimir Levin826ce072024-01-24 17:42:1613 // Amazing new feature! https://chromestatus.com/feature/123
Yashar Dabiran91ea4a872019-02-19 15:46:2914 name: "AmazingNewFeature",
15 status: "experimental",
16}
17```
18The status of the feature controls when it will be enabled in the Blink engine.
19
Xianzhu Wangadb0670a22020-07-16 23:04:5820| Status Value | Web feature enabled during [web tests] with content_shell [1] | Web feature enabled as part of web experimental features [2] | Web feature enabled in stable release | Non-web exposed feature enabled through a command line flag [3]
Yashar Dabiran91ea4a872019-02-19 15:46:2921|:---:|:---:|:---:|:---:|:---:|
22| <missing\> | No | No | No | Yes |
23| `test` | Yes | No | No | No |
24| `experimental` | Yes | Yes | No | No |
25| `stable` | Yes | Yes | Yes | No |
26
Xianzhu Wangfeae8952020-07-16 18:07:5727\[1]: content_shell will not enable experimental/test features by default. The `--run-web-tests` flag used as part of running web tests enables this behaviour. The `--enable-blink-test-features` flag also enables this behavior in Chromium and content_shell's browser mode.
Yashar Dabiran91a8662d2019-02-19 18:56:0228
29\[2]: Navigate to about:flags in the URL bar and turn on "Enable experimental web platform features" (formerly, "Enable experimental WebKit features") **or** run Chromium with `--enable-experimental-web-platform-features` (formerly, --enable-experimental-webkit-features).
Yashar Dabiran91ea4a872019-02-19 15:46:2930Works in all Chromium channels: canary, dev, beta, and stable.
Yashar Dabiran91a8662d2019-02-19 18:56:0231
32\[3]: For features that are not web exposed features but require code in Blink to be triggered. Such feature can have a about:flags entry or be toggled based on other signals. Such entries should be called out in a comment to differentiate them from stalled entries.
Yashar Dabiran91ea4a872019-02-19 15:46:2933
34### Platform-specific Feature Status
35For features that do not have the same status on every platform, you can specify their status using a dictionary value.
36
37For example in the declaration below:
38```js
39{
40 name: "NewFeature",
41 status: {
42 "Android": "test",
43 "ChromeOS": "experimental",
44 "Win": "stable",
45 "default": "",
46 }
47}
48```
49the feature has the status `test` on Android, `experimental` on Chrome OS and `stable` on Windows and no status on the other platforms.
50The status of all the not-specified platforms is set using the `default` key. For example, the declaration:
51```js
52status: {
53 "Android": "stable",
54 "default", "experimental",
55}
56```
57will set the feature status to `experimental` on all platforms except on Android (which will be set to `stable`).
58
59**Note:** Omitting `default` from the status dictionary will be treated the same as writing `"default": ""`.
60
61**Note:** You can find the list of all supported platforms in [runtime_enabled_features.json5 status declaration][supportedPlatforms].
62
63### Guidelines for Setting Feature Status
64Any in-development feature can be added with no status, the only requirement is that code OWNERS are willing to have the code landed in the tree (as for any commit).
65
Xianzhu Wangfeae8952020-07-16 18:07:5766* For a feature to be marked `status: "test"`, it must be in a sufficient state to permit internal testing. For example, enabling it should not be known to easily cause crashes, leak memory, or otherwise significantly effect the reliability of bots. Consideration should also be given to the potential for loss of test coverage of shipping behavior. For example, if a feature causes a new code path to be taken instead of an existing one, it is possible that some valuable test coverage and regression protection could be lost by setting a feature to `status: "test"`. Especially, using `status: "test"` for features that have substantially different code paths from the shipped product is strongly discouraged. Consider using a [virtual test suite] or setting up a [flag-specific] [trybot (example)] when it's important to keep testing both old and new code paths. [LayoutNG] and [BlinkGenPropertyTrees] are examples of features where we ensured test coverage of both new and old code paths until they were fully launched, without using `status: "test"`. See the linked document/bug for how we achieved that.
Yashar Dabiran91ea4a872019-02-19 15:46:2967
Xianzhu Wangfeae8952020-07-16 18:07:5768* For a feature to be marked `status: "experimental"`, it should be far enough along to permit testing by early adopter web developers. Many chromium enthusiasts run with `--enable-experimental-web-platform-features`, and so promoting a feature to experimental status can be a good way to get early warning of any stability or compatibility problems. If such problems are discovered (e.g. major websites being seriously broken when the feature is enabled), the feature should be demoted back to no status or `status: "test"` to avoid creating undue problems for such users. It's notoriously difficult to diagnose a bug report from a user who neglects to mention that they have this flag enabled. Often a feature will be set to experimental status long before it's implementation is complete, and while there is still substantial churn on the API design. Features in this state are not expected to work completely, just do something of value which developers may want to provide feedback on.
Yashar Dabiran91ea4a872019-02-19 15:46:2969
Mason Freed02450ef2020-09-03 22:50:5870 **Note:** features set to "experimental" should **not** be expected to cause significant breakage of existing major sites. The primary use case is new APIs or features that are not expected to cause compat issues. If your feature could be reasonably expected to cause compat issues, please keep it marked no status or `status:"test"` [4], and instead use the Finch system, which is better suited to detect and disable such features in case of problems.
Mathias Bynens4fd0e952023-07-31 09:36:3371
72\[4]: In this case, "no status" is preferred to `status:"test"` unless you can ensure test coverage of the code paths with the feature disabled. See the `status:"test"` section for more details.
Mason Freed02450ef2020-09-03 22:50:5873
Xianzhu Wangfeae8952020-07-16 18:07:5774* For a feature to be marked `status: "stable"`, it must be complete and ready for use by all chrome users. Often this means it has gotten approval via the [blink launch process]. However, for features which are not web observable (e.g. a flag to track a large-scale code refactoring), this approval is not needed. In rare cases a feature may be tested on canary and dev channels by temporarily setting it to `status: "stable"`, with a comment pointing to a bug marked `Release-Block-Beta` tracking setting the feature back to `status: "experimental"` before the branch for beta.
Yashar Dabiran91ea4a872019-02-19 15:46:2975
Mathias Bynens4fd0e952023-07-31 09:36:3376When a feature has shipped and is no longer at risk of needing to be disabled, its associated RuntimeEnableFeatures entry should be removed entirely. Permanent features should generally not have flags.
Yashar Dabiran91ea4a872019-02-19 15:46:2977
Xianzhu Wangfeae8952020-07-16 18:07:5778If a feature is not stable and no longer under active development, remove `status: "test"/"experimental"` on it (and consider deleting the code implementing the feature).
Yashar Dabiran91ea4a872019-02-19 15:46:2979
Xianzhu Wang05355f4a2020-09-02 01:22:1680### Relationship between a Chromium Feature and a Blink Feature
81
Kent Tamura1aea82b2022-09-14 16:48:2982In some cases, e.g. for finch experiment, you may need to define a Chromium
83feature for a blink feature. If you need a Chromium feature just for finch
Kent Tamura0bc0a4532023-02-17 04:18:3884experiment for a blink feature, see the next section. Otherwise, you should
85specify `base_feature: "none"`, and their relationship is defined in
86[content/child/runtime_features.cc]. See the [initialize blink features] doc
87for more details.
Xianzhu Wang05355f4a2020-09-02 01:22:1688
Xianzhu Wanga4e3e1f52024-02-16 21:24:0789**Note:** `base_feature: "none"` is strongly discouraged if the feature
90doesn't have an associated base feature because the feature would lack a
91killswitch controllable via finch.
92
Xianzhu Wang05355f4a2020-09-02 01:22:1693**Note:** If a feature is implemented at both Chromium side and blink side, as the blink feature doesn't fully work by itself, we normally don't set the blink feature's status so that the Chromium feature can fully control the blink feature ([example][controlled by chromium feature]).
94
Kent Tamura1aea82b2022-09-14 16:48:2995If you need to update or check a blink feature status from outside of blink,
Xianzhu Wanga4e3e1f52024-02-16 21:24:0796with dedicated methods (instead of `WebRuntimeFeatures::EnableFeatureFromString()`),
Kent Tamura1aea82b2022-09-14 16:48:2997you can generate methods of `WebRuntimeFeatures` by adding `public: true,` to
Xianzhu Wanga4e3e1f52024-02-16 21:24:0798the feature entry in `runtime_enabled_features.json5`. This should be
99rare because `WebRuntimeFeatures::EnableFeaturesFromString()` works in
100most cases.
Kent Tamura1aea82b2022-09-14 16:48:29101
102### Generate a `base::Feature` instance from a Blink Feature
103
Kent Tamura0bc0a4532023-02-17 04:18:38104A Blink feature entry generates a corresponding `base::Feature` instance with
105the same name in `blink::features` namespace by default. It's helpful for a
106Finch experiment for the feature, including a kill switch.
Kent Tamura1aea82b2022-09-14 16:48:29107
Kent Tamura0bc0a4532023-02-17 04:18:38108Specify `base_feature: "AnotherFlagName"` if you'd like to generate a
109`base::Feature` with a different name.
Kent Tamura1aea82b2022-09-14 16:48:29110
Xianzhu Wanga4e3e1f52024-02-16 21:24:07111Specify `base_feature: "none"` to disable `base::Feature` generation
112(see the note above about in what situation `base_feature: "none"` is strongly
113discouraged).
Kent Tamura0bc0a4532023-02-17 04:18:38114
115The name specified by `base_feature` or `name` is used for the feature
Kent Tamura1aea82b2022-09-14 16:48:29116name which is referred in `--enable-features=` flag and Finch configurations.
117
118The generated `base::Feature` is enabled by default if the status of the blink
119feature is `stable`, and disabled by default otherwise. This behavior can be
120overridden by `base_feature_status` field.
121
Lingqi Chi5de54a32021-10-27 05:03:59122### Introducing dependencies among Runtime Enabled Features
123
124The parameters of `implied_by` and `depends_on` can be used to specify the relationship to other features.
125
126* "implied_by": With this field specified, this feature is enabled automatically if any of the implied_by features is enabled.
127
128* "depends_on": With this field specified, this feature is enabled only if all of the depends_on features are enabled.
129
130**Note:** Only one of `implied_by` and `depends_on` can be specified.
131
Yashar Dabiran91ea4a872019-02-19 15:46:29132### Runtime Enabled CSS Properties
133
134If your feature is adding new CSS Properties you will need to use the runtime_flag argument in [renderer/core/css/css_properties.json5][cssProperties].
135
136## Using A Runtime Enabled Feature
137
138### C++ Source Code
139Add this include:
140```cpp
141#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
142```
143This will provide following static methods to check/set whether your feature is enabled:
144```cpp
145bool RuntimeEnabledFeatures::AmazingNewFeatureEnabled();
146void RuntimeEnabledFeatures::SetAmazingNewFeatureEnabled(bool enabled);
147```
148**Note:** MethodNames and FeatureNames are in UpperCamelCase. This is handled automatically in code generators, and works even if the feature's flag name begins with an acronym such as "CSS", "IME", or "HTML".
149For example "CSSMagicFeature" becomes `RuntimeEnabledFeatures::CSSMagicFeatureEnabled()` and `RuntimeEnabledFeatures::SetCSSMagicFeatureEnabled(bool)`.
150
151
152### IDL Files
153Use the [Blink extended attribute] `[RuntimeEnabled]` as in `[RuntimeEnabled=AmazingNewFeature]` in your IDL definition.
154
155**Note:** FeatureNames are in UpperCamelCase; please use this case in IDL files.
156
157You can guard the entire interface, as in this example:
158```
159[
160 RuntimeEnabled=AmazingNewFeature // Guard the entire interface.
161] interface AmazingNewObject {
162 attribute DOMString amazingNewAttribute;
163 void amazingNewMethod();
164};
165```
166Alternatively, you can guard individual definition members:
167```
168interface ExistingObject {
169 attribute DOMString existingAttribute;
170 // Guarded attribute.
171 [RuntimeEnabled=AmazingNewFeature] attribute DOMString amazingNewAttribute;
172 // Guarded method.
173 [RuntimeEnabled=AmazingNewFeature] void amazingNewMethod();
174};
175```
176**Note:** You *cannot* guard individual arguments, as this is very confusing and error-prone. Instead, use overloading and guard the overloads.
177
178For example, instead of:
179```
180interface ExistingObject {
181 foo(long x, [RuntimeEnabled=FeatureName] optional long y); // Don't do this!
182};
183```
184do:
185```
186interface ExistingObject {
187 // Overload can be replaced with optional if [RuntimeEnabled] is removed
188 foo(long x);
189 [RuntimeEnabled=FeatureName] foo(long x, long y);
190};
191```
192
193**Warning:** You will not be able to change the enabled state of these at runtime as the V8 object templates definitions are created during start up and will not be updated during runtime.
194
195## Web Tests (JavaScript)
Xianzhu Wangadb0670a22020-07-16 23:04:58196
197In [web tests], you can test whether a feature is enabled using:
Yashar Dabiran91ea4a872019-02-19 15:46:29198```javascript
199internals.runtimeFlags.amazingNewFeatureEnabled
200```
Xianzhu Wangadb0670a22020-07-16 23:04:58201This attribute is read only and cannot be changed, unless `settable_from_internals: true` is specified for the feature.
Yashar Dabiran91ea4a872019-02-19 15:46:29202
Xianzhu Wangadb0670a22020-07-16 23:04:58203**Note:** The `internals` JavaScript API is only available in content_shell for use by web tests and does not appear in Chromium. In content_shell's browser mode, `--expose-internals-for-testing` is needed to have the `internals` JavaScript API.
Yashar Dabiran91ea4a872019-02-19 15:46:29204
Francis McCabe83913672021-03-30 18:52:12205**Note:** If your runtime feature is called `AmazingNewFeature`, the Javascript variable name is `internals.runtimeFlags.amazingNewFeatureEnabled`.
206
Yashar Dabiran91ea4a872019-02-19 15:46:29207### Running Web Tests
Xianzhu Wangadb0670a22020-07-16 23:04:58208When content_shell is run for web tests with `--stable-release-mode` flag, test-only and experimental features (ones listed in [runtime_enabled_features.json5] with `status: "test"` or `status: "experimental"`) are turned off. The [virtual/stable] suite runs with the flag, which is one of the ways to ensure test coverage of production code path for these features.
Yashar Dabiran91ea4a872019-02-19 15:46:29209
210## Generated Files
211[renderer/build/scripts/make_runtime_features.py][make_runtime_features.py] uses [runtime_enabled_features.json5] to generate:
212```
213<compilation directory>/gen/third_party/blink/renderer/platform/runtime_enabled_features.h
214<compilation directory>/gen/third_party/blink/renderer/platform/runtime_enabled_features.cc
215```
216[renderer/build/scripts/make_internal_runtime_flags.py][make_internal_runtime_flags.py] uses [runtime_enabled_features.json5] to generate:
217```
218<compilation directory>/gen/third_party/blink/renderer/core/testing/internal_runtime_flags.idl
219<compilation directory>/gen/thrid_party/blink/renderer/core/testing/internal_runtime_flags.h
220```
221[renderer/bindings/scripts/code_generator_v8.py][code_generator_v8.py] uses the generated `internal_runtime_flags.idl` to generate:
222```
223<compilation directory>/gen/third_party/blink/renderer/bindings/core/v8/v8_internal_runtime_flags.h
224<compilation directory>/gen/third_party/blink/renderer/bindings/core/v8/v8_internal_runtime_flags.cc
225```
226## Command-line Switches
227`content` provides two switches which can be used to turn runtime enabled features on or off, intended for use during development. They are exposed by both `content_shell` and `chrome`.
228```
229--enable-blink-features=SomeNewFeature,SomeOtherNewFeature
230--disable-blink-features=SomeOldFeature
231```
232After applying most other feature settings, the features requested feature settings (comma-separated) are changed. "disable" is applied later (and takes precedence), regardless of the order the switches appear on the command line. These switches only affect Blink's state. Some features may need to be switched on in Chromium as well; in this case, a specific flag is required.
233
234**Announcement**
235https://groups.google.com/a/chromium.org/d/msg/blink-dev/JBakhu5J6Qs/re2LkfEslTAJ
236
237
Eric Willigers354ee682022-01-24 10:16:55238[web tests]: <https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_tests.md>
239[supportedPlatforms]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/platform/runtime_enabled_features.json5#36>
240[cssProperties]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/core/css/css_properties.json5>
241[virtual test suite]: <https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_tests.md#testing-runtime-flags>
242[flag-specific]: <https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_tests.md#testing-runtime-flags>
Xianzhu Wangfeae8952020-07-16 18:07:57243[trybot (example)]: <https://chromium-review.googlesource.com/c/chromium/src/+/1850255>
Xianzhu Wange86080d2020-07-16 20:59:14244[LayoutNG]: <https://docs.google.com/document/d/17t6HjA5X8T5xq1LlKoLEGTn_MioGCdEPpijpJeLalK0/edit#heading=h.guvbepjyp0oj>
Xianzhu Wangfeae8952020-07-16 18:07:57245[BlinkGenPropertyTrees]: <https://crbug.com/836884>
Yashar Dabiran91ea4a872019-02-19 15:46:29246[blink launch process]: <https://www.chromium.org/blink/launching-features>
Eric Willigers354ee682022-01-24 10:16:55247[Blink extended attribute]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/bindings/IDLExtendedAttributes.md>
248[make_runtime_features.py]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/build/scripts/make_runtime_features.py>
249[runtime_enabled_features.json5]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/platform/runtime_enabled_features.json5>
250[make_internal_runtime_flags.py]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/build/scripts/make_internal_runtime_flags.py>
251[code_generator_v8.py]: <https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/bindings/scripts/code_generator_v8.py>
252[virtual/stable]: <https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/VirtualTestSuites;drc=9878f26d52d32871ed1c085444196e5453909eec;l=112>
sisidovskib343b362022-12-12 16:53:58253[content/child/runtime_features.cc]: <https://source.chromium.org/chromium/chromium/src/+/main:content/child/runtime_features.cc>
Eric Willigers354ee682022-01-24 10:16:55254[initialize blink features]: <https://chromium.googlesource.com/chromium/src/+/main/docs/initialize_blink_features.md>
Rick Byerse64b12a2023-03-24 19:06:38255[controlled by chromium feature]: <https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5;drc=70bddadf50a14254072cf7ca0bcf83e4331a7d4f;l=833>