Integrating a feature with the Origin Trials framework

To expose your feature via the Origin Trials framework, there are a few code changes required.

WARNING: This is only available for features implemented in Blink.

Code Changes

NOTE: You can land these code changes before requesting to run an origin trial. These code changes make it possible to control a feature via an origin trial, but don't require an origin trial to be approved. For more on the process, see Running an Origin Trial.

Step 1: Add Runtime Enabled Feature in Blink for Origin Trial

First, you’ll need to configure runtime_enabled_features.json5. If you don‘t have a Blink’s Runtime Enabled Feature flag yet, you will need to add an entry in this file.

The following fields of an entry are relevant:

  • name: The name of your runtime enabled feature, e.g. "MyFeature".
  • origin_trial_feature_name: The name of your runtime enabled feature in the origin trial. This can be the same as your runtime feature flag (i.e. name field), or different. Eventually, this configured name will be used in the origin trials developer console.
  • origin_trial_os: Specifies a [list] of platforms where they will allow the trial to be enabled. The list values are case-insensitive, but must match one of the defined OS_<platform> macros (see build_config.h).
  • origin_trial_allows_third_party: Must be enabled to allow third-party tokens to work correctly. Set to true, if (and only if) you intend to support third-party matching.
  • base_feature: Generates a base::Feature in the blink::features namespace if the value is not "none". It helps to control the Origin Trial remotely. See also Generate a base::Feature instance from a Blink Feature.

Not specific to Origin Trial:

  • status: Controls when the runtime enabled feature is enabled in Blink. See also the Status table.
  • base_feature_status: Controls when the base::Feature defined by base_feature is enabled.

More details are explained in the json5 file and in the above linked doc.

If the runtime enabled feature flag is used in C++, you will have to change all callers of the no-argument overload of RuntimeEnabledFeatures::MyFeatureEnabled() to the overload that takes a const FeatureContext*. You can pass an ExecutionContext here, e.g. using ExecutionContext::From(ScriptState*).

Examples

RuntimeEnabledFeature flag name, trial name and base::Feature are all the same:

{
  name: "MyFeature",  // Generates `RuntimeEnabledFeatures::MyFeatureEnabled()`
  origin_trial_feature_name: "MyFeature",
  status: "experimental",
  // No need to specify base_feature.
},

RuntimeEnabledFeature flag name, trial name, and base::Feature name are different:

{
  name: "MyFeature",
  origin_trial_feature_name: "MyFeatureTrial",
  base_feature: "MyBaseFeature",  // Generates blink::features::kMyBaseFeature
  status: "experimental",
},

Trial limited to specific platform:

{
  name: "MyFeature",
  origin_trial_feature_name: "MyFeature",
  origin_trial_os: ["android"],
  status: "experimental",
},

WebView considerations

Because WebView is built as part of the "android" os target, it is not possible to exclude a trial from WebView if it is enabled on Android.

If the feature under trial can be enabled on WebView alongside other Android platforms, this is preferred.

In situations where this is not feasible, the recommended solution is to explicitly disable the origin trial in AwMainDelegate::BasicStartupComplete() in aw_main_delegate.cc by appending the embedder_support::kOriginTrialDisabledFeatures switch with the disabled trial names as values.

See https://crrev.com/c/3733267 for an example of how this can be done.

Step 2: Gating Access

Once configured, there are two mechanisms to gate access to your feature behind an origin trial. You can use either mechanism, or both, as appropriate to your feature implementation.

1) In C++

A native C++ method that you can call in Blink code at runtime to expose your feature:

bool RuntimeEnabledFeatures::MyFeatureEnabled(ExecutionContext*)
WARNING: Your feature implementation must not persist the result of the enabled check. Your code should simply call RuntimeEnabledFeatures::MyFeatureEnabled(ExecutionContext*) as often as necessary to gate access to your feature.