#include "base/metrics/field_trial.h"
#include <algorithm>
#include <string_view>
#include <utility>
#include "base/auto_reset.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/debug/crash_logging.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/memory.h"
#include "base/process/process_handle.h"
#include "base/process/process_info.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#if BUILDFLAG(USE_BLINK)
#include "base/memory/shared_memory_switch.h"
#include "base/process/launch.h"
#endif
#if BUILDFLAG(IS_APPLE) && BUILDFLAG(USE_BLINK)
#include "base/mac/mach_port_rendezvous.h"
#endif
#if BUILDFLAG(IS_POSIX) && BUILDFLAG(USE_BLINK)
#include <unistd.h>
#include "base/threading/platform_thread.h"
#include "base/posix/global_descriptors.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
#if BUILDFLAG(IS_FUCHSIA)
#include <lib/zx/vmo.h>
#include <zircon/process.h>
#include "base/fuchsia/fuchsia_logging.h"
#endif
namespace base {
namespace {
#if BUILDFLAG(USE_BLINK)
SharedMemoryError;
#endif
const char kPersistentStringSeparator = …;
const char kActivationMarker = …;
const char kAllocatorName[] = …;
const size_t kFieldTrialAllocationSize = …;
#if BUILDFLAG(IS_APPLE) && BUILDFLAG(USE_BLINK)
constexpr MachPortsForRendezvous::key_type kFieldTrialRendezvousKey = 'fldt';
#endif
void WriteStringPair(Pickle* pickle,
std::string_view string1,
std::string_view string2) { … }
void PickleFieldTrial(const FieldTrial::PickleState& trial_state,
Pickle* pickle) { … }
FieldTrial::Probability GetGroupBoundaryValue(
FieldTrial::Probability divisor,
double entropy_value) { … }
void OnOutOfMemory(size_t size) { … }
void AppendFieldTrialGroupToString(bool activated,
std::string_view trial_name,
std::string_view group_name,
std::string& field_trials_string) { … }
}
const int FieldTrial::kNotFinalized = …;
const int FieldTrial::kDefaultGroupNumber = …;
bool FieldTrial::enable_benchmarking_ = …;
FieldTrial::EntropyProvider::~EntropyProvider() = default;
uint32_t FieldTrial::EntropyProvider::GetPseudorandomValue(
uint32_t salt,
uint32_t output_range) const { … }
FieldTrial::PickleState::PickleState() = default;
FieldTrial::PickleState::PickleState(const PickleState& other) = default;
FieldTrial::PickleState::~PickleState() = default;
bool FieldTrial::FieldTrialEntry::GetState(std::string_view& trial_name,
std::string_view& group_name,
bool& overridden) const { … }
bool FieldTrial::FieldTrialEntry::GetParams(
std::map<std::string, std::string>* params) const { … }
PickleIterator FieldTrial::FieldTrialEntry::GetPickleIterator() const { … }
bool FieldTrial::FieldTrialEntry::ReadHeader(PickleIterator& iter,
std::string_view& trial_name,
std::string_view& group_name,
bool& overridden) const { … }
bool FieldTrial::FieldTrialEntry::ReadStringPair(
PickleIterator* iter,
std::string_view* trial_name,
std::string_view* group_name) const { … }
void FieldTrial::AppendGroup(const std::string& name,
Probability group_probability) { … }
void FieldTrial::Activate() { … }
const std::string& FieldTrial::group_name() { … }
const std::string& FieldTrial::GetGroupNameWithoutActivation() { … }
void FieldTrial::SetForced() { … }
bool FieldTrial::IsOverridden() const { … }
void FieldTrial::EnableBenchmarking() { … }
FieldTrial* FieldTrial::CreateSimulatedFieldTrial(
std::string_view trial_name,
Probability total_probability,
std::string_view default_group_name,
double entropy_value) { … }
bool FieldTrial::ParseFieldTrialsString(std::string_view trials_string,
bool override_trials,
std::vector<State>& entries) { … }
std::string FieldTrial::BuildFieldTrialStateString(
const std::vector<State>& states) { … }
FieldTrial::FieldTrial(std::string_view trial_name,
const Probability total_probability,
std::string_view default_group_name,
double entropy_value,
bool is_low_anonymity,
bool is_overridden)
: … { … }
FieldTrial::~FieldTrial() = default;
void FieldTrial::SetTrialRegistered() { … }
void FieldTrial::SetGroupChoice(const std::string& group_name, int number) { … }
void FieldTrial::FinalizeGroupChoice() { … }
bool FieldTrial::GetActiveGroup(ActiveGroup* active_group) const { … }
void FieldTrial::GetStateWhileLocked(PickleState* field_trial_state) { … }
FieldTrialList* FieldTrialList::global_ = …;
FieldTrialList::Observer::~Observer() = default;
FieldTrialList::FieldTrialList() { … }
FieldTrialList::~FieldTrialList() { … }
FieldTrial* FieldTrialList::FactoryGetFieldTrial(
std::string_view trial_name,
FieldTrial::Probability total_probability,
std::string_view default_group_name,
const FieldTrial::EntropyProvider& entropy_provider,
uint32_t randomization_seed,
bool is_low_anonymity,
bool is_overridden) { … }
FieldTrial* FieldTrialList::Find(std::string_view trial_name) { … }
std::string FieldTrialList::FindFullName(std::string_view trial_name) { … }
bool FieldTrialList::TrialExists(std::string_view trial_name) { … }
bool FieldTrialList::IsTrialActive(std::string_view trial_name) { … }
std::vector<FieldTrial::State> FieldTrialList::GetAllFieldTrialStates(
PassKey<test::ScopedFeatureList>) { … }
void FieldTrialList::AllStatesToString(std::string* output) { … }
std::string FieldTrialList::AllParamsToString(EscapeDataFunc encode_data_func) { … }
void FieldTrialList::GetActiveFieldTrialGroups(
FieldTrial::ActiveGroups* active_groups) { … }
std::set<std::string> FieldTrialList::GetActiveTrialsOfParentProcess() { … }
bool FieldTrialList::CreateTrialsFromString(const std::string& trials_string,
bool override_trials) { … }
bool FieldTrialList::CreateTrialsFromFieldTrialStates(
PassKey<test::ScopedFeatureList>,
const std::vector<FieldTrial::State>& entries) { … }
void FieldTrialList::CreateTrialsInChildProcess(const CommandLine& cmd_line) { … }
void FieldTrialList::ApplyFeatureOverridesInChildProcess(
FeatureList* feature_list) { … }
#if BUILDFLAG(USE_BLINK)
void FieldTrialList::PopulateLaunchOptionsWithFieldTrialState(
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)
GlobalDescriptors::Key descriptor_key,
ScopedFD& descriptor_to_share,
#endif
CommandLine* command_line,
LaunchOptions* launch_options) { … }
#endif
ReadOnlySharedMemoryRegion
FieldTrialList::DuplicateFieldTrialSharedMemoryForTesting() { … }
FieldTrial* FieldTrialList::CreateFieldTrial(std::string_view name,
std::string_view group_name,
bool is_low_anonymity,
bool is_overridden) { … }
bool FieldTrialList::AddObserver(Observer* observer) { … }
void FieldTrialList::RemoveObserver(Observer* observer) { … }
void FieldTrialList::NotifyFieldTrialGroupSelection(FieldTrial* field_trial) { … }
size_t FieldTrialList::GetFieldTrialCount() { … }
size_t FieldTrialList::GetRandomizedFieldTrialCount() { … }
bool FieldTrialList::GetParamsFromSharedMemory(
FieldTrial* field_trial,
std::map<std::string, std::string>* params) { … }
void FieldTrialList::ClearParamsFromSharedMemoryForTesting() { … }
void FieldTrialList::DumpAllFieldTrialsToPersistentAllocator(
PersistentMemoryAllocator* allocator) { … }
std::vector<const FieldTrial::FieldTrialEntry*>
FieldTrialList::GetAllFieldTrialsFromPersistentAllocator(
PersistentMemoryAllocator const& allocator) { … }
FieldTrialList* FieldTrialList::GetInstance() { … }
FieldTrialList* FieldTrialList::ResetInstance() { … }
FieldTrialList* FieldTrialList::BackupInstanceForTesting() { … }
void FieldTrialList::RestoreInstanceForTesting(FieldTrialList* instance) { … }
#if BUILDFLAG(USE_BLINK)
SharedMemoryError FieldTrialList::CreateTrialsFromSwitchValue(
const std::string& switch_value) { … }
#endif
bool FieldTrialList::CreateTrialsFromSharedMemoryRegion(
const ReadOnlySharedMemoryRegion& shm_region) { … }
bool FieldTrialList::CreateTrialsFromSharedMemoryMapping(
ReadOnlySharedMemoryMapping shm_mapping) { … }
void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() { … }
void FieldTrialList::AddToAllocatorWhileLocked(
PersistentMemoryAllocator* allocator,
FieldTrial* field_trial) { … }
void FieldTrialList::ActivateFieldTrialEntryWhileLocked(
FieldTrial* field_trial) { … }
FieldTrial* FieldTrialList::PreLockedFind(std::string_view name) { … }
void FieldTrialList::Register(FieldTrial* trial, bool is_randomized_trial) { … }
FieldTrialList::RegistrationMap FieldTrialList::GetRegisteredTrials() { … }
bool FieldTrialList::CreateTrialsFromFieldTrialStatesInternal(
const std::vector<FieldTrial::State>& entries) { … }
void FieldTrialList::GetActiveFieldTrialGroupsInternal(
FieldTrial::ActiveGroups* active_groups,
bool include_low_anonymity) { … }
bool FieldTrialList::AddObserverInternal(Observer* observer,
bool include_low_anonymity) { … }
void FieldTrialList::RemoveObserverInternal(Observer* observer,
bool include_low_anonymity) { … }
}