blob: 028d12a605b5f1be83f2bad0e30df1664e1ddf37 [file] [log] [blame] [view]
chasejc74a4c9c2017-02-10 20:38:091# Integrating a feature with the Origin Trials framework
2
3To expose your feature via the origin trials framework, there are a few code
4changes required.
5
6[TOC]
7
8## Code Changes
9
10### Runtime Enabled Features
11
Kent Tamurab10f7eda2017-09-15 06:45:2012First, youll need to configure [runtime\_enabled\_features.json5]. This is
chasejc74a4c9c2017-02-10 20:38:0913explained in the file, but you use `origin_trial_feature_name` to associate your
14runtime feature flag with a name for your origin trial. The name can be the
15same as your runtime feature flag, or different. Eventually, this configured
16name will be used in the Origin Trials developer console (still under
17development). You can have both `status: experimental` and
18`origin_trial_feature_name` if you want your feature to be enabled either by
19using the `--enable-experimental-web-platform-features` flag **or** the origin
20trial.
21
22You may have a feature that is not available on all platforms, or need to limit
23the trial to specific platforms. Use `origin_trial_os: [list]` to specify which
24platforms will allow the trial to be enabled. The list values are case-
25insensitive, but must match one of the defined `OS_<platform>` macros (see
26[build_config.h]).
27
28#### Examples
29
30Flag name and trial name are the same:
31```
32{
33 name: "MyFeature",
34 origin_trial_feature_name: "MyFeature",
35 status: "experimental",
36},
37```
38Flag name and trial name are different:
39```
40{
41 name: "MyFeature",
42 origin_trial_feature_name: "MyFeatureTrial",
43 status: "experimental",
44},
45```
46Trial limited to specific platform:
47``` json
48{
49 name: "MyFeature",
50 origin_trial_feature_name: "MyFeature",
51 origin_trial_os: ["android"],
52 status: "experimental",
53},
54```
55
56### Gating Access
57
58Once configured, there are two mechanisms to gate access to your feature behind
59an origin trial. You can use either mechanism, or both, as appropriate to your
60feature implementation.
61
621. A native C++ method that you can call in Blink code at runtime to expose your
63 feature: `bool OriginTrials::myFeatureEnabled()`
642. An IDL attribute \[[OriginTrialEnabled]\] that you can use to automatically
Ian Clellanda94fcfb2017-07-20 03:43:4865 generate code to expose and hide JavaScript methods/attributes/objects. This
66 attribute works very similarly to \[RuntimeEnabled\].
chasejc74a4c9c2017-02-10 20:38:0967```
68[OriginTrialEnabled=MyFeature]
69partial interface Navigator {
70 readonly attribute MyFeatureManager myFeature;
71}
72```
73
Ruslan Burakov53cefa72019-05-09 08:22:2574### Web Feature Counting
75
76Once the feature is created, in order to run the origin trial you need to track
77how often users use your feature. You can do it in two ways.
78
79#### Increment counter in your c++ code.
80
811. Add your feature counter to end of [web\_feature.mojom]:
82
83```
84enum WebFeature {
85 // ...
86 kLastFeatureBeforeYours = 1235,
87 // Here, increment the last feature count before yours by 1.
88 kMyFeature = 1236,
89
90 kNumberOfFeatures, // This enum value must be last.
91};
92```
932. Run [update\_use\_counter\_feature\_enum.py] to update the UMA mapping.
94
953. Increment your feature counter in c++ code.
96```c++
97#include "third_party/blink/renderer/core/frame/use_counter.h"
98
99// ...
100
101 if (OriginTrials::myFeatureEnabled()) {
102 UseCounter::Count(context, WebFeature::kMyFeature);
103 }
104```
105
106#### Update counter with \[Measure\] IDL attribute
107
1081. Add \[[Measure]\] IDL attribute
109```
110partial interface Navigator {
111 [OriginTrialEnabled=MyFeature, Measure]
112 readonly attribute MyFeatureManager myFeature;
113```
114
1152. The code to increment your feature counter will be generated in V8
116 automatically. But it requires you to follow \[[Measure]\] IDL attribute
117 naming convention when you will add your feature counter to
118 [web\_feature.mojom].
119```
120enum WebFeature {
121 // ...
122 kLastFeatureBeforeYours = 1235,
123 // Here, increment the last feature count before yours by 1.
124 kV8Navigator_MyFeature_AttributeGetter = 1236,
125
126 kNumberOfFeatures, // This enum value must be last.
127};
128```
129
130
chasejc74a4c9c2017-02-10 20:38:09131**NOTE:** Your feature implementation must not persist the result of the enabled
132check. Your code should simply call `OriginTrials::myFeatureEnabled()` as often
133as necessary to gate access to your feature.
134
chasejc74a4c9c2017-02-10 20:38:09135## Limitations
136
137What you can't do, because of the nature of these Origin Trials, is know at
138either browser or renderer startup time whether your feature is going to be used
139in the current page/context. This means that if you require lots of expensive
140processing to begin (say you index the user's hard drive, or scan an entire city
141for interesting weather patterns,) that you will have to either do it on browser
142startup for *all* users, just in case it's used, or do it on first access. (If
143you go with first access, then only people trying the experiment will notice the
144delay, and hopefully only the first time they use it.). We are investigating
145providing a method like `OriginTrials::myFeatureShouldInitialize()` that will
146hint if you should do startup initialization. For example, this could include
147checks for trials that have been revoked (or throttled) due to usage, if the
148entire origin trials framework has been disabled, etc. The method would be
149conservative and assume initialization is required, but it could avoid expensive
150startup in some known scenarios.
151
152Similarly, if you need to know in the browser process whether a feature should
153be enabled, then you will have to either have the renderer inform it at runtime,
154or else just assume that it's always enabled, and gate access to the feature
155from the renderer.
156
157## Testing
158
Steve Kobes6d752cb2019-01-16 01:37:46159To test an origin trial feature during development, follow these steps:
chasejc74a4c9c2017-02-10 20:38:09160
Steve Kobes6d752cb2019-01-16 01:37:461611. Use [generate_token.py] to generate a token signed with the test private key.
162 You can generate signed tokens for any origin that you need to help you test,
163 including localhost or 127.0.0.1. Example:
chasejc74a4c9c2017-02-10 20:38:09164
Steve Kobes6d752cb2019-01-16 01:37:46165 ```
166 tools/origin_trials/generate_token.py http://localhost:8000 MyFeature
167 ```
chasejc74a4c9c2017-02-10 20:38:09168
Steve Kobes6d752cb2019-01-16 01:37:461692. Copy the token from the end of the output and use it in a `<meta>` tag or
170 an `Origin-Trial` header as described in the [Developer Guide].
chasejc74a4c9c2017-02-10 20:38:09171
Steve Kobes6d752cb2019-01-16 01:37:461723. Run Chrome with the test public key by passing:
173 `--origin-trial-public-key=dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA=`
174
175The `--origin-trial-public-key` switch is not needed with `content_shell`, as it
176uses the test public key by default.
177
178The test private key is stored in the repo at `tools/origin_trials/eftest.key`.
179It's also used by Origin Trials unit tests and web tests.
180
181If you cannot set command-line switches (e.g., on Chrome OS), you can also
182directly modify [chrome_origin_trial_policy.cc].
chasejc74a4c9c2017-02-10 20:38:09183
Kent Tamura59ffb022018-11-27 05:30:56184### Web Tests
185When using the \[OriginTrialEnabled\] IDL attribute, you should add web tests
Ian Clellanda94fcfb2017-07-20 03:43:48186to verify that the V8 bindings code is working as expected. Depending on how
chasej0ac7dd22017-02-23 18:16:17187your feature is exposed, you'll want tests for the exposed interfaces, as well
188as tests for script-added tokens. For examples, refer to the existing tests in
189[origin_trials/webexposed].
190
chasejc74a4c9c2017-02-10 20:38:09191[build_config.h]: /build/build_config.h
192[chrome_origin_trial_policy.cc]: /chrome/common/origin_trials/chrome_origin_trial_policy.cc
chasejc74a4c9c2017-02-10 20:38:09193[generate_token.py]: /tools/origin_trials/generate_token.py
194[Developer Guide]: https://github.com/jpchase/OriginTrials/blob/gh-pages/developer-guide.md
Kent Tamura6943cf792018-04-09 05:24:54195[OriginTrialEnabled]: /third_party/blink/renderer/bindings/IDLExtendedAttributes.md#_OriginTrialEnabled_i_m_a_c_
Kent Tamura59ffb022018-11-27 05:30:56196[origin_trials/webexposed]: /third_party/blink/web_tests/http/tests/origin_trials/webexposed/
Kent Tamura6943cf792018-04-09 05:24:54197[runtime\_enabled\_features.json5]: /third_party/blink/renderer/platform/runtime_enabled_features.json5
Lucas Furukawa Gadani6c24cdae2018-04-27 00:28:40198[trial_token_unittest.cc]: /third_party/blink/common/origin_trials/trial_token_unittest.cc
Ruslan Burakov53cefa72019-05-09 08:22:25199[web\_feature.mojom]: /third_party/blink/public/mojom/web_feature/web_feature.mojom
200[update\_use\_counter\_feature\_enum.py]: /tools/metrics/histograms/update_use_counter_feature_enum.py
201[Measure]: /third_party/blink/renderer/bindings/IDLExtendedAttributes.md#Measure_i_m_a_c