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

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

{{source_files_for_generated_file(template_file, input_files)}}

#include "build/build_config.h"
#include "build/chromeos_buildflags.h"

#include "third_party/blink/renderer/platform/runtime_enabled_features.h"

#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/origin_trial_feature/origin_trial_feature.mojom-shared.h"
#include "third_party/blink/renderer/platform/feature_context.h"
#include "third_party/blink/renderer/platform/runtime_feature_state/runtime_feature_state_override_context.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

namespace blink {

RuntimeEnabledFeaturesBase::Backup::Backup()
  : {% for feature in features -%}
    {%- if feature.is_protected_feature -%}
    {{feature.data_member_name}}(RuntimeEnabledFeaturesBase::get_{{feature.data_member_name}}())
    {%- else -%}
    {{feature.data_member_name}}(RuntimeEnabledFeaturesBase::{{feature.data_member_name}})
    {%- endif -%}
    {%- if not loop.last %},
    {%+ endif -%}
    {% endfor %} {}

void RuntimeEnabledFeaturesBase::Backup::Restore() {
  {% for feature in features %}
  {% if feature.is_protected_feature %}
  RuntimeEnabledFeaturesBase::Set{{feature.name}}Enabled({{feature.data_member_name}});
  {% else %}
  RuntimeEnabledFeaturesBase::{{feature.data_member_name}} = {{feature.data_member_name}};
  {% endif %}
  {% endfor %}
}

{% for feature_set in feature_sets %}
void RuntimeEnabledFeaturesBase::Set{{feature_set|capitalize}}FeaturesEnabled(bool enable) {
  {% for feature in features if feature.status_type == 'str' and feature.status == feature_set %}
  Set{{feature.name}}Enabled(enable);
  {% endfor %}

  // Platform-dependent features
  {% for platform in platforms %}
#if {{platform_buildflag(platform)}}
  {% for feature in features if feature.status_type == 'dict' and feature.status[platform] == feature_set %}
  Set{{feature.name}}Enabled(enable);
  {% endfor %}
#endif

  {% endfor %}
  // Default values for platforms not specifically handled above
#if
  {%- for platform in platforms %}
  {%- if not loop.first %} &&{% endif %}
 !{{platform_buildflag(platform)}}
  {%- endfor %}

  {% for feature in features if feature.status_type == 'dict' and feature.status['default'] == feature_set %}
  Set{{feature.name}}Enabled(enable);
  {% endfor %}
#endif
}

{% endfor %}

void RuntimeEnabledFeaturesBase::SetOriginTrialControlledFeaturesEnabled(bool enable) {
  {% for feature in origin_trial_controlled_features %}
  Set{{feature.name}}Enabled(enable);
  {% endfor %}
}

void RuntimeEnabledFeaturesBase::SetFeatureEnabledFromString(
    const std::string& name, bool enable) {
  static const struct {
    const char* name;
    void (*SetFunction)(bool);
  } kFeatures[] = {
  {% for feature in features|sort(attribute='name') %}
    {"{{feature.name}}", Set{{feature.name}}Enabled},
  {% endfor %}
  };

  auto feature = std::lower_bound(std::begin(kFeatures), std::end(kFeatures), name, [](const auto& feature, const std::string& name) {
    return feature.name < name;
  });

  if (feature != std::end(kFeatures) && feature->name == name)
    feature->SetFunction(enable);
  else
    DLOG(ERROR) << "RuntimeEnabledFeature not recognized: " << name;
}

bool RuntimeEnabledFeaturesBase::IsFeatureEnabledFromString(
    const std::string& name) {
  static const struct {
    const char* name;
    bool (*GetFunction)();
  } kFeatures[] = {
  {% for feature in features|sort(attribute='name') %}
    {% if not feature.in_origin_trial %}
    {"{{feature.name}}",  {{feature.name}}Enabled},
    {% endif %}
  {% endfor %}
  };

  auto feature = std::lower_bound(std::begin(kFeatures), std::end(kFeatures), name, [](const auto& feature, const std::string& name) {
    return feature.name < name;
  });

  if (feature != std::end(kFeatures) && feature->name == name) {
    return feature->GetFunction();
  } else {
    CHECK(false) << " RuntimeEnabledFeature not recognized: " << name;
    return false;
  }
}

// static
void RuntimeEnabledFeaturesBase::UpdateStatusFromBaseFeatures() {
  struct BaseFeatureToRuntimeFeatureMap {
    const base::Feature& feature;
    void (*enabler)(bool enable);
    bool if_overridden;
  };
  const BaseFeatureToRuntimeFeatureMap mappings[] = {
  {% for feature in features|sort(attribute='name') %}
    {% if feature.base_feature %}
    {blink::features::k{{feature.base_feature}}, Set{{feature.name}}Enabled,
     {{'true' if feature.copied_from_base_feature_if == "overridden" else 'false'}}},
    {% endif %}
  {% endfor %}
  };
  for (const auto& map : mappings) {
    const bool feature_enabled = base::FeatureList::IsEnabled(map.feature);
    const bool is_overridden =
        base::FeatureList::GetStateIfOverridden(map.feature).has_value();
    if (map.if_overridden) {
      if (is_overridden)
        map.enabler(feature_enabled);
    } else {
      if (feature_enabled || is_overridden)
        map.enabler(feature_enabled);
    }
  }
}

{% for feature in features %}
{% if feature.is_protected_feature %}
void RuntimeEnabledFeaturesBase::Set{{feature.name}}Enabled(bool enabled) {
  if (get_{{feature.data_member_name}}() == enabled) {
    return;
  }
  base::AutoWritableMemory protected_memory_writer({{feature.data_member_name}});
  protected_memory_writer.GetProtectedData() = enabled;
}
{% endif %}
{% endfor %}

{% for feature in features %}
{%if feature.is_overridable_feature and not feature.in_origin_trial%}
bool RuntimeEnabledFeaturesBase::{{feature.name}}Enabled(const FeatureContext* context) {
  if(context && context->GetRuntimeFeatureStateOverrideContext()
                    ->Is{{feature.name}}ForceEnabled()) {
    return true;
  }
  if(context && context->GetRuntimeFeatureStateOverrideContext()
                    ->Is{{feature.name}}ForceDisabled()) {
    return false;
  }

  return {{feature.name}}Enabled();
}

{% endif %}
{% endfor %}

{% for feature in origin_trial_controlled_features %}

bool RuntimeEnabledFeaturesBase::{{feature.name}}Enabled(const FeatureContext* context) {
  {% if feature.is_overridable_feature%}
  if(context && context->GetRuntimeFeatureStateOverrideContext()
                    ->Is{{feature.name}}ForceEnabled()) {
    return true;
  }
  if(context && context->GetRuntimeFeatureStateOverrideContext()
                    ->Is{{feature.name}}ForceDisabled()) {
    return false;
  }

  {% endif %}
  {% for depends_on in feature.depends_on %}
  if (!RuntimeEnabledFeaturesBase::{{depends_on}}Enabled(context))
    return false;
  {% endfor %}
  {% for implied_by in feature.implied_by %}
  if (RuntimeEnabledFeaturesBase::{{implied_by}}Enabled(context))
    return true;
  {% endfor %}
  {% if feature.is_protected_feature %}
  if (get_{{feature.data_member_name}}())
  {% else %}
  if ({{feature.data_member_name}})
  {% endif %}
    return true;
  {% if not feature.origin_trial_feature_name %}
  // The feature does not have an origin trial name and its runtime flag
  // is not enabled.
  return false;
  {% else %}
  return context && context->FeatureEnabled(mojom::blink::OriginTrialFeature::k{{feature.name}});
  {% endif %}
}

{% endfor %}

{% for feature in features %}
{% if feature.status_type == 'str' %}
{% if feature.is_protected_feature %}
DEFINE_PROTECTED_DATA base::ProtectedMemory<bool> RuntimeEnabledFeaturesBase::{{feature.data_member_name}};
{% else %}
bool RuntimeEnabledFeaturesBase::{{feature.data_member_name}} = {{'true' if feature.status == 'stable' else 'false'}};
{% endif %}
{% endif %}
{% endfor %}

// Platform-dependent features
{% for platform in platforms %}
#if {{platform_buildflag(platform)}}
{% for feature in features %}
{% if feature.status_type == 'dict' %}
bool RuntimeEnabledFeaturesBase::{{feature.data_member_name}} = {{'true' if feature.status[platform] == 'stable' else 'false'}};
{% endif %}
{% endfor %}
#endif

{% endfor %}
// Default values for platforms not specifically handled above
#if
{%- for platform in platforms %}
{%- if not loop.first %} &&{% endif %}
 !{{platform_buildflag(platform)}}
{%- endfor %}

{% for feature in features %}
{% if feature.status_type == 'dict' %}
bool RuntimeEnabledFeaturesBase::{{feature.data_member_name}} = {{'true' if feature.status['default'] == 'stable' else 'false'}};
{% endif %}
{% endfor %}
#endif

// Simple getter methods for protected memory values that ensure they are
// properly initialized before first access.
{% for feature in features %}
{% if feature.is_protected_feature %}
bool RuntimeEnabledFeaturesBase::get_{{feature.data_member_name}}() {
  static base::ProtectedMemoryInitializer {{feature.data_member_name}}initializer({{feature.data_member_name}}, {{'true' if feature.status == 'stable' else 'false'}});
  return *{{feature.data_member_name}};
}
{% endif %}
{% endfor %}

} // namespace blink