Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 1 | # Integrating a feature with the Origin Trials framework |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 2 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 3 | To expose your feature via the [Origin Trials framework], there are a few code |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 4 | changes required. |
| 5 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 6 | *** note |
| 7 | **WARNING:** This is only available for features implemented in Blink. |
| 8 | *** |
| 9 | |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 10 | [TOC] |
| 11 | |
| 12 | ## Code Changes |
| 13 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 14 | *** promo |
| 15 | **NOTE:** You can land these code changes before requesting to run an origin |
| 16 | trial. |
Jason Chase | dbd8b973 | 2020-11-26 17:18:43 | [diff] [blame] | 17 | These code changes make it possible to control a feature via an origin trial, |
| 18 | but don't require an origin trial to be approved. For more on the process, see |
| 19 | [Running an Origin Trial]. |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 20 | *** |
Jason Chase | dbd8b973 | 2020-11-26 17:18:43 | [diff] [blame] | 21 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 22 | ### Step 1: Add Runtime Enabled Feature in Blink for Origin Trial |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 23 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 24 | First, you’ll need to configure [runtime\_enabled\_features.json5]. If you don't |
| 25 | have a Blink's [Runtime Enabled Feature] flag yet, you will need to add an entry |
| 26 | in this file. |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 27 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 28 | The following fields of an entry are relevant: |
Christian Biesinger | 0651e825 | 2022-01-25 17:18:08 | [diff] [blame] | 29 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 30 | - `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 |
| 37 | of the defined `OS_<platform>` macros (see [build_config.h]). |
| 38 | - `base_feature`: Generates a `base::Feature` in the `blink::features` |
Kent Tamura | 0bc0a453 | 2023-02-17 04:18:38 | [diff] [blame] | 39 | namespace if the value is not `"none"`. It helps to control the Origin Trial |
| 40 | remotely. See also [Generate a `base::Feature` instance from a Blink Feature] |
| 41 | [from blink]. |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 42 | |
| 43 | Not specific to Origin Trial: |
| 44 | |
| 45 | - `status`: Controls when the runtime enabled feature is enabled in Blink. See |
| 46 | also [the Status table]. |
| 47 | - `base_feature_status`: Controls when the `base::Feature` defined by |
| 48 | `base_feature` is enabled. |
| 49 | |
| 50 | More details are explained in the json5 file and in the above linked doc. |
| 51 | |
| 52 | If the runtime enabled feature flag is [used in C++](#1-in-c), you will have to |
| 53 | change all callers of the no-argument overload of |
| 54 | `RuntimeEnabledFeatures::MyFeatureEnabled()` to the overload that takes a |
| 55 | `const FeatureContext*`. You can pass an `ExecutionContext` here, e.g. using |
| 56 | `ExecutionContext::From(ScriptState*)`. |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 57 | |
| 58 | #### Examples |
| 59 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 60 | RuntimeEnabledFeature flag name, trial name and `base::Feature` are all the |
| 61 | same: |
| 62 | |
| 63 | ```json |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 64 | { |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 65 | name: "MyFeature", // Generates `RuntimeEnabledFeatures::MyFeatureEnabled()` |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 66 | origin_trial_feature_name: "MyFeature", |
| 67 | status: "experimental", |
Kent Tamura | 0bc0a453 | 2023-02-17 04:18:38 | [diff] [blame] | 68 | // No need to specify base_feature. |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 69 | }, |
| 70 | ``` |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 71 | |
Kent Tamura | 0bc0a453 | 2023-02-17 04:18:38 | [diff] [blame] | 72 | RuntimeEnabledFeature flag name, trial name, and `base::Feature` name are |
| 73 | different: |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 74 | |
| 75 | ```json |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 76 | { |
| 77 | name: "MyFeature", |
| 78 | origin_trial_feature_name: "MyFeatureTrial", |
Kent Tamura | 0bc0a453 | 2023-02-17 04:18:38 | [diff] [blame] | 79 | base_feature: "MyBaseFeature", // Generates blink::features::kMyBaseFeature |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 80 | status: "experimental", |
| 81 | }, |
| 82 | ``` |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 83 | |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 84 | Trial limited to specific platform: |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 85 | |
| 86 | ```json |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 87 | { |
| 88 | name: "MyFeature", |
| 89 | origin_trial_feature_name: "MyFeature", |
| 90 | origin_trial_os: ["android"], |
| 91 | status: "experimental", |
| 92 | }, |
| 93 | ``` |
| 94 | |
Peter Birk Pakkenberg | f6ca525 | 2022-09-05 08:54:05 | [diff] [blame] | 95 | #### WebView considerations |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 96 | |
| 97 | Because WebView is built as part of the `"android"` os target, it is not |
| 98 | possible to exclude a trial from WebView if it is enabled on Android. |
Peter Birk Pakkenberg | f6ca525 | 2022-09-05 08:54:05 | [diff] [blame] | 99 | |
| 100 | If the feature under trial can be enabled on WebView alongside other Android |
| 101 | platforms, this is preferred. |
| 102 | |
| 103 | In situations where this is not feasible, the recommended solution is to |
| 104 | explicitly disable the origin trial in |
| 105 | `AwMainDelegate::BasicStartupComplete()` in [aw\_main\_delegate.cc] by |
| 106 | appending the `embedder_support::kOriginTrialDisabledFeatures` switch with the |
| 107 | disabled trial names as values. |
| 108 | |
| 109 | See http://crrev.com/c/3733267 for an example of how this can be done. |
| 110 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 111 | ### Step 2: Gating Access |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 112 | |
| 113 | Once configured, there are two mechanisms to gate access to your feature behind |
| 114 | an origin trial. You can use either mechanism, or both, as appropriate to your |
| 115 | feature implementation. |
| 116 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 117 | #### 1) In C++ |
| 118 | |
| 119 | A native C++ method that you can call in Blink code at runtime to expose your |
| 120 | feature: |
| 121 | |
| 122 | ```cpp |
| 123 | bool RuntimeEnabledFeatures::MyFeatureEnabled(ExecutionContext*) |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 124 | ``` |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 125 | |
| 126 | *** note |
| 127 | **WARNING:** Your feature implementation must not persist the result of the |
| 128 | enabled check. Your code should simply call |
| 129 | `RuntimeEnabledFeatures::MyFeatureEnabled(ExecutionContext*)` as often as |
| 130 | necessary to gate access to your feature. |
| 131 | *** |
| 132 | |
| 133 | #### 2-1) In Web IDL |
| 134 | |
| 135 | An IDL attribute \[[RuntimeEnabled]\] that you can use to automatically generate |
| 136 | code to expose and hide JavaScript methods/attributes/objects. |
| 137 | |
| 138 | ```cpp |
Allen Robinson | b0efcfa | 2019-06-25 13:24:04 | [diff] [blame] | 139 | [RuntimeEnabled=MyFeature] |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 140 | partial interface Navigator { |
| 141 | readonly attribute MyFeatureManager myFeature; |
| 142 | } |
| 143 | ``` |
| 144 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 145 | #### 2-2) CSS Properties |
Allen Robinson | b0efcfa | 2019-06-25 13:24:04 | [diff] [blame] | 146 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 147 | *** promo |
| 148 | **NOTE:** For CSS properties, you do not need to edit the IDL files, as the |
| 149 | exposure on the [CSSStyleDeclaration] is handled at runtime. |
| 150 | *** |
Rodney Ding | 533e41a | 2020-01-15 20:17:18 | [diff] [blame] | 151 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 152 | You can also run experiment for new CSS properties with origin trial. After you |
| 153 | have configured your feature in [runtime\_enabled\_features.json5] as above, |
| 154 | head to [css\_properties.json5]. As explained in the file, you use |
| 155 | `runtime_flag` to associate the CSS property with the feature you just defined. |
| 156 | This will automatically link the CSS property to the origin trial defined in the |
| 157 | runtime feature. It will be available in both JavaScript (`Element.style`) and |
| 158 | CSS (including `@supports`) when the trial is enabled. |
Rodney Ding | 533e41a | 2020-01-15 20:17:18 | [diff] [blame] | 159 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 160 | *** promo |
| 161 | **EXAMPLE:** [origin-trial-test-property] defines a test css property controlled |
| 162 | via runtime feature `OriginTrialsSampleAPI` and subsequently an origin trial |
| 163 | named `Frobulate`. |
| 164 | *** |
| 165 | |
| 166 | *** note |
| 167 | **ISSUE:** In the rare cases where the origin trial token is added via script |
| 168 | after the css style declaration, the css property will be enabled and is fully |
| 169 | functional, however it will not appear on the [CSSStyleDeclaration] interface, |
| 170 | i.e. not accessible in `Element.style`. This issue is tracked in crbug/1041993. |
| 171 | *** |
| 172 | |
| 173 | ### Step 3: Mapping Runtime Enabled Feature to `base::Feature` (optional) |
| 174 | |
| 175 | Given the following example: |
| 176 | |
| 177 | ```json |
| 178 | { |
| 179 | name: "MyFeature", |
| 180 | origin_trial_feature_name: "MyFeature", |
| 181 | base_feature: "MyFeature", |
| 182 | status: "experimental", |
| 183 | }, |
| 184 | ``` |
| 185 | |
| 186 | ```cpp |
| 187 | [RuntimeEnabled=MyFeature] |
| 188 | interface MyFeatureAPI { |
| 189 | readonly attribute bool dummy; |
| 190 | } |
| 191 | ``` |
| 192 | |
| 193 | ```cpp |
| 194 | // third_party/blink/.../my_feature_api.cc |
| 195 | bool MyFeatureAPI::ConnectToBrowser() { |
| 196 | if (base::FeatureList::IsEnabled(blink::features::kMyFeature) { |
| 197 | // Do something |
| 198 | } |
| 199 | return false; |
| 200 | } |
| 201 | ``` |
| 202 | |
| 203 | The above example shows a new feature relies on a `base::Feature` generated from |
| 204 | the `base_feature` definition in json file, e.g. `blink::features::kMyFeature`, |
| 205 | in addition to the runtime enabled feature flag `MyFeature`. |
| 206 | However, their values are not associated. |
| 207 | |
| 208 | In addition, due to the [limitation](#limitations), the runtime enabled feature |
| 209 | flag is not available in the browser process **by default**: |
| 210 | |
| 211 | > if you need to know in the browser process whether a feature should |
| 212 | > be enabled, then you will have to either have the renderer inform it at |
| 213 | > runtime, or else just assume that it's always enabled, and gate access to the |
| 214 | > feature from the renderer. |
| 215 | |
| 216 | *** note |
| 217 | **TLDR:** Turning on `MyFeature` doesn't automatically turning on |
| 218 | `blink::features::kMyFeature`, and vice versa. |
| 219 | *** |
| 220 | |
| 221 | To mitigate the issue, there are several options: |
| 222 | |
| 223 | #### Option 1: Fully Enabling `base::Feature`, e.g. `kMyFeature` |
| 224 | |
| 225 | And letting Origin Trial decides when your feature (via runtime enabled feature |
| 226 | flag `blink::features::MyFeature`) is available, as suggested in the above |
| 227 | quote. The `base::Feature` can be enabled via a remote Finch config, or by |
| 228 | updating the default value in C++. |
| 229 | |
| 230 | However, after the Origin Trial ends, it will be impossible to ramp up the |
| 231 | feature by Finch if the part controlled by `MyFeature` cannot be enabled |
| 232 | independently. For example, if you have a new Web API `MyFeatureAPI`, enabling |
| 233 | `MyFeature` will just make the IDL available to everyone without the |
| 234 | Blink/browser implementation. |
| 235 | |
| 236 | *** note |
| 237 | **Example Bug:** https://crbug.com/1360678. |
| 238 | *** |
| 239 | |
| 240 | #### Option 2: Setting Up a Custom Mapping |
| 241 | |
| 242 | 1. Make `MyFeature` depend on `blink::features::kMyFeature` so that the feature |
| 243 | is not enabled if `features::kMyFeatures` is not enabled. In |
| 244 | [third_party/blink/renderer/core/origin_trials/origin_trial_context.cc](../third_party/blink/renderer/core/origin_trials/origin_trial_context.cc): |
| 245 | |
| 246 | ```cpp |
| 247 | bool OriginTrialContext::CanEnableTrialFromName(const StringView& trial_name) { |
| 248 | ... |
| 249 | if (trial_name == "MyFeature") { |
| 250 | return base::FeatureList::IsEnabled(blink::features::kMyFeatures); |
| 251 | } |
| 252 | } |
| 253 | ``` |
| 254 | |
| 255 | 2. Add custom relationship for `MyFeature` and `blink::features::kMyFeature` to |
| 256 | handle your use case. |
| 257 | |
| 258 | Read |
| 259 | [**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) |
| 260 | first. If the mappings described there don't meet your use case, refer to |
| 261 | the following examples. |
| 262 | |
| 263 | In [content/child/runtime_features.cc](https://source.chromium.org/chromium/chromium/src/+/main:content/child/runtime_features.cc): |
| 264 | |
| 265 | ```cpp |
| 266 | void SetCustomizedRuntimeFeaturesFromCombinedArgs( |
| 267 | const base::CommandLine& command_line) { |
| 268 | // Example 1: https://bit.ly/configuring-trust-tokens |
| 269 | // Example 2: https://crrev.com/c/3878922/14/content/child/runtime_features.cc |
| 270 | } |
| 271 | ``` |
| 272 | |
| 273 | ### Step 4: Web Feature Counting |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 274 | |
| 275 | Once the feature is created, in order to run the origin trial you need to track |
| 276 | how often users use your feature. You can do it in two ways. |
| 277 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 278 | #### Increment counter in your c++ code |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 279 | |
| 280 | 1. Add your feature counter to end of [web\_feature.mojom]: |
| 281 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 282 | ```cpp |
| 283 | enum WebFeature { |
| 284 | // ... |
| 285 | kLastFeatureBeforeYours = 1235, |
| 286 | // Here, increment the last feature count before yours by 1. |
| 287 | kMyFeature = 1236, |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 288 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 289 | kNumberOfFeatures, // This enum value must be last. |
| 290 | }; |
| 291 | ``` |
| 292 | |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 293 | 2. Run [update\_use\_counter\_feature\_enum.py] to update the UMA mapping. |
| 294 | |
| 295 | 3. Increment your feature counter in c++ code. |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 296 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 297 | ```c++ |
| 298 | #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 299 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 300 | // ... |
| 301 | |
| 302 | if (RuntimeEnabledFeatures::MyFeatureEnabled(context)) { |
| 303 | UseCounter::Count(context, WebFeature::kMyFeature); |
| 304 | } |
| 305 | ``` |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 306 | |
| 307 | #### Update counter with \[Measure\] IDL attribute |
| 308 | |
| 309 | 1. Add \[[Measure]\] IDL attribute |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 310 | |
| 311 | ```cpp |
| 312 | partial interface Navigator { |
| 313 | [RuntimeEnabled=MyFeature, Measure] |
| 314 | readonly attribute MyFeatureManager myFeature; |
| 315 | ``` |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 316 | |
| 317 | 2. The code to increment your feature counter will be generated in V8 |
| 318 | automatically. But it requires you to follow \[[Measure]\] IDL attribute |
| 319 | naming convention when you will add your feature counter to |
| 320 | [web\_feature.mojom]. |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 321 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 322 | ```cpp |
| 323 | enum WebFeature { |
| 324 | // ... |
| 325 | kLastFeatureBeforeYours = 1235, |
| 326 | // Here, increment the last feature count before yours by 1. |
| 327 | kV8Navigator_MyFeature_AttributeGetter = 1236, |
| 328 | |
| 329 | kNumberOfFeatures, // This enum value must be last. |
| 330 | }; |
| 331 | ``` |
| 332 | |
| 333 | ### Step 5: Add Web Tests |
| 334 | |
| 335 | When using the \[[RuntimeEnabled]\] IDL attribute, you should add web tests |
| 336 | to verify that the V8 bindings code is working as expected. Depending on how |
| 337 | your feature is exposed, you'll want tests for the exposed interfaces, as well |
| 338 | as tests for script-added tokens. For examples, refer to the existing tests in |
| 339 | [origin_trials/webexposed]. |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 340 | |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 341 | ## Limitations |
| 342 | |
Allen Robinson | b0efcfa | 2019-06-25 13:24:04 | [diff] [blame] | 343 | What you can't do, because of the nature of these origin trials, is know at |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 344 | either browser or renderer startup time whether your feature is going to be used |
| 345 | in the current page/context. This means that if you require lots of expensive |
| 346 | processing to begin (say you index the user's hard drive, or scan an entire city |
| 347 | for interesting weather patterns,) that you will have to either do it on browser |
| 348 | startup for *all* users, just in case it's used, or do it on first access. (If |
| 349 | you go with first access, then only people trying the experiment will notice the |
| 350 | delay, and hopefully only the first time they use it.). We are investigating |
| 351 | providing a method like `OriginTrials::myFeatureShouldInitialize()` that will |
| 352 | hint if you should do startup initialization. For example, this could include |
| 353 | checks for trials that have been revoked (or throttled) due to usage, if the |
| 354 | entire origin trials framework has been disabled, etc. The method would be |
| 355 | conservative and assume initialization is required, but it could avoid expensive |
| 356 | startup in some known scenarios. |
| 357 | |
| 358 | Similarly, if you need to know in the browser process whether a feature should |
| 359 | be enabled, then you will have to either have the renderer inform it at runtime, |
| 360 | or else just assume that it's always enabled, and gate access to the feature |
| 361 | from the renderer. |
| 362 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 363 | ## Manual Testing |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 364 | |
Steve Kobes | 6d752cb | 2019-01-16 01:37:46 | [diff] [blame] | 365 | To test an origin trial feature during development, follow these steps: |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 366 | |
Steve Kobes | 6d752cb | 2019-01-16 01:37:46 | [diff] [blame] | 367 | 1. Use [generate_token.py] to generate a token signed with the test private key. |
| 368 | You can generate signed tokens for any origin that you need to help you test, |
| 369 | including localhost or 127.0.0.1. Example: |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 370 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 371 | ```bash |
| 372 | tools/origin_trials/generate_token.py http://localhost:8000 MyFeature |
| 373 | ``` |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 374 | |
Jason Chase | dbd8b973 | 2020-11-26 17:18:43 | [diff] [blame] | 375 | There are additional flags to generate third-party tokens, set the expiry |
| 376 | date, and control other options. See the command help for details (`--help`). |
| 377 | For example, to generate a third-party token, with [user subset exclusion]: |
| 378 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 379 | ```bash |
| 380 | tools/origin_trials/generate_token.py --is-third-party --usage-restriction=subset http://localhost:8000 MyFeature |
| 381 | ``` |
Jason Chase | dbd8b973 | 2020-11-26 17:18:43 | [diff] [blame] | 382 | |
Steve Kobes | 6d752cb | 2019-01-16 01:37:46 | [diff] [blame] | 383 | 2. Copy the token from the end of the output and use it in a `<meta>` tag or |
| 384 | an `Origin-Trial` header as described in the [Developer Guide]. |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 385 | |
Steve Kobes | 6d752cb | 2019-01-16 01:37:46 | [diff] [blame] | 386 | 3. Run Chrome with the test public key by passing: |
| 387 | `--origin-trial-public-key=dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA=` |
| 388 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 389 | You can also run Chrome with both the test public key and the default public key |
| 390 | along side by passing: |
Andrii Sagaidak | dbc6a77 | 2019-12-12 03:43:39 | [diff] [blame] | 391 | `--origin-trial-public-key=dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA=,fMS4mpO6buLQ/QMd+zJmxzty/VQ6B1EUZqoCU04zoRU=` |
| 392 | |
Steve Kobes | 6d752cb | 2019-01-16 01:37:46 | [diff] [blame] | 393 | The `--origin-trial-public-key` switch is not needed with `content_shell`, as it |
| 394 | uses the test public key by default. |
| 395 | |
| 396 | The test private key is stored in the repo at `tools/origin_trials/eftest.key`. |
| 397 | It's also used by Origin Trials unit tests and web tests. |
| 398 | |
| 399 | If you cannot set command-line switches (e.g., on Chrome OS), you can also |
| 400 | directly modify [chrome_origin_trial_policy.cc]. |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 401 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 402 | To see additional information about origin trial token parsing (including |
| 403 | reasons for failures, or token names for successful tokens), you can add these |
| 404 | switches: |
Mason Freed | 9ee18c76 | 2020-08-18 20:57:21 | [diff] [blame] | 405 | |
| 406 | `--vmodule=trial_token=2,origin_trial_context=1` |
| 407 | |
| 408 | If you are building with `is_debug=false`, then you will also need to add |
| 409 | `dcheck_always_on=true` to your build options, and add this to the command line: |
| 410 | |
| 411 | `--enable-logging=stderr` |
| 412 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 413 | ## Related Documents |
Mason Freed | 9ee18c76 | 2020-08-18 20:57:21 | [diff] [blame] | 414 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 415 | - [Chromium Feature API & Finch (Googler-only)](http://go/finch-feature-api) |
| 416 | - [Configuration: Prefs, Settings, Features, Switches & Flags](configuration.md) |
| 417 | - [Runtime Enabled Features](../third_party/blink/renderer/platform/RuntimeEnabledFeatures.md) |
| 418 | - [Initialization of Blink runtime features in content layer](initialize_blink_features.md) |
chasej | 0ac7dd2 | 2017-02-23 18:16:17 | [diff] [blame] | 419 | |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 420 | [Origin Trials framework]: http://googlechrome.github.io/OriginTrials/developer-guide.html |
| 421 | [Runtime Enabled Features]: ../third_party/blink/renderer/platform/RuntimeEnabledFeatures.md |
| 422 | [from blink]: ../third_party/blink/renderer/platform/RuntimeEnabledFeatures.md#generate-a-instance-from-a-blink-feature |
| 423 | [the Status table]: ../third_party/blink/renderer/platform/RuntimeEnabledFeatures.md#adding-a-runtime-enabled-feature |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 424 | [build_config.h]: /build/build_config.h |
| 425 | [chrome_origin_trial_policy.cc]: /chrome/common/origin_trials/chrome_origin_trial_policy.cc |
chasej | c74a4c9c | 2017-02-10 20:38:09 | [diff] [blame] | 426 | [generate_token.py]: /tools/origin_trials/generate_token.py |
| 427 | [Developer Guide]: https://github.com/jpchase/OriginTrials/blob/gh-pages/developer-guide.md |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 428 | [RuntimeEnabled]: ../third_party/blink/renderer/bindings/IDLExtendedAttributes.md#RuntimeEnabled_i_m_a_c |
| 429 | [origin_trials/webexposed]: ../third_party/blink/web_tests/http/tests/origin_trials/webexposed/ |
| 430 | [runtime\_enabled\_features.json5]: ../third_party/blink/renderer/platform/runtime_enabled_features.json5 |
| 431 | [trial_token_unittest.cc]: ../third_party/blink/common/origin_trials/trial_token_unittest.cc |
| 432 | [web\_feature.mojom]: ../third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom |
Ruslan Burakov | 53cefa7 | 2019-05-09 08:22:25 | [diff] [blame] | 433 | [update\_use\_counter\_feature\_enum.py]: /tools/metrics/histograms/update_use_counter_feature_enum.py |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 434 | [Measure]: ../third_party/blink/renderer/bindings/IDLExtendedAttributes.md#Measure_i_m_a_c |
| 435 | [css\_properties.json5]: ../third_party/blink/renderer/core/css/css_properties.json5 |
Rodney Ding | 533e41a | 2020-01-15 20:17:18 | [diff] [blame] | 436 | [origin-trial-test-property]: https://chromium.googlesource.com/chromium/src/+/ff2ab8b89745602c8300322c2a0158e210178c7e/third_party/blink/renderer/core/css/css_properties.json5#2635 |
Ming-Ying Chung | c23505d6 | 2022-09-22 10:07:33 | [diff] [blame] | 437 | [CSSStyleDeclaration]: ../third_party/blink/renderer/core/css/css_style_declaration.idl |
Jason Chase | dbd8b973 | 2020-11-26 17:18:43 | [diff] [blame] | 438 | [Running an Origin Trial]: https://www.chromium.org/blink/origin-trials/running-an-origin-trial |
| 439 | [user subset exclusion]: https://docs.google.com/document/d/1xALH9W7rWmX0FpjudhDeS2TNTEOXuPn4Tlc9VmuPdHA/edit#heading=h.myaz1twlipw |