Commit f3438b49 authored by Charlie Hu's avatar Charlie Hu Committed by Commit Bot

Add GetAvailableDocumentPolicyFeatures to feature_policy_helper.cc

This CL adds support for origin trials for document policy by adding
GetAvailableDocumentPolicyFeatures to feature_policy_helper.cc.

Potentially need to rename feature_policy_helper and
GetDefaultNameFeatureMap later.

Change-Id: I3f703c3d4f5a2c4f635b99839d06308a2c9eff6a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2008322Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarIan Clelland <iclelland@chromium.org>
Commit-Queue: Charlie Hu <chenleihu@google.com>
Cr-Commit-Position: refs/heads/master@{#737082}
parent 4613e010
......@@ -13,46 +13,48 @@ class FeaturePolicyFeatureWriter(json5_generator.Writer):
def __init__(self, json5_file_path, output_dir):
super(FeaturePolicyFeatureWriter, self).__init__(json5_file_path, output_dir)
self._outputs = {
(self.file_basename + '.cc'): self.generate_implementation,
}
self._features = self.json5_file.name_dictionaries
# Set runtime and feature policy features
self._runtime_features = []
self._feature_policy_features = []
for feature in self._features:
runtime_features = []
feature_policy_features = []
# Note: there can be feature with same 'name' attribute in document_policy_features
# and in feature_policy_features. They are supposed to have the same 'depends_on' attribute.
# However, their feature_policy_name and document_policy_name might be different.
document_policy_features = []
for feature in self.json5_file.name_dictionaries:
if feature['feature_policy_name']:
self._feature_policy_features.append(feature)
feature_policy_features.append(feature)
elif feature['document_policy_name']:
document_policy_features.append(feature)
else:
self._runtime_features.append(feature)
origin_trials_set = origin_trials(self._runtime_features)
runtime_features.append(feature)
self._origin_trial_dependency_map = defaultdict(list)
self._runtime_to_feature_policy_map = defaultdict(list)
for feature in self._feature_policy_features:
origin_trials_set = origin_trials(runtime_features)
origin_trial_dependency_map = defaultdict(list)
runtime_to_feature_policy_map = defaultdict(list)
runtime_to_document_policy_map = defaultdict(list)
for feature in feature_policy_features + document_policy_features:
for dependency in feature['depends_on']:
if str(dependency) in origin_trials_set:
self._origin_trial_dependency_map[feature['name']].append(dependency)
deps = origin_trial_dependency_map[feature['name']]
if dependency not in deps:
deps.append(dependency)
else:
self._runtime_to_feature_policy_map[dependency].append(feature['name'])
self._header_guard = self.make_header_guard(self._relative_output_dir + self.file_basename + '.h')
def _template_inputs(self):
return {
'feature_policy_features': self._feature_policy_features,
'header_guard': self._header_guard,
'input_files': self._input_files,
'runtime_features': self._runtime_features,
'runtime_to_feature_policy_map': self._runtime_to_feature_policy_map,
'origin_trial_dependency_map': self._origin_trial_dependency_map,
}
if feature['feature_policy_name']:
runtime_to_feature_policy_map[dependency].append(feature['name'])
else:
runtime_to_document_policy_map[dependency].append(feature['name'])
@template_expander.use_jinja('templates/' + file_basename + '.cc.tmpl')
def generate_implementation(self):
return self._template_inputs()
self._outputs = {
self.file_basename + '.cc': template_expander.use_jinja('templates/' + self.file_basename + '.cc.tmpl')(lambda: {
'header_guard': self.make_header_guard(self._relative_output_dir + self.file_basename + '.h'),
'input_files': self._input_files,
'feature_policy_features': feature_policy_features,
'document_policy_features': document_policy_features,
'origin_trial_dependency_map': origin_trial_dependency_map,
'runtime_to_feature_policy_map': runtime_to_feature_policy_map,
'runtime_to_document_policy_map': runtime_to_document_policy_map
}),
}
if __name__ == '__main__':
......
......@@ -37,9 +37,9 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
mojom::FeaturePolicyFeature::k{{feature.name}});
{% endif %}
{% endfor %}
{% for runtime_feature_name, FP_features in runtime_to_feature_policy_map.items() | sort %}
{% for runtime_feature_name, dependent_features in runtime_to_feature_policy_map.items() | sort %}
if (RuntimeEnabledFeatures::{{runtime_feature_name}}Enabled()) {
{% for feature in FP_features %}
{% for feature in dependent_features %}
default_feature_name_map.Set(k{{feature}}PolicyName,
mojom::FeaturePolicyFeature::k{{feature}});
{% endfor %}
......@@ -49,6 +49,25 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
return default_feature_name_map;
}
const FeatureSet& GetAvailableDocumentPolicyFeatures() {
DEFINE_STATIC_LOCAL(FeatureSet, features, ());
if (features.IsEmpty()) {
{% for feature in document_policy_features %}
{% if not feature.depends_on or feature.name in origin_trial_dependency_map %}
features.insert(mojom::FeaturePolicyFeature::k{{feature.name}});
{% endif %}
{% endfor %}
{% for runtime_feature_name, dependent_features in runtime_to_document_policy_map.items() | sort %}
if (RuntimeEnabledFeatures::{{runtime_feature_name}}Enabled()) {
{% for feature in dependent_features %}
features.insert(mojom::FeaturePolicyFeature::k{{feature}});
{% endfor %}
}
{% endfor %}
}
return features;
}
// If any of the origin trial runtime feature is enabled, returns false,
// i.e. the feature is considered enabled by origin trial.
bool DisabledByOriginTrial(const String& feature_name,
......
......@@ -861,6 +861,7 @@ blink_python_runner("make_core_generated_feature_policy_helper") {
inputs = scripts_for_json5_files + [
"../build/scripts/make_feature_policy_helper.py",
"./feature_policy/feature_policy_features.json5",
"./feature_policy/document_policy_features.json5",
"../platform/runtime_enabled_features.json5",
"../build/scripts/templates/feature_policy_helper.cc.tmpl",
]
......@@ -870,6 +871,8 @@ blink_python_runner("make_core_generated_feature_policy_helper") {
rebase_path("../platform/runtime_enabled_features.json5", root_build_dir),
rebase_path("./feature_policy/feature_policy_features.json5",
root_build_dir),
rebase_path("./feature_policy/document_policy_features.json5",
root_build_dir),
"--output_dir",
"$rel_blink_core_gen_dir/feature_policy",
]
......
{
// All document policy (https://w3c.github.io/webappsec-feature-policy/document-policy.html)
// features are defined here.
// All Features have to be defined in FeaturePolicyFeature enum as well
// (defined in third_party/blink/public/mojom/feature_policy/feature_policy.mojom).
// The enum value has to have the same name as the feature name here.
parameters: {
// document_policy_name: "FEATURE_NAME" is used to specify the policy name
// which gets parsed from the header or the allow attribute.
document_policy_name: {},
value_name: {},
// valid c++ type strings, e.g. bool, double, float.
value_type: {},
// valid c++ expression strings, e.g. true/false, 1.0, -1.
default_value: {},
// "depends_on" specifies relationship to runtime features defined
// in "runtime_enabled_features.json5":
// depends_on: ["feature1", "feature2", ...]
// * If the depends_on features are *only* runtime features, the feature is
// available if any of the runtime features are enabled.
// * If the depends_on list includes origin trial features, the feature is
// available if any of the origin trial features are enabled.
depends_on: {
default: [],
valid_type: "list",
},
},
data: [
{
name: "FontDisplay",
document_policy_name: "font-display-late-swap",
value_name: "",
value_type: "bool",
default_value: "true",
depends_on: ["ExperimentalProductivityFeatures"],
},
{
name: "UnoptimizedLosslessImages",
document_policy_name: "unoptimized-lossless-images",
value_name: "bpp",
value_type: "double",
default_value: "PolicyValue::CreateMaxPolicyValue(mojom::PolicyValueType::kDecDouble)",
depends_on: ["UnoptimizedImagePolicies"],
},
],
}
......@@ -9,11 +9,14 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
using FeatureNameMap = HashMap<String, mojom::blink::FeaturePolicyFeature>;
using FeatureSet = HashSet<mojom::blink::FeaturePolicyFeature,
IntHash<mojom::blink::FeaturePolicyFeature>>;
class FeatureContext;
......@@ -23,6 +26,12 @@ class FeatureContext;
// policy object.
const FeatureNameMap& GetDefaultFeatureNameMap();
// This method defines the feature names which will be recognized by the parser
// for the Document-Policy HTTP header and the <iframe> "policy" attribute, as
// well as the features which will be recognized by the document or iframe
// policy object.
const FeatureSet& GetAvailableDocumentPolicyFeatures();
// Returns true if this feature is currently disabled by an origin trial (it is
// origin trial controlled, and the origin trial is not enabled).
bool DisabledByOriginTrial(const String&, FeatureContext*);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment