chromium/base/feature_list.cc

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include "base/feature_list.h"

#include <stddef.h>

#include <string>
#include <string_view>
#include <tuple>

#include "base/base_switches.h"
#include "base/containers/contains.h"
#include "base/containers/span.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/persistent_memory_allocator.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/pickle.h"
#include "base/rand_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "base/feature_visitor.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

namespace base {

namespace {

// Pointer to the FeatureList instance singleton that was set via
// FeatureList::SetInstance(). Does not use base/memory/singleton.h in order to
// have more control over initialization timing. Leaky.
FeatureList* g_feature_list_instance =;

// Tracks access to Feature state before FeatureList registration.
class EarlyFeatureAccessTracker {};

#if DCHECK_IS_ON()
const char* g_reason_overrides_disallowed =;

void DCheckOverridesAllowed() {}
#else
void DCheckOverridesAllowed() {}
#endif

// An allocator entry for a feature in shared memory. The FeatureEntry is
// followed by a base::Pickle object that contains the feature and trial name.
struct FeatureEntry {};

// Splits |text| into two parts by the |separator| where the first part will be
// returned updated in |first| and the second part will be returned as |second|.
// This function returns false if there is more than one |separator| in |first|.
// If there is no |separator| presented in |first|, this function will not
// modify |first| and |second|. It's used for splitting the |enable_features|
// flag into feature name, field trial name and feature parameters.
bool SplitIntoTwo(std::string_view text,
                  std::string_view separator,
                  std::string_view* first,
                  std::string* second) {}

// Checks and parses the |enable_features| flag and sets
// |parsed_enable_features| to be a comma-separated list of features,
// |force_fieldtrials| to be a comma-separated list of field trials that each
// feature want to associate with and |force_fieldtrial_params| to be the field
// trial parameters for each field trial.
// Returns true if |enable_features| is parsable, otherwise false.
bool ParseEnableFeatures(const std::string& enable_features,
                         std::string* parsed_enable_features,
                         std::string* force_fieldtrials,
                         std::string* force_fieldtrial_params) {}

std::pair<FeatureList::OverrideState, uint16_t> UnpackFeatureCache(
    uint32_t packed_cache_value) {}

uint32_t PackFeatureCache(FeatureList::OverrideState override_state,
                          uint32_t caching_context) {}

// A monotonically increasing id, passed to `FeatureList`s as they are created
// to invalidate the cache member of `base::Feature` objects that were queried
// with a different `FeatureList` installed.
uint16_t g_current_caching_context =;

}  // namespace

#if BUILDFLAG(DCHECK_IS_CONFIGURABLE)
BASE_FEATURE(kDCheckIsFatalFeature,
             "DcheckIsFatal",
             FEATURE_DISABLED_BY_DEFAULT);
#endif  // BUILDFLAG(DCHECK_IS_CONFIGURABLE)

FeatureList::FeatureList() :{}

FeatureList::~FeatureList() = default;

FeatureList::ScopedDisallowOverrides::ScopedDisallowOverrides(
    const char* reason)
#if DCHECK_IS_ON()
    :{}
#else
{
}
#endif

FeatureList::ScopedDisallowOverrides::~ScopedDisallowOverrides() {}

void FeatureList::InitFromCommandLine(const std::string& enable_features,
                                      const std::string& disable_features) {}

void FeatureList::InitFromSharedMemory(PersistentMemoryAllocator* allocator) {}

bool FeatureList::IsFeatureOverridden(const std::string& feature_name) const {}

bool FeatureList::IsFeatureOverriddenFromCommandLine(
    const std::string& feature_name) const {}

bool FeatureList::IsFeatureOverriddenFromCommandLine(
    const std::string& feature_name,
    OverrideState state) const {}

void FeatureList::AssociateReportingFieldTrial(
    const std::string& feature_name,
    OverrideState for_overridden_state,
    FieldTrial* field_trial) {}

void FeatureList::RegisterFieldTrialOverride(const std::string& feature_name,
                                             OverrideState override_state,
                                             FieldTrial* field_trial) {}

void FeatureList::RegisterExtraFeatureOverrides(
    const std::vector<FeatureOverrideInfo>& extra_overrides) {}

void FeatureList::AddFeaturesToAllocator(PersistentMemoryAllocator* allocator) {}

void FeatureList::GetFeatureOverrides(std::string* enable_overrides,
                                      std::string* disable_overrides,
                                      bool include_group_name) const {}

void FeatureList::GetCommandLineFeatureOverrides(
    std::string* enable_overrides,
    std::string* disable_overrides) const {}

// static
bool FeatureList::IsEnabled(const Feature& feature) {}

// static
bool FeatureList::IsValidFeatureOrFieldTrialName(std::string_view name) {}

// static
std::optional<bool> FeatureList::GetStateIfOverridden(const Feature& feature) {}

// static
FieldTrial* FeatureList::GetFieldTrial(const Feature& feature) {}

// static
std::vector<std::string_view> FeatureList::SplitFeatureListString(
    std::string_view input) {}

// static
bool FeatureList::ParseEnableFeatureString(std::string_view enable_feature,
                                           std::string* feature_name,
                                           std::string* study_name,
                                           std::string* group_name,
                                           std::string* params) {}

// static
bool FeatureList::InitInstance(const std::string& enable_features,
                               const std::string& disable_features) {}

// static
bool FeatureList::InitInstance(
    const std::string& enable_features,
    const std::string& disable_features,
    const std::vector<FeatureOverrideInfo>& extra_overrides) {}

// static
FeatureList* FeatureList::GetInstance() {}

// static
void FeatureList::SetInstance(std::unique_ptr<FeatureList> instance) {}

// static
void FeatureList::SetEarlyAccessInstance(
    std::unique_ptr<FeatureList> instance,
    base::flat_set<std::string> allowed_feature_names) {}

// static
std::unique_ptr<FeatureList> FeatureList::ClearInstanceForTesting() {}

// static
void FeatureList::RestoreInstanceForTesting(
    std::unique_ptr<FeatureList> instance) {}

// static
void FeatureList::FailOnFeatureAccessWithoutFeatureList() {}

// static
const Feature* FeatureList::GetEarlyAccessedFeatureForTesting() {}

// static
void FeatureList::ResetEarlyFeatureAccessTrackerForTesting() {}

void FeatureList::AddEarlyAllowedFeatureForTesting(std::string feature_name) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
// static
void FeatureList::VisitFeaturesAndParams(FeatureVisitor& visitor) {
  CHECK(g_feature_list_instance);
  FieldTrialParamAssociator* params_associator =
      FieldTrialParamAssociator::GetInstance();

  for (auto& feature_override : g_feature_list_instance->overrides_) {
    FieldTrial* field_trial = feature_override.second.field_trial;

    std::string trial_name;
    std::string group_name;
    FieldTrialParams params;
    if (field_trial) {
      trial_name = field_trial->trial_name();
      group_name = field_trial->group_name();
      params_associator->GetFieldTrialParamsWithoutFallback(
          trial_name, group_name, &params);
    }

    visitor.Visit(feature_override.first,
                  feature_override.second.overridden_state, params, trial_name,
                  group_name);
  }
}
#endif  // BULDFLAG(IS_CHROMEOS_ASH)

void FeatureList::FinalizeInitialization() {}

bool FeatureList::IsFeatureEnabled(const Feature& feature) const {}

std::optional<bool> FeatureList::IsFeatureEnabledIfOverridden(
    const Feature& feature) const {}

FeatureList::OverrideState FeatureList::GetOverrideState(
    const Feature& feature) const {}

FeatureList::OverrideState FeatureList::GetOverrideStateByFeatureName(
    std::string_view feature_name) const {}

FieldTrial* FeatureList::GetAssociatedFieldTrial(const Feature& feature) const {}

const base::FeatureList::OverrideEntry*
FeatureList::GetOverrideEntryByFeatureName(std::string_view name) const {}

FieldTrial* FeatureList::GetAssociatedFieldTrialByFeatureName(
    std::string_view name) const {}

bool FeatureList::HasAssociatedFieldTrialByFeatureName(
    std::string_view name) const {}

FieldTrial* FeatureList::GetEnabledFieldTrialByFeatureName(
    std::string_view name) const {}

std::unique_ptr<FeatureList::Accessor> FeatureList::ConstructAccessor() {}

void FeatureList::RegisterOverridesFromCommandLine(
    const std::string& feature_list,
    OverrideState overridden_state) {}

void FeatureList::RegisterOverride(std::string_view feature_name,
                                   OverrideState overridden_state,
                                   FieldTrial* field_trial) {}

void FeatureList::GetFeatureOverridesImpl(std::string* enable_overrides,
                                          std::string* disable_overrides,
                                          bool command_line_only,
                                          bool include_group_name) const {}

bool FeatureList::CheckFeatureIdentity(const Feature& feature) const {}

bool FeatureList::IsEarlyAccessInstance() const {}

bool FeatureList::AllowFeatureAccess(const Feature& feature) const {}

FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state,
                                          FieldTrial* field_trial)
    :{}

FeatureList::Accessor::Accessor(FeatureList* feature_list)
    :{}

FeatureList::OverrideState FeatureList::Accessor::GetOverrideStateByFeatureName(
    std::string_view feature_name) {}

bool FeatureList::Accessor::GetParamsByFeatureName(
    std::string_view feature_name,
    std::map<std::string, std::string>* params) {}

}  // namespace base