// Copyright 2012 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 // The FieldTrial class handles the lower level configuration of running A/B // tests. // // Most server-side experiments should be configured using Features which // have a simpler interface. See base/feature_list.h for details on // configurating a Feature for an experiment. // In certain cases you may still need to use FieldTrial directly. This is // generally for either: // - Client-configured experiments: // The experiment is controlled directly in the code. For example, if the // server controlled behavior is not yet available. See below documentation. // - Synthetic field trials: // These act like field trials for reporting purposes, but the group // placement is controlled directly. See RegisterSyntheticFieldTrial(). // If you have access, see go/client-side-field-trials for additional context. //------------------------------------------------------------------------------ // Details: // FieldTrial is a class for handling details of statistical experiments // performed by actual users in the field (i.e., in a shipped or beta product). // All code is called exclusively on the UI thread currently. It only handles // the lower level details, server-side experiments should use // generally use Features (see above). // // The simplest example is an experiment to see whether one of two options // produces "better" results across our user population. In that scenario, UMA // data is uploaded to aggregate the test results, and this FieldTrial class // manages the state of each such experiment (state == which option was // pseudo-randomly selected). // // States are typically generated randomly, either based on a one time // randomization (which will yield the same results, in terms of selecting // the client for a field trial or not, for every run of the program on a // given machine), or by a session randomization (generated each time the // application starts up, but held constant during the duration of the // process). //------------------------------------------------------------------------------ // Example: Suppose we have an experiment involving memory, such as determining // the impact of some pruning algorithm. Note that using this API directly is // not recommended, see above. // // FieldTrials are reference counted, and persist automagically until // // process teardown, courtesy of their automatic registration in // // FieldTrialList. // scoped_refptr<base::FieldTrial> trial( // base::FieldTrialList::FactoryGetFieldTrial( // "MemoryExperiment", 1000, "StandardMem", entropy_provider); // // trial->AppendGroup("HighMem", 20); // 2% in HighMem group. // trial->AppendGroup("LowMem", 20); // 2% in LowMem group. // // Take action depending of which group we randomly land in. // if (trial->group_name() == "HighMem") // SetPruningAlgorithm(kType1); // else if (trial->group_name() == "LowMem") // SetPruningAlgorithm(kType2); //------------------------------------------------------------------------------ #ifndef BASE_METRICS_FIELD_TRIAL_H_ #define BASE_METRICS_FIELD_TRIAL_H_ #include <stddef.h> #include <stdint.h> #include <atomic> #include <functional> #include <map> #include <memory> #include <set> #include <string> #include <string_view> #include <vector> #include "base/atomicops.h" #include "base/base_export.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/ref_counted.h" #include "base/memory/shared_memory_mapping.h" #include "base/metrics/persistent_memory_allocator.h" #include "base/pickle.h" #include "base/synchronization/lock.h" #include "base/types/expected.h" #include "base/types/pass_key.h" #include "build/blink_buildflags.h" #include "build/build_config.h" #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) #include "base/files/platform_file.h" #include "base/posix/global_descriptors.h" #endif namespace base { namespace test { class ScopedFeatureList; } // namespace test class CompareActiveGroupToFieldTrialMatcher; class FieldTrialList; struct LaunchOptions; #if BUILDFLAG(USE_BLINK) namespace shared_memory { enum class SharedMemoryError; } // namespace shared_memory #endif class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> { … }; //------------------------------------------------------------------------------ // Class with a list of all active field trials. A trial is active if it has // been registered, which includes evaluating its state based on its // probability. Only one instance of this class exists and outside of testing, // will live for the entire life time of the process. class BASE_EXPORT FieldTrialList { … }; } // namespace base #endif // BASE_METRICS_FIELD_TRIAL_H_