chromium/third_party/blink/renderer/build/scripts/templates/policy_helper.cc.tmpl

{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %}
{{license()}}

{{source_files_for_generated_file(template_file, input_files)}}

#include "third_party/blink/renderer/core/permissions_policy/policy_helper.h"

#include "third_party/blink/public/mojom/permissions_policy/document_policy_feature.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/protocol/page.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"

namespace blink {
namespace {

{% for feature in permissions_policy_features %}
const char k{{feature.name}}PolicyName[] = "{{feature.permissions_policy_name}}";
{% endfor %}

}  // namespace

// Features which depend on a flag also have the same flag controlling whether
// they are in this map. Features which are shipping as part of an origin trial
// add their feature names to this map unconditionally, as the trial token could
// be added after the HTTP header needs to be parsed. This also means that
// top-level documents which simply want to embed another page which uses an
// origin trial feature, without using the feature themselves, can use
// permissions policy to allow use of the feature in subframes (The framed
// document will still require a valid origin trial token to use the feature in
// this scenario).
const FeatureNameMap GetDefaultFeatureNameMap(bool is_isolated_context) {
  DEFINE_STATIC_LOCAL(FeatureNameMapCache, default_feature_name_map_cache, ());
  FeatureNameMapCacheKey key(is_isolated_context);
  if (default_feature_name_map_cache.Contains(key) &&
      !default_feature_name_map_cache.at(key).empty()) {
    return default_feature_name_map_cache.at(key);
  }

  FeatureNameMap default_feature_name_map;
  {% for feature in permissions_policy_features %}
  {% if not feature.depends_on or feature.name in pp_origin_trial_dependency_map %}
  {% if feature.visibility == "All" %}
  default_feature_name_map.Set(
      k{{feature.name}}PolicyName,
      mojom::PermissionsPolicyFeature::k{{feature.name}});
  {% elif feature.visibility == "IsolatedContext" %}
  if (is_isolated_context) {
    default_feature_name_map.Set(
        k{{feature.name}}PolicyName,
        mojom::PermissionsPolicyFeature::k{{feature.name}});
  }
  {% endif %}
  {% endif %}
  {% endfor %}
  {% for runtime_feature_name, dependent_features in runtime_to_permissions_policy_map.items() | sort %}
  if (RuntimeEnabledFeatures::{{runtime_feature_name}}Enabled()) {
    {% for feature in dependent_features %}
    {% if name_to_permissions_policy_map[feature].visibility == "All" %}
    default_feature_name_map.Set(k{{feature}}PolicyName,
                                 mojom::PermissionsPolicyFeature::k{{feature}});
    {% elif name_to_permissions_policy_map[feature].visibility == "IsolatedContext" %}
    if (is_isolated_context) {
      default_feature_name_map.Set(
          k{{feature}}PolicyName,
          mojom::PermissionsPolicyFeature::k{{feature}});
    }
    {% endif %}
    {% endfor %}
  }
  {% endfor %}

  // Before we set |key| in the hash to be the map, check that it's empty.
  if (default_feature_name_map_cache.Contains(key)) {
    CHECK(default_feature_name_map_cache.at(key).empty());
  }

  // The contents of |default_feature_name_map| are copied into
  // |default_feature_name_map_cache| here, which is declared static
  // local above.
  default_feature_name_map_cache.Set(key, default_feature_name_map);

  return default_feature_name_map;
}


DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeaturesInternal() {
  DEFINE_STATIC_LOCAL(DocumentPolicyFeatureSet, features, ());
  return features;
}


void ResetAvailableDocumentPolicyFeaturesForTest() {
  GetAvailableDocumentPolicyFeaturesInternal().clear();
}


const DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeatures() {
  DocumentPolicyFeatureSet& features = GetAvailableDocumentPolicyFeaturesInternal();
  if (features.empty()) {
    {% for feature in document_policy_features %}
    {% if not feature.depends_on or feature.name in dp_origin_trial_dependency_map %}
    features.insert(mojom::DocumentPolicyFeature::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::DocumentPolicyFeature::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,
                           FeatureContext* feature_context) {
  {% for feature_name, dependencies in pp_origin_trial_dependency_map.items() | sort %}
  if (feature_name == k{{feature_name}}PolicyName) {
    return
    {%- for dependency in dependencies %}
    {%- if not loop.first %} &&{% endif %}
 !RuntimeEnabledFeatures::{{dependency}}Enabled(feature_context)
    {%- endfor %};
  }
  {% endfor %}
  return false;
}

bool DisabledByOriginTrial(mojom::blink::DocumentPolicyFeature feature,
                           FeatureContext* feature_context) {
  {% for feature_name, dependencies in dp_origin_trial_dependency_map.items() | sort %}
  if (feature == mojom::DocumentPolicyFeature::k{{feature_name}}) {
    return
    {%- for dependency in dependencies %}
    {%- if not loop.first %} &&{% endif %}
 !RuntimeEnabledFeatures::{{dependency}}Enabled(feature_context)
    {%- endfor %};
  }
  {% endfor %}
  return false;
}

String PermissionsPolicyFeatureToProtocol(mojom::blink::PermissionsPolicyFeature feature, ExecutionContext* execution_context) {
  if (execution_context && execution_context->IsIsolatedContext()) {
    switch (feature) {
      {% for feature in permissions_policy_features %}
      {% if feature.visibility == "IsolatedContext" %}
      case mojom::blink::PermissionsPolicyFeature::k{{feature.name}}:
        return protocol::Page::PermissionsPolicyFeatureEnum::{{feature.devtools_enum_name}};
      {% endif %}
      {% endfor %}
      default:
        break;
    }
  }
  switch (feature) {
    {% for feature in permissions_policy_features %}
    {% if feature.visibility == "All" %}
    case mojom::blink::PermissionsPolicyFeature::k{{feature.name}}:
      return protocol::Page::PermissionsPolicyFeatureEnum::{{feature.devtools_enum_name}};
    {% endif %}
    {% endfor %}
    default:
      // This default case also handles the mojom entry for
      // mojom::blink::PermissionsPolicyFeature::kNotFound.
      NOTREACHED_IN_MIGRATION();
      return "";
  }
}

}  // namespace blink