blob: cd570233986001c6fbd03f95238ef1089427236a [file] [log] [blame] [view]
Ming-Ying Chungc23505d62022-09-22 10:07:331# Integrating a feature with the Origin Trials framework
chasejc74a4c9c2017-02-10 20:38:092
Ming-Ying Chungc23505d62022-09-22 10:07:333To expose your feature via the [Origin Trials framework], there are a few code
chasejc74a4c9c2017-02-10 20:38:094changes required.
5
Ming-Ying Chungc23505d62022-09-22 10:07:336*** note
7**WARNING:** This is only available for features implemented in Blink.
8***
9
chasejc74a4c9c2017-02-10 20:38:0910[TOC]
11
12## Code Changes
13
Ming-Ying Chungc23505d62022-09-22 10:07:3314*** promo
15**NOTE:** You can land these code changes before requesting to run an origin
16trial.
Jason Chasedbd8b9732020-11-26 17:18:4317These code changes make it possible to control a feature via an origin trial,
18but don't require an origin trial to be approved. For more on the process, see
19[Running an Origin Trial].
Ming-Ying Chungc23505d62022-09-22 10:07:3320***
Jason Chasedbd8b9732020-11-26 17:18:4321
Ming-Ying Chungc23505d62022-09-22 10:07:3322### Step 1: Add Runtime Enabled Feature in Blink for Origin Trial
chasejc74a4c9c2017-02-10 20:38:0923
Nate Fischer151aa1e2023-08-17 15:36:3324First, you’ll need to configure [`runtime_enabled_features.json5`]. If you don't
Ming-Ying Chungc23505d62022-09-22 10:07:3325have a Blink's [Runtime Enabled Feature] flag yet, you will need to add an entry
26in this file.
chasejc74a4c9c2017-02-10 20:38:0927
Ming-Ying Chungc23505d62022-09-22 10:07:3328The following fields of an entry are relevant:
Christian Biesinger0651e8252022-01-25 17:18:0829
Ming-Ying Chungc23505d62022-09-22 10:07:3330- `name`: The name of your runtime enabled feature, e.g. `"MyFeature"`.
31- `origin_trial_feature_name`: The name of your runtime enabled feature in the
32 origin trial. This can be the same as your runtime feature flag (i.e. `name`
33 field), or different. Eventually, this configured name will be used in the
34 origin trials developer console.
35- `origin_trial_os`: Specifies a `[list]` of platforms where they will allow the
36 trial to be enabled. The list values are case-insensitive, but must match one
Nate Fischer151aa1e2023-08-17 15:36:3337 of the defined `OS_<platform>` macros (see [`build_config.h`]).
Panos Astithasf9ce05662023-11-14 02:20:4138- `origin_trial_allows_third_party`: Must be enabled to allow third-party tokens
39 to work correctly. Set to true, if (and only if) you intend to support
40 third-party matching.
Ming-Ying Chungc23505d62022-09-22 10:07:3341- `base_feature`: Generates a `base::Feature` in the `blink::features`
Kent Tamura0bc0a4532023-02-17 04:18:3842 namespace if the value is not `"none"`. It helps to control the Origin Trial
Nate Fischer151aa1e2023-08-17 15:36:3343 remotely. See also [Generate a `base::Feature` instance from a Blink Feature].
Ming-Ying Chungc23505d62022-09-22 10:07:3344
45Not specific to Origin Trial:
46
47- `status`: Controls when the runtime enabled feature is enabled in Blink. See
48 also [the Status table].
49- `base_feature_status`: Controls when the `base::Feature` defined by
50 `base_feature` is enabled.
51
52More details are explained in the json5 file and in the above linked doc.
53
Evelynn Kaplan72b8f1b2025-03-27 15:50:0654If the runtime enabled feature flag is [used in C++](#1_in-c), you will have to
Ming-Ying Chungc23505d62022-09-22 10:07:3355change all callers of the no-argument overload of
56`RuntimeEnabledFeatures::MyFeatureEnabled()` to the overload that takes a
57`const FeatureContext*`. You can pass an `ExecutionContext` here, e.g. using
58`ExecutionContext::From(ScriptState*)`.
chasejc74a4c9c2017-02-10 20:38:0959
60#### Examples
61
Ming-Ying Chungc23505d62022-09-22 10:07:3362RuntimeEnabledFeature flag name, trial name and `base::Feature` are all the
63same:
64
65```json
chasejc74a4c9c2017-02-10 20:38:0966{
Ming-Ying Chungc23505d62022-09-22 10:07:3367 name: "MyFeature", // Generates `RuntimeEnabledFeatures::MyFeatureEnabled()`
chasejc74a4c9c2017-02-10 20:38:0968 origin_trial_feature_name: "MyFeature",
69 status: "experimental",
Kent Tamura0bc0a4532023-02-17 04:18:3870 // No need to specify base_feature.
chasejc74a4c9c2017-02-10 20:38:0971},
72```
Ming-Ying Chungc23505d62022-09-22 10:07:3373
Kent Tamura0bc0a4532023-02-17 04:18:3874RuntimeEnabledFeature flag name, trial name, and `base::Feature` name are
75different:
Ming-Ying Chungc23505d62022-09-22 10:07:3376
77```json
chasejc74a4c9c2017-02-10 20:38:0978{
79 name: "MyFeature",
80 origin_trial_feature_name: "MyFeatureTrial",
Kent Tamura0bc0a4532023-02-17 04:18:3881 base_feature: "MyBaseFeature", // Generates blink::features::kMyBaseFeature
chasejc74a4c9c2017-02-10 20:38:0982 status: "experimental",
83},
84```
Ming-Ying Chungc23505d62022-09-22 10:07:3385
chasejc74a4c9c2017-02-10 20:38:0986Trial limited to specific platform:
Ming-Ying Chungc23505d62022-09-22 10:07:3387
88```json
chasejc74a4c9c2017-02-10 20:38:0989{
90 name: "MyFeature",
91 origin_trial_feature_name: "MyFeature",
92 origin_trial_os: ["android"],
93 status: "experimental",
94},
95```
96
Peter Birk Pakkenbergf6ca5252022-09-05 08:54:0597#### WebView considerations
Ming-Ying Chungc23505d62022-09-22 10:07:3398
99Because WebView is built as part of the `"android"` os target, it is not
100possible to exclude a trial from WebView if it is enabled on Android.
Peter Birk Pakkenbergf6ca5252022-09-05 08:54:05101
102If the feature under trial can be enabled on WebView alongside other Android
103platforms, this is preferred.
104
105In situations where this is not feasible, the recommended solution is to
106explicitly disable the origin trial in
Nate Fischer151aa1e2023-08-17 15:36:33107`AwMainDelegate::BasicStartupComplete()` in [`aw_main_delegate.cc`] by
Peter Birk Pakkenbergf6ca5252022-09-05 08:54:05108appending the `embedder_support::kOriginTrialDisabledFeatures` switch with the
109disabled trial names as values.
110
Nate Fischer151aa1e2023-08-17 15:36:33111See https://crrev.com/c/3733267 for an example of how this can be done.
Peter Birk Pakkenbergf6ca5252022-09-05 08:54:05112
Ming-Ying Chungc23505d62022-09-22 10:07:33113### Step 2: Gating Access
chasejc74a4c9c2017-02-10 20:38:09114
115Once configured, there are two mechanisms to gate access to your feature behind
116an origin trial. You can use either mechanism, or both, as appropriate to your
117feature implementation.
118
Ming-Ying Chungc23505d62022-09-22 10:07:33119#### 1) In C++
120
121A native C++ method that you can call in Blink code at runtime to expose your
122feature:
123
124```cpp
125bool RuntimeEnabledFeatures::MyFeatureEnabled(ExecutionContext*)
chasejc74a4c9c2017-02-10 20:38:09126```
Ming-Ying Chungc23505d62022-09-22 10:07:33127
128*** note
129**WARNING:** Your feature implementation must not persist the result of the
130enabled check. Your code should simply call
131`RuntimeEnabledFeatures::MyFeatureEnabled(ExecutionContext*)` as often as
132necessary to gate access to your feature.
133***
134
135#### 2-1) In Web IDL
136
137An IDL attribute \[[RuntimeEnabled]\] that you can use to automatically generate
138code to expose and hide JavaScript methods/attributes/objects.
139
140```cpp
Allen Robinsonb0efcfa2019-06-25 13:24:04141[RuntimeEnabled=MyFeature]
chasejc74a4c9c2017-02-10 20:38:09142partial interface Navigator {
143 readonly attribute MyFeatureManager myFeature;
144}
145```
146
Ming-Ying Chungc23505d62022-09-22 10:07:33147#### 2-2) CSS Properties
Allen Robinsonb0efcfa2019-06-25 13:24:04148
Ming-Ying Chungc23505d62022-09-22 10:07:33149*** promo
150**NOTE:** For CSS properties, you do not need to edit the IDL files, as the
151exposure on the [CSSStyleDeclaration] is handled at runtime.
152***
Rodney Ding533e41a2020-01-15 20:17:18153
Ming-Ying Chungc23505d62022-09-22 10:07:33154You can also run experiment for new CSS properties with origin trial. After you
Nate Fischer151aa1e2023-08-17 15:36:33155have configured your feature in [`runtime_enabled_features.json5`] as above,
156head to [`css_properties.json5`]. As explained in the file, you use
Ming-Ying Chungc23505d62022-09-22 10:07:33157`runtime_flag` to associate the CSS property with the feature you just defined.
158This will automatically link the CSS property to the origin trial defined in the
159runtime feature. It will be available in both JavaScript (`Element.style`) and
160CSS (including `@supports`) when the trial is enabled.
Rodney Ding533e41a2020-01-15 20:17:18161
Ming-Ying Chungc23505d62022-09-22 10:07:33162*** promo
163**EXAMPLE:** [origin-trial-test-property] defines a test css property controlled
164via runtime feature `OriginTrialsSampleAPI` and subsequently an origin trial
165named `Frobulate`.
166***
167
168*** note
169**ISSUE:** In the rare cases where the origin trial token is added via script
170after the css style declaration, the css property will be enabled and is fully
171functional, however it will not appear on the [CSSStyleDeclaration] interface,
172i.e. not accessible in `Element.style`. This issue is tracked in crbug/1041993.
173***
174
175### Step 3: Mapping Runtime Enabled Feature to `base::Feature` (optional)
176
177Given the following example:
178
179```json
180{
181 name: "MyFeature",
182 origin_trial_feature_name: "MyFeature",
183 base_feature: "MyFeature",
184 status: "experimental",
185},
186```
187
188```cpp
189[RuntimeEnabled=MyFeature]
190interface MyFeatureAPI {
191 readonly attribute bool dummy;
192}
193```
194
195```cpp
196// third_party/blink/.../my_feature_api.cc
197bool MyFeatureAPI::ConnectToBrowser() {
198 if (base::FeatureList::IsEnabled(blink::features::kMyFeature) {
199 // Do something
200 }
201 return false;
202}
203```
204
205The above example shows a new feature relies on a `base::Feature` generated from
206the `base_feature` definition in json file, e.g. `blink::features::kMyFeature`,
207in addition to the runtime enabled feature flag `MyFeature`.
208However, their values are not associated.
209
210In addition, due to the [limitation](#limitations), the runtime enabled feature
211flag is not available in the browser process **by default**:
212
213> if you need to know in the browser process whether a feature should
214> be enabled, then you will have to either have the renderer inform it at
215> runtime, or else just assume that it's always enabled, and gate access to the
216> feature from the renderer.
217
218*** note
219**TLDR:** Turning on `MyFeature` doesn't automatically turning on
220`blink::features::kMyFeature`, and vice versa.
221***
222
223To mitigate the issue, there are several options:
224
225#### Option 1: Fully Enabling `base::Feature`, e.g. `kMyFeature`
226
Johnny Stenbackfc32f1c02024-08-03 00:15:46227And letting Origin Trial decide when your feature (via runtime enabled feature
Ming-Ying Chungc23505d62022-09-22 10:07:33228flag `blink::features::MyFeature`) is available, as suggested in the above
229quote. The `base::Feature` can be enabled via a remote Finch config, or by
230updating the default value in C++.
231
232However, after the Origin Trial ends, it will be impossible to ramp up the
233feature by Finch if the part controlled by `MyFeature` cannot be enabled
234independently. For example, if you have a new Web API `MyFeatureAPI`, enabling
235`MyFeature` will just make the IDL available to everyone without the
236Blink/browser implementation.
237
238*** note
239**Example Bug:** https://crbug.com/1360678.
240***
241
242#### Option 2: Setting Up a Custom Mapping
243
2441. Make `MyFeature` depend on `blink::features::kMyFeature` so that the feature
245 is not enabled if `features::kMyFeatures` is not enabled. In
Nate Fischer151aa1e2023-08-17 15:36:33246 [third_party/blink/renderer/core/origin_trials/origin_trial_context.cc](/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc):
Ming-Ying Chungc23505d62022-09-22 10:07:33247
248 ```cpp
249 bool OriginTrialContext::CanEnableTrialFromName(const StringView& trial_name) {
250 ...
251 if (trial_name == "MyFeature") {
252 return base::FeatureList::IsEnabled(blink::features::kMyFeatures);
253 }
254 }
255 ```
256
2572. Add custom relationship for `MyFeature` and `blink::features::kMyFeature` to
258 handle your use case.
259
260 Read
261 [**Determine how your feature is initialized: Depends on the status of a base::Feature**](initialize_blink_features.md#step-2_determine-how-your-feature-is-initialized)
262 first. If the mappings described there don't meet your use case, refer to
263 the following examples.
264
265 In [content/child/runtime_features.cc](https://source.chromium.org/chromium/chromium/src/+/main:content/child/runtime_features.cc):
266
267 ```cpp
268 void SetCustomizedRuntimeFeaturesFromCombinedArgs(
269 const base::CommandLine& command_line) {
270 // Example 1: https://bit.ly/configuring-trust-tokens
271 // Example 2: https://crrev.com/c/3878922/14/content/child/runtime_features.cc
272 }
273 ```
274
275### Step 4: Web Feature Counting
Ruslan Burakov53cefa72019-05-09 08:22:25276
277Once the feature is created, in order to run the origin trial you need to track
278how often users use your feature. You can do it in two ways.
279
Nate Fischer151aa1e2023-08-17 15:36:33280#### Increment counter in your C++ code
Ruslan Burakov53cefa72019-05-09 08:22:25281
Johnny Stenbackfc32f1c02024-08-03 00:15:462821. Add your feature counter to the end of [`webdx_feature.mojom`] (or
283 [`web_feature.mojom`] if it's a feature that's somehow not expected to be
284 described in the [web platform dx
285 repository](https://github.com/web-platform-dx/web-features/))"
Ruslan Burakov53cefa72019-05-09 08:22:25286
Ming-Ying Chungc23505d62022-09-22 10:07:33287 ```cpp
Johnny Stenbackfc32f1c02024-08-03 00:15:46288 enum WebDXFeature {
Ming-Ying Chungc23505d62022-09-22 10:07:33289 // ...
290 kLastFeatureBeforeYours = 1235,
291 // Here, increment the last feature count before yours by 1.
292 kMyFeature = 1236,
Ruslan Burakov53cefa72019-05-09 08:22:25293
Ming-Ying Chungc23505d62022-09-22 10:07:33294 kNumberOfFeatures, // This enum value must be last.
295 };
296 ```
297
Johnny Stenbackfc32f1c02024-08-03 00:15:462982. Run [`update_use_counter_feature_enum.py`] to update the UMA mappings.
Ruslan Burakov53cefa72019-05-09 08:22:25299
Nate Fischer151aa1e2023-08-17 15:36:333003. Increment your feature counter in C++ code.
Ruslan Burakov53cefa72019-05-09 08:22:25301
Nate Fischer151aa1e2023-08-17 15:36:33302 ```cpp
Ming-Ying Chungc23505d62022-09-22 10:07:33303 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
Ruslan Burakov53cefa72019-05-09 08:22:25304
Ming-Ying Chungc23505d62022-09-22 10:07:33305 // ...
306
307 if (RuntimeEnabledFeatures::MyFeatureEnabled(context)) {
308 UseCounter::Count(context, WebFeature::kMyFeature);
309 }
310 ```
Ruslan Burakov53cefa72019-05-09 08:22:25311
Johnny Stenbackfc32f1c02024-08-03 00:15:46312#### Update counter with \[MeasureAs\] IDL attribute
Ruslan Burakov53cefa72019-05-09 08:22:25313
Johnny Stenbackfc32f1c02024-08-03 00:15:463141. Add \[[MeasureAs="WebDXFeature::kMyFeature"]\] IDL attribute
Ming-Ying Chungc23505d62022-09-22 10:07:33315
316 ```cpp
317 partial interface Navigator {
Johnny Stenbackfc32f1c02024-08-03 00:15:46318 [RuntimeEnabled=MyFeature, MeasureAs="WebDXFeature::kMyFeature"]
Ming-Ying Chungc23505d62022-09-22 10:07:33319 readonly attribute MyFeatureManager myFeature;
320 ```
Ruslan Burakov53cefa72019-05-09 08:22:25321
Johnny Stenbackfc32f1c02024-08-03 00:15:46322 Alternatively, if your feature counter doesn't fit as a WebDXFeature use
323 counter, make it a WebFeature instead and drop the WebDXFeature:: prefix (and
324 quotes) in the \[[MeasureAs]\] attribute above, or use \[[Measure]\] instead
325 and follow the \[[Measure]\] IDL attribute naming convention.
326
3272. Add your use counter to [`webdx_feature.mojom`] (or alternatively to
328 [`web_feature.mojom`]). The code to increment your feature counter will be
329 generated in the V8 bindings code automatically.
Ruslan Burakov53cefa72019-05-09 08:22:25330
Ming-Ying Chungc23505d62022-09-22 10:07:33331 ```cpp
Johnny Stenbackfc32f1c02024-08-03 00:15:46332 enum WebDXFeature {
Ming-Ying Chungc23505d62022-09-22 10:07:33333 // ...
334 kLastFeatureBeforeYours = 1235,
335 // Here, increment the last feature count before yours by 1.
Johnny Stenbackfc32f1c02024-08-03 00:15:46336 kMyFeature = 1236,
Ming-Ying Chungc23505d62022-09-22 10:07:33337
338 kNumberOfFeatures, // This enum value must be last.
339 };
340 ```
341
342### Step 5: Add Web Tests
343
344When using the \[[RuntimeEnabled]\] IDL attribute, you should add web tests
345to verify that the V8 bindings code is working as expected. Depending on how
346your feature is exposed, you'll want tests for the exposed interfaces, as well
347as tests for script-added tokens. For examples, refer to the existing tests in
348[origin_trials/webexposed].
Ruslan Burakov53cefa72019-05-09 08:22:25349
chasejc74a4c9c2017-02-10 20:38:09350## Limitations
351
Allen Robinsonb0efcfa2019-06-25 13:24:04352What you can't do, because of the nature of these origin trials, is know at
chasejc74a4c9c2017-02-10 20:38:09353either browser or renderer startup time whether your feature is going to be used
354in the current page/context. This means that if you require lots of expensive
355processing to begin (say you index the user's hard drive, or scan an entire city
356for interesting weather patterns,) that you will have to either do it on browser
357startup for *all* users, just in case it's used, or do it on first access. (If
358you go with first access, then only people trying the experiment will notice the
359delay, and hopefully only the first time they use it.). We are investigating
360providing a method like `OriginTrials::myFeatureShouldInitialize()` that will
361hint if you should do startup initialization. For example, this could include
362checks for trials that have been revoked (or throttled) due to usage, if the
363entire origin trials framework has been disabled, etc. The method would be
364conservative and assume initialization is required, but it could avoid expensive
365startup in some known scenarios.
366
367Similarly, if you need to know in the browser process whether a feature should
368be enabled, then you will have to either have the renderer inform it at runtime,
369or else just assume that it's always enabled, and gate access to the feature
370from the renderer.
371
Ming-Ying Chungc23505d62022-09-22 10:07:33372## Manual Testing
chasejc74a4c9c2017-02-10 20:38:09373
Steve Kobes6d752cb2019-01-16 01:37:46374To test an origin trial feature during development, follow these steps:
chasejc74a4c9c2017-02-10 20:38:09375
Nate Fischer151aa1e2023-08-17 15:36:333761. Use [`generate_token.py`] to generate a token signed with the test private key.
Steve Kobes6d752cb2019-01-16 01:37:46377 You can generate signed tokens for any origin that you need to help you test,
378 including localhost or 127.0.0.1. Example:
chasejc74a4c9c2017-02-10 20:38:09379
Ming-Ying Chungc23505d62022-09-22 10:07:33380 ```bash
381 tools/origin_trials/generate_token.py http://localhost:8000 MyFeature
382 ```
chasejc74a4c9c2017-02-10 20:38:09383
Jason Chasedbd8b9732020-11-26 17:18:43384 There are additional flags to generate third-party tokens, set the expiry
385 date, and control other options. See the command help for details (`--help`).
386 For example, to generate a third-party token, with [user subset exclusion]:
387
Ming-Ying Chungc23505d62022-09-22 10:07:33388 ```bash
389 tools/origin_trials/generate_token.py --is-third-party --usage-restriction=subset http://localhost:8000 MyFeature
390 ```
Jason Chasedbd8b9732020-11-26 17:18:43391
Steve Kobes6d752cb2019-01-16 01:37:463922. Copy the token from the end of the output and use it in a `<meta>` tag or
393 an `Origin-Trial` header as described in the [Developer Guide].
chasejc74a4c9c2017-02-10 20:38:09394
Steve Kobes6d752cb2019-01-16 01:37:463953. Run Chrome with the test public key by passing:
396 `--origin-trial-public-key=dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA=`
397
Ming-Ying Chungc23505d62022-09-22 10:07:33398You can also run Chrome with both the test public key and the default public key
399along side by passing:
Andrii Sagaidakdbc6a772019-12-12 03:43:39400`--origin-trial-public-key=dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA=,fMS4mpO6buLQ/QMd+zJmxzty/VQ6B1EUZqoCU04zoRU=`
401
Nate Fischerb3b80ef2023-08-17 15:59:24402*** promo
403**TIP:** See
404[this doc](https://www.chromium.org/developers/how-tos/run-chromium-with-flags/)
405to apply commandline switches for Chrome for Android and
406[this doc](/android_webview/docs/commandline-flags.md) to apply commandline
407switches for Android WebView.
408***
409
Steve Kobes6d752cb2019-01-16 01:37:46410The `--origin-trial-public-key` switch is not needed with `content_shell`, as it
411uses the test public key by default.
412
413The test private key is stored in the repo at `tools/origin_trials/eftest.key`.
414It's also used by Origin Trials unit tests and web tests.
415
416If you cannot set command-line switches (e.g., on Chrome OS), you can also
Nate Fischer151aa1e2023-08-17 15:36:33417directly modify [`chrome_origin_trial_policy.cc`].
chasejc74a4c9c2017-02-10 20:38:09418
Ming-Ying Chungc23505d62022-09-22 10:07:33419To see additional information about origin trial token parsing (including
420reasons for failures, or token names for successful tokens), you can add these
421switches:
Mason Freed9ee18c762020-08-18 20:57:21422
423 `--vmodule=trial_token=2,origin_trial_context=1`
424
425If you are building with `is_debug=false`, then you will also need to add
426`dcheck_always_on=true` to your build options, and add this to the command line:
427
428 `--enable-logging=stderr`
429
Ming-Ying Chungc23505d62022-09-22 10:07:33430## Related Documents
Mason Freed9ee18c762020-08-18 20:57:21431
Ming-Ying Chungc23505d62022-09-22 10:07:33432- [Chromium Feature API & Finch (Googler-only)](http://go/finch-feature-api)
433- [Configuration: Prefs, Settings, Features, Switches & Flags](configuration.md)
Nate Fischer151aa1e2023-08-17 15:36:33434- [Runtime Enabled Features]
Ming-Ying Chungc23505d62022-09-22 10:07:33435- [Initialization of Blink runtime features in content layer](initialize_blink_features.md)
chasej0ac7dd22017-02-23 18:16:17436
Nate Fischer151aa1e2023-08-17 15:36:33437[Origin Trials framework]: https://googlechrome.github.io/OriginTrials/developer-guide.html
438[Runtime Enabled Feature]: /third_party/blink/renderer/platform/RuntimeEnabledFeatures.md
439[Runtime Enabled Features]: /third_party/blink/renderer/platform/RuntimeEnabledFeatures.md
440[Generate a `base::Feature` instance from a Blink Feature]: /third_party/blink/renderer/platform/RuntimeEnabledFeatures.md#generate-a-instance-from-a-blink-feature
441[the Status table]: /third_party/blink/renderer/platform/RuntimeEnabledFeatures.md#adding-a-runtime-enabled-feature
442[`build_config.h`]: /build/build_config.h
443[`chrome_origin_trial_policy.cc`]: /chrome/common/origin_trials/chrome_origin_trial_policy.cc
444[`generate_token.py`]: /tools/origin_trials/generate_token.py
chasejc74a4c9c2017-02-10 20:38:09445[Developer Guide]: https://github.com/jpchase/OriginTrials/blob/gh-pages/developer-guide.md
Nate Fischer151aa1e2023-08-17 15:36:33446[RuntimeEnabled]: /third_party/blink/renderer/bindings/IDLExtendedAttributes.md#RuntimeEnabled
447[origin_trials/webexposed]: /third_party/blink/web_tests/http/tests/origin_trials/webexposed/
448[`runtime_enabled_features.json5`]: /third_party/blink/renderer/platform/runtime_enabled_features.json5
Johnny Stenbackfc32f1c02024-08-03 00:15:46449[`webdx_feature.mojom`]: /third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom
Nate Fischer151aa1e2023-08-17 15:36:33450[`web_feature.mojom`]: /third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
451[`update_use_counter_feature_enum.py`]: /tools/metrics/histograms/update_use_counter_feature_enum.py
452[Measure]: /third_party/blink/renderer/bindings/IDLExtendedAttributes.md#Measure
453[`css_properties.json5`]: /third_party/blink/renderer/core/css/css_properties.json5
Rodney Ding533e41a2020-01-15 20:17:18454[origin-trial-test-property]: https://chromium.googlesource.com/chromium/src/+/ff2ab8b89745602c8300322c2a0158e210178c7e/third_party/blink/renderer/core/css/css_properties.json5#2635
Nate Fischer151aa1e2023-08-17 15:36:33455[CSSStyleDeclaration]: /third_party/blink/renderer/core/css/css_style_declaration.idl
Jason Chasedbd8b9732020-11-26 17:18:43456[Running an Origin Trial]: https://www.chromium.org/blink/origin-trials/running-an-origin-trial
457[user subset exclusion]: https://docs.google.com/document/d/1xALH9W7rWmX0FpjudhDeS2TNTEOXuPn4Tlc9VmuPdHA/edit#heading=h.myaz1twlipw
Nate Fischer151aa1e2023-08-17 15:36:33458[`aw_main_delegate.cc`]: /android_webview/lib/aw_main_delegate.cc