xref: /aosp_15_r20/external/libchrome/base/metrics/field_trial.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker // FieldTrial is a class for handling details of statistical experiments
6*635a8641SAndroid Build Coastguard Worker // performed by actual users in the field (i.e., in a shipped or beta product).
7*635a8641SAndroid Build Coastguard Worker // All code is called exclusively on the UI thread currently.
8*635a8641SAndroid Build Coastguard Worker //
9*635a8641SAndroid Build Coastguard Worker // The simplest example is an experiment to see whether one of two options
10*635a8641SAndroid Build Coastguard Worker // produces "better" results across our user population.  In that scenario, UMA
11*635a8641SAndroid Build Coastguard Worker // data is uploaded to aggregate the test results, and this FieldTrial class
12*635a8641SAndroid Build Coastguard Worker // manages the state of each such experiment (state == which option was
13*635a8641SAndroid Build Coastguard Worker // pseudo-randomly selected).
14*635a8641SAndroid Build Coastguard Worker //
15*635a8641SAndroid Build Coastguard Worker // States are typically generated randomly, either based on a one time
16*635a8641SAndroid Build Coastguard Worker // randomization (which will yield the same results, in terms of selecting
17*635a8641SAndroid Build Coastguard Worker // the client for a field trial or not, for every run of the program on a
18*635a8641SAndroid Build Coastguard Worker // given machine), or by a session randomization (generated each time the
19*635a8641SAndroid Build Coastguard Worker // application starts up, but held constant during the duration of the
20*635a8641SAndroid Build Coastguard Worker // process).
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
23*635a8641SAndroid Build Coastguard Worker // Example:  Suppose we have an experiment involving memory, such as determining
24*635a8641SAndroid Build Coastguard Worker // the impact of some pruning algorithm.
25*635a8641SAndroid Build Coastguard Worker // We assume that we already have a histogram of memory usage, such as:
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker //   UMA_HISTOGRAM_COUNTS("Memory.RendererTotal", count);
28*635a8641SAndroid Build Coastguard Worker 
29*635a8641SAndroid Build Coastguard Worker // Somewhere in main thread initialization code, we'd probably define an
30*635a8641SAndroid Build Coastguard Worker // instance of a FieldTrial, with code such as:
31*635a8641SAndroid Build Coastguard Worker 
32*635a8641SAndroid Build Coastguard Worker // // FieldTrials are reference counted, and persist automagically until
33*635a8641SAndroid Build Coastguard Worker // // process teardown, courtesy of their automatic registration in
34*635a8641SAndroid Build Coastguard Worker // // FieldTrialList.
35*635a8641SAndroid Build Coastguard Worker // // Note: This field trial will run in Chrome instances compiled through
36*635a8641SAndroid Build Coastguard Worker // //       8 July, 2015, and after that all instances will be in "StandardMem".
37*635a8641SAndroid Build Coastguard Worker // scoped_refptr<base::FieldTrial> trial(
38*635a8641SAndroid Build Coastguard Worker //     base::FieldTrialList::FactoryGetFieldTrial(
39*635a8641SAndroid Build Coastguard Worker //         "MemoryExperiment", 1000, "StandardMem", 2015, 7, 8,
40*635a8641SAndroid Build Coastguard Worker //         base::FieldTrial::ONE_TIME_RANDOMIZED, NULL));
41*635a8641SAndroid Build Coastguard Worker //
42*635a8641SAndroid Build Coastguard Worker // const int high_mem_group =
43*635a8641SAndroid Build Coastguard Worker //     trial->AppendGroup("HighMem", 20);  // 2% in HighMem group.
44*635a8641SAndroid Build Coastguard Worker // const int low_mem_group =
45*635a8641SAndroid Build Coastguard Worker //     trial->AppendGroup("LowMem", 20);   // 2% in LowMem group.
46*635a8641SAndroid Build Coastguard Worker // // Take action depending of which group we randomly land in.
47*635a8641SAndroid Build Coastguard Worker // if (trial->group() == high_mem_group)
48*635a8641SAndroid Build Coastguard Worker //   SetPruningAlgorithm(kType1);  // Sample setting of browser state.
49*635a8641SAndroid Build Coastguard Worker // else if (trial->group() == low_mem_group)
50*635a8641SAndroid Build Coastguard Worker //   SetPruningAlgorithm(kType2);  // Sample alternate setting.
51*635a8641SAndroid Build Coastguard Worker 
52*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
53*635a8641SAndroid Build Coastguard Worker 
54*635a8641SAndroid Build Coastguard Worker #ifndef BASE_METRICS_FIELD_TRIAL_H_
55*635a8641SAndroid Build Coastguard Worker #define BASE_METRICS_FIELD_TRIAL_H_
56*635a8641SAndroid Build Coastguard Worker 
57*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
58*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
59*635a8641SAndroid Build Coastguard Worker 
60*635a8641SAndroid Build Coastguard Worker #include <map>
61*635a8641SAndroid Build Coastguard Worker #include <memory>
62*635a8641SAndroid Build Coastguard Worker #include <set>
63*635a8641SAndroid Build Coastguard Worker #include <string>
64*635a8641SAndroid Build Coastguard Worker #include <vector>
65*635a8641SAndroid Build Coastguard Worker 
66*635a8641SAndroid Build Coastguard Worker #include "base/atomicops.h"
67*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
68*635a8641SAndroid Build Coastguard Worker #include "base/command_line.h"
69*635a8641SAndroid Build Coastguard Worker #include "base/feature_list.h"
70*635a8641SAndroid Build Coastguard Worker #include "base/files/file.h"
71*635a8641SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
72*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
73*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
74*635a8641SAndroid Build Coastguard Worker #include "base/memory/shared_memory.h"
75*635a8641SAndroid Build Coastguard Worker #include "base/memory/shared_memory_handle.h"
76*635a8641SAndroid Build Coastguard Worker #include "base/metrics/persistent_memory_allocator.h"
77*635a8641SAndroid Build Coastguard Worker #include "base/observer_list_threadsafe.h"
78*635a8641SAndroid Build Coastguard Worker #include "base/pickle.h"
79*635a8641SAndroid Build Coastguard Worker #include "base/process/launch.h"
80*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
81*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
82*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
83*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker namespace base {
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker class FieldTrialList;
88*635a8641SAndroid Build Coastguard Worker 
89*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> {
90*635a8641SAndroid Build Coastguard Worker  public:
91*635a8641SAndroid Build Coastguard Worker   typedef int Probability;  // Probability type for being selected in a trial.
92*635a8641SAndroid Build Coastguard Worker 
93*635a8641SAndroid Build Coastguard Worker   // TODO(665129): Make private again after crash has been resolved.
94*635a8641SAndroid Build Coastguard Worker   typedef SharedPersistentMemoryAllocator::Reference FieldTrialRef;
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker   // Specifies the persistence of the field trial group choice.
97*635a8641SAndroid Build Coastguard Worker   enum RandomizationType {
98*635a8641SAndroid Build Coastguard Worker     // One time randomized trials will persist the group choice between
99*635a8641SAndroid Build Coastguard Worker     // restarts, which is recommended for most trials, especially those that
100*635a8641SAndroid Build Coastguard Worker     // change user visible behavior.
101*635a8641SAndroid Build Coastguard Worker     ONE_TIME_RANDOMIZED,
102*635a8641SAndroid Build Coastguard Worker     // Session randomized trials will roll the dice to select a group on every
103*635a8641SAndroid Build Coastguard Worker     // process restart.
104*635a8641SAndroid Build Coastguard Worker     SESSION_RANDOMIZED,
105*635a8641SAndroid Build Coastguard Worker   };
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker   // EntropyProvider is an interface for providing entropy for one-time
108*635a8641SAndroid Build Coastguard Worker   // randomized (persistent) field trials.
109*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT EntropyProvider {
110*635a8641SAndroid Build Coastguard Worker    public:
111*635a8641SAndroid Build Coastguard Worker     virtual ~EntropyProvider();
112*635a8641SAndroid Build Coastguard Worker 
113*635a8641SAndroid Build Coastguard Worker     // Returns a double in the range of [0, 1) to be used for the dice roll for
114*635a8641SAndroid Build Coastguard Worker     // the specified field trial. If |randomization_seed| is not 0, it will be
115*635a8641SAndroid Build Coastguard Worker     // used in preference to |trial_name| for generating the entropy by entropy
116*635a8641SAndroid Build Coastguard Worker     // providers that support it. A given instance should always return the same
117*635a8641SAndroid Build Coastguard Worker     // value given the same input |trial_name| and |randomization_seed| values.
118*635a8641SAndroid Build Coastguard Worker     virtual double GetEntropyForTrial(const std::string& trial_name,
119*635a8641SAndroid Build Coastguard Worker                                       uint32_t randomization_seed) const = 0;
120*635a8641SAndroid Build Coastguard Worker   };
121*635a8641SAndroid Build Coastguard Worker 
122*635a8641SAndroid Build Coastguard Worker   // A pair representing a Field Trial and its selected group.
123*635a8641SAndroid Build Coastguard Worker   struct ActiveGroup {
124*635a8641SAndroid Build Coastguard Worker     std::string trial_name;
125*635a8641SAndroid Build Coastguard Worker     std::string group_name;
126*635a8641SAndroid Build Coastguard Worker   };
127*635a8641SAndroid Build Coastguard Worker 
128*635a8641SAndroid Build Coastguard Worker   // A triplet representing a FieldTrial, its selected group and whether it's
129*635a8641SAndroid Build Coastguard Worker   // active. String members are pointers to the underlying strings owned by the
130*635a8641SAndroid Build Coastguard Worker   // FieldTrial object. Does not use StringPiece to avoid conversions back to
131*635a8641SAndroid Build Coastguard Worker   // std::string.
132*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT State {
133*635a8641SAndroid Build Coastguard Worker     const std::string* trial_name = nullptr;
134*635a8641SAndroid Build Coastguard Worker     const std::string* group_name = nullptr;
135*635a8641SAndroid Build Coastguard Worker     bool activated = false;
136*635a8641SAndroid Build Coastguard Worker 
137*635a8641SAndroid Build Coastguard Worker     State();
138*635a8641SAndroid Build Coastguard Worker     State(const State& other);
139*635a8641SAndroid Build Coastguard Worker     ~State();
140*635a8641SAndroid Build Coastguard Worker   };
141*635a8641SAndroid Build Coastguard Worker 
142*635a8641SAndroid Build Coastguard Worker   // We create one FieldTrialEntry per field trial in shared memory, via
143*635a8641SAndroid Build Coastguard Worker   // AddToAllocatorWhileLocked. The FieldTrialEntry is followed by a
144*635a8641SAndroid Build Coastguard Worker   // base::Pickle object that we unpickle and read from.
145*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT FieldTrialEntry {
146*635a8641SAndroid Build Coastguard Worker     // SHA1(FieldTrialEntry): Increment this if structure changes!
147*635a8641SAndroid Build Coastguard Worker     static constexpr uint32_t kPersistentTypeId = 0xABA17E13 + 2;
148*635a8641SAndroid Build Coastguard Worker 
149*635a8641SAndroid Build Coastguard Worker     // Expected size for 32/64-bit check.
150*635a8641SAndroid Build Coastguard Worker     static constexpr size_t kExpectedInstanceSize = 8;
151*635a8641SAndroid Build Coastguard Worker 
152*635a8641SAndroid Build Coastguard Worker     // Whether or not this field trial is activated. This is really just a
153*635a8641SAndroid Build Coastguard Worker     // boolean but using a 32 bit value for portability reasons. It should be
154*635a8641SAndroid Build Coastguard Worker     // accessed via NoBarrier_Load()/NoBarrier_Store() to prevent the compiler
155*635a8641SAndroid Build Coastguard Worker     // from doing unexpected optimizations because it thinks that only one
156*635a8641SAndroid Build Coastguard Worker     // thread is accessing the memory location.
157*635a8641SAndroid Build Coastguard Worker     subtle::Atomic32 activated;
158*635a8641SAndroid Build Coastguard Worker 
159*635a8641SAndroid Build Coastguard Worker     // Size of the pickled structure, NOT the total size of this entry.
160*635a8641SAndroid Build Coastguard Worker     uint32_t pickle_size;
161*635a8641SAndroid Build Coastguard Worker 
162*635a8641SAndroid Build Coastguard Worker     // Calling this is only valid when the entry is initialized. That is, it
163*635a8641SAndroid Build Coastguard Worker     // resides in shared memory and has a pickle containing the trial name and
164*635a8641SAndroid Build Coastguard Worker     // group name following it.
165*635a8641SAndroid Build Coastguard Worker     bool GetTrialAndGroupName(StringPiece* trial_name,
166*635a8641SAndroid Build Coastguard Worker                               StringPiece* group_name) const;
167*635a8641SAndroid Build Coastguard Worker 
168*635a8641SAndroid Build Coastguard Worker     // Calling this is only valid when the entry is initialized as well. Reads
169*635a8641SAndroid Build Coastguard Worker     // the parameters following the trial and group name and stores them as
170*635a8641SAndroid Build Coastguard Worker     // key-value mappings in |params|.
171*635a8641SAndroid Build Coastguard Worker     bool GetParams(std::map<std::string, std::string>* params) const;
172*635a8641SAndroid Build Coastguard Worker 
173*635a8641SAndroid Build Coastguard Worker    private:
174*635a8641SAndroid Build Coastguard Worker     // Returns an iterator over the data containing names and params.
175*635a8641SAndroid Build Coastguard Worker     PickleIterator GetPickleIterator() const;
176*635a8641SAndroid Build Coastguard Worker 
177*635a8641SAndroid Build Coastguard Worker     // Takes the iterator and writes out the first two items into |trial_name|
178*635a8641SAndroid Build Coastguard Worker     // and |group_name|.
179*635a8641SAndroid Build Coastguard Worker     bool ReadStringPair(PickleIterator* iter,
180*635a8641SAndroid Build Coastguard Worker                         StringPiece* trial_name,
181*635a8641SAndroid Build Coastguard Worker                         StringPiece* group_name) const;
182*635a8641SAndroid Build Coastguard Worker   };
183*635a8641SAndroid Build Coastguard Worker 
184*635a8641SAndroid Build Coastguard Worker   typedef std::vector<ActiveGroup> ActiveGroups;
185*635a8641SAndroid Build Coastguard Worker 
186*635a8641SAndroid Build Coastguard Worker   // A return value to indicate that a given instance has not yet had a group
187*635a8641SAndroid Build Coastguard Worker   // assignment (and hence is not yet participating in the trial).
188*635a8641SAndroid Build Coastguard Worker   static const int kNotFinalized;
189*635a8641SAndroid Build Coastguard Worker 
190*635a8641SAndroid Build Coastguard Worker   // Disables this trial, meaning it always determines the default group
191*635a8641SAndroid Build Coastguard Worker   // has been selected. May be called immediately after construction, or
192*635a8641SAndroid Build Coastguard Worker   // at any time after initialization (should not be interleaved with
193*635a8641SAndroid Build Coastguard Worker   // AppendGroup calls). Once disabled, there is no way to re-enable a
194*635a8641SAndroid Build Coastguard Worker   // trial.
195*635a8641SAndroid Build Coastguard Worker   // TODO(mad): http://code.google.com/p/chromium/issues/detail?id=121446
196*635a8641SAndroid Build Coastguard Worker   // This doesn't properly reset to Default when a group was forced.
197*635a8641SAndroid Build Coastguard Worker   void Disable();
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker   // Establish the name and probability of the next group in this trial.
200*635a8641SAndroid Build Coastguard Worker   // Sometimes, based on construction randomization, this call may cause the
201*635a8641SAndroid Build Coastguard Worker   // provided group to be *THE* group selected for use in this instance.
202*635a8641SAndroid Build Coastguard Worker   // The return value is the group number of the new group.
203*635a8641SAndroid Build Coastguard Worker   int AppendGroup(const std::string& name, Probability group_probability);
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker   // Return the name of the FieldTrial (excluding the group name).
trial_name()206*635a8641SAndroid Build Coastguard Worker   const std::string& trial_name() const { return trial_name_; }
207*635a8641SAndroid Build Coastguard Worker 
208*635a8641SAndroid Build Coastguard Worker   // Return the randomly selected group number that was assigned, and notify
209*635a8641SAndroid Build Coastguard Worker   // any/all observers that this finalized group number has presumably been used
210*635a8641SAndroid Build Coastguard Worker   // (queried), and will never change. Note that this will force an instance to
211*635a8641SAndroid Build Coastguard Worker   // participate, and make it illegal to attempt to probabilistically add any
212*635a8641SAndroid Build Coastguard Worker   // other groups to the trial.
213*635a8641SAndroid Build Coastguard Worker   int group();
214*635a8641SAndroid Build Coastguard Worker 
215*635a8641SAndroid Build Coastguard Worker   // If the group's name is empty, a string version containing the group number
216*635a8641SAndroid Build Coastguard Worker   // is used as the group name. This causes a winner to be chosen if none was.
217*635a8641SAndroid Build Coastguard Worker   const std::string& group_name();
218*635a8641SAndroid Build Coastguard Worker 
219*635a8641SAndroid Build Coastguard Worker   // Finalizes the group choice and returns the chosen group, but does not mark
220*635a8641SAndroid Build Coastguard Worker   // the trial as active - so its state will not be reported until group_name()
221*635a8641SAndroid Build Coastguard Worker   // or similar is called.
222*635a8641SAndroid Build Coastguard Worker   const std::string& GetGroupNameWithoutActivation();
223*635a8641SAndroid Build Coastguard Worker 
224*635a8641SAndroid Build Coastguard Worker   // Set the field trial as forced, meaning that it was setup earlier than
225*635a8641SAndroid Build Coastguard Worker   // the hard coded registration of the field trial to override it.
226*635a8641SAndroid Build Coastguard Worker   // This allows the code that was hard coded to register the field trial to
227*635a8641SAndroid Build Coastguard Worker   // still succeed even though the field trial has already been registered.
228*635a8641SAndroid Build Coastguard Worker   // This must be called after appending all the groups, since we will make
229*635a8641SAndroid Build Coastguard Worker   // the group choice here. Note that this is a NOOP for already forced trials.
230*635a8641SAndroid Build Coastguard Worker   // And, as the rest of the FieldTrial code, this is not thread safe and must
231*635a8641SAndroid Build Coastguard Worker   // be done from the UI thread.
232*635a8641SAndroid Build Coastguard Worker   void SetForced();
233*635a8641SAndroid Build Coastguard Worker 
234*635a8641SAndroid Build Coastguard Worker   // Enable benchmarking sets field trials to a common setting.
235*635a8641SAndroid Build Coastguard Worker   static void EnableBenchmarking();
236*635a8641SAndroid Build Coastguard Worker 
237*635a8641SAndroid Build Coastguard Worker   // Creates a FieldTrial object with the specified parameters, to be used for
238*635a8641SAndroid Build Coastguard Worker   // simulation of group assignment without actually affecting global field
239*635a8641SAndroid Build Coastguard Worker   // trial state in the running process. Group assignment will be done based on
240*635a8641SAndroid Build Coastguard Worker   // |entropy_value|, which must have a range of [0, 1).
241*635a8641SAndroid Build Coastguard Worker   //
242*635a8641SAndroid Build Coastguard Worker   // Note: Using this function will not register the field trial globally in the
243*635a8641SAndroid Build Coastguard Worker   // running process - for that, use FieldTrialList::FactoryGetFieldTrial().
244*635a8641SAndroid Build Coastguard Worker   //
245*635a8641SAndroid Build Coastguard Worker   // The ownership of the returned FieldTrial is transfered to the caller which
246*635a8641SAndroid Build Coastguard Worker   // is responsible for deref'ing it (e.g. by using scoped_refptr<FieldTrial>).
247*635a8641SAndroid Build Coastguard Worker   static FieldTrial* CreateSimulatedFieldTrial(
248*635a8641SAndroid Build Coastguard Worker       const std::string& trial_name,
249*635a8641SAndroid Build Coastguard Worker       Probability total_probability,
250*635a8641SAndroid Build Coastguard Worker       const std::string& default_group_name,
251*635a8641SAndroid Build Coastguard Worker       double entropy_value);
252*635a8641SAndroid Build Coastguard Worker 
253*635a8641SAndroid Build Coastguard Worker  private:
254*635a8641SAndroid Build Coastguard Worker   // Allow tests to access our innards for testing purposes.
255*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration);
256*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities);
257*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability);
258*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability);
259*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities);
260*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner);
261*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability);
262*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroups);
263*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AllGroups);
264*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroupsNotFinalized);
265*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save);
266*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SaveAll);
267*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore);
268*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOff);
269*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOn);
270*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_Default);
271*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_NonDefault);
272*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FloatBoundariesGiveEqualGroupSizes);
273*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DoesNotSurpassTotalProbability);
274*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest,
275*635a8641SAndroid Build Coastguard Worker                            DoNotAddSimulatedFieldTrialsToAllocator);
276*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, ClearParamsFromSharedMemory);
277*635a8641SAndroid Build Coastguard Worker 
278*635a8641SAndroid Build Coastguard Worker   friend class base::FieldTrialList;
279*635a8641SAndroid Build Coastguard Worker 
280*635a8641SAndroid Build Coastguard Worker   friend class RefCounted<FieldTrial>;
281*635a8641SAndroid Build Coastguard Worker 
282*635a8641SAndroid Build Coastguard Worker   // This is the group number of the 'default' group when a choice wasn't forced
283*635a8641SAndroid Build Coastguard Worker   // by a call to FieldTrialList::CreateFieldTrial. It is kept private so that
284*635a8641SAndroid Build Coastguard Worker   // consumers don't use it by mistake in cases where the group was forced.
285*635a8641SAndroid Build Coastguard Worker   static const int kDefaultGroupNumber;
286*635a8641SAndroid Build Coastguard Worker 
287*635a8641SAndroid Build Coastguard Worker   // Creates a field trial with the specified parameters. Group assignment will
288*635a8641SAndroid Build Coastguard Worker   // be done based on |entropy_value|, which must have a range of [0, 1).
289*635a8641SAndroid Build Coastguard Worker   FieldTrial(const std::string& trial_name,
290*635a8641SAndroid Build Coastguard Worker              Probability total_probability,
291*635a8641SAndroid Build Coastguard Worker              const std::string& default_group_name,
292*635a8641SAndroid Build Coastguard Worker              double entropy_value);
293*635a8641SAndroid Build Coastguard Worker   virtual ~FieldTrial();
294*635a8641SAndroid Build Coastguard Worker 
295*635a8641SAndroid Build Coastguard Worker   // Return the default group name of the FieldTrial.
default_group_name()296*635a8641SAndroid Build Coastguard Worker   std::string default_group_name() const { return default_group_name_; }
297*635a8641SAndroid Build Coastguard Worker 
298*635a8641SAndroid Build Coastguard Worker   // Marks this trial as having been registered with the FieldTrialList. Must be
299*635a8641SAndroid Build Coastguard Worker   // called no more than once and before any |group()| calls have occurred.
300*635a8641SAndroid Build Coastguard Worker   void SetTrialRegistered();
301*635a8641SAndroid Build Coastguard Worker 
302*635a8641SAndroid Build Coastguard Worker   // Sets the chosen group name and number.
303*635a8641SAndroid Build Coastguard Worker   void SetGroupChoice(const std::string& group_name, int number);
304*635a8641SAndroid Build Coastguard Worker 
305*635a8641SAndroid Build Coastguard Worker   // Ensures that a group is chosen, if it hasn't yet been. The field trial
306*635a8641SAndroid Build Coastguard Worker   // might yet be disabled, so this call will *not* notify observers of the
307*635a8641SAndroid Build Coastguard Worker   // status.
308*635a8641SAndroid Build Coastguard Worker   void FinalizeGroupChoice();
309*635a8641SAndroid Build Coastguard Worker 
310*635a8641SAndroid Build Coastguard Worker   // Implements FinalizeGroupChoice() with the added flexibility of being
311*635a8641SAndroid Build Coastguard Worker   // deadlock-free if |is_locked| is true and the caller is holding a lock.
312*635a8641SAndroid Build Coastguard Worker   void FinalizeGroupChoiceImpl(bool is_locked);
313*635a8641SAndroid Build Coastguard Worker 
314*635a8641SAndroid Build Coastguard Worker   // Returns the trial name and selected group name for this field trial via
315*635a8641SAndroid Build Coastguard Worker   // the output parameter |active_group|, but only if the group has already
316*635a8641SAndroid Build Coastguard Worker   // been chosen and has been externally observed via |group()| and the trial
317*635a8641SAndroid Build Coastguard Worker   // has not been disabled. In that case, true is returned and |active_group|
318*635a8641SAndroid Build Coastguard Worker   // is filled in; otherwise, the result is false and |active_group| is left
319*635a8641SAndroid Build Coastguard Worker   // untouched.
320*635a8641SAndroid Build Coastguard Worker   bool GetActiveGroup(ActiveGroup* active_group) const;
321*635a8641SAndroid Build Coastguard Worker 
322*635a8641SAndroid Build Coastguard Worker   // Returns the trial name and selected group name for this field trial via
323*635a8641SAndroid Build Coastguard Worker   // the output parameter |field_trial_state| for all the studies when
324*635a8641SAndroid Build Coastguard Worker   // |bool include_expired| is true. In case when |bool include_expired| is
325*635a8641SAndroid Build Coastguard Worker   // false, if the trial has not been disabled true is returned and
326*635a8641SAndroid Build Coastguard Worker   // |field_trial_state| is filled in; otherwise, the result is false and
327*635a8641SAndroid Build Coastguard Worker   // |field_trial_state| is left untouched.
328*635a8641SAndroid Build Coastguard Worker   // This function is deadlock-free if the caller is holding a lock.
329*635a8641SAndroid Build Coastguard Worker   bool GetStateWhileLocked(State* field_trial_state, bool include_expired);
330*635a8641SAndroid Build Coastguard Worker 
331*635a8641SAndroid Build Coastguard Worker   // Returns the group_name. A winner need not have been chosen.
group_name_internal()332*635a8641SAndroid Build Coastguard Worker   std::string group_name_internal() const { return group_name_; }
333*635a8641SAndroid Build Coastguard Worker 
334*635a8641SAndroid Build Coastguard Worker   // The name of the field trial, as can be found via the FieldTrialList.
335*635a8641SAndroid Build Coastguard Worker   const std::string trial_name_;
336*635a8641SAndroid Build Coastguard Worker 
337*635a8641SAndroid Build Coastguard Worker   // The maximum sum of all probabilities supplied, which corresponds to 100%.
338*635a8641SAndroid Build Coastguard Worker   // This is the scaling factor used to adjust supplied probabilities.
339*635a8641SAndroid Build Coastguard Worker   const Probability divisor_;
340*635a8641SAndroid Build Coastguard Worker 
341*635a8641SAndroid Build Coastguard Worker   // The name of the default group.
342*635a8641SAndroid Build Coastguard Worker   const std::string default_group_name_;
343*635a8641SAndroid Build Coastguard Worker 
344*635a8641SAndroid Build Coastguard Worker   // The randomly selected probability that is used to select a group (or have
345*635a8641SAndroid Build Coastguard Worker   // the instance not participate).  It is the product of divisor_ and a random
346*635a8641SAndroid Build Coastguard Worker   // number between [0, 1).
347*635a8641SAndroid Build Coastguard Worker   Probability random_;
348*635a8641SAndroid Build Coastguard Worker 
349*635a8641SAndroid Build Coastguard Worker   // Sum of the probabilities of all appended groups.
350*635a8641SAndroid Build Coastguard Worker   Probability accumulated_group_probability_;
351*635a8641SAndroid Build Coastguard Worker 
352*635a8641SAndroid Build Coastguard Worker   // The number that will be returned by the next AppendGroup() call.
353*635a8641SAndroid Build Coastguard Worker   int next_group_number_;
354*635a8641SAndroid Build Coastguard Worker 
355*635a8641SAndroid Build Coastguard Worker   // The pseudo-randomly assigned group number.
356*635a8641SAndroid Build Coastguard Worker   // This is kNotFinalized if no group has been assigned.
357*635a8641SAndroid Build Coastguard Worker   int group_;
358*635a8641SAndroid Build Coastguard Worker 
359*635a8641SAndroid Build Coastguard Worker   // A textual name for the randomly selected group. Valid after |group()|
360*635a8641SAndroid Build Coastguard Worker   // has been called.
361*635a8641SAndroid Build Coastguard Worker   std::string group_name_;
362*635a8641SAndroid Build Coastguard Worker 
363*635a8641SAndroid Build Coastguard Worker   // When enable_field_trial_ is false, field trial reverts to the 'default'
364*635a8641SAndroid Build Coastguard Worker   // group.
365*635a8641SAndroid Build Coastguard Worker   bool enable_field_trial_;
366*635a8641SAndroid Build Coastguard Worker 
367*635a8641SAndroid Build Coastguard Worker   // When forced_ is true, we return the chosen group from AppendGroup when
368*635a8641SAndroid Build Coastguard Worker   // appropriate.
369*635a8641SAndroid Build Coastguard Worker   bool forced_;
370*635a8641SAndroid Build Coastguard Worker 
371*635a8641SAndroid Build Coastguard Worker   // Specifies whether the group choice has been reported to observers.
372*635a8641SAndroid Build Coastguard Worker   bool group_reported_;
373*635a8641SAndroid Build Coastguard Worker 
374*635a8641SAndroid Build Coastguard Worker   // Whether this trial is registered with the global FieldTrialList and thus
375*635a8641SAndroid Build Coastguard Worker   // should notify it when its group is queried.
376*635a8641SAndroid Build Coastguard Worker   bool trial_registered_;
377*635a8641SAndroid Build Coastguard Worker 
378*635a8641SAndroid Build Coastguard Worker   // Reference to related field trial struct and data in shared memory.
379*635a8641SAndroid Build Coastguard Worker   FieldTrialRef ref_;
380*635a8641SAndroid Build Coastguard Worker 
381*635a8641SAndroid Build Coastguard Worker   // When benchmarking is enabled, field trials all revert to the 'default'
382*635a8641SAndroid Build Coastguard Worker   // group.
383*635a8641SAndroid Build Coastguard Worker   static bool enable_benchmarking_;
384*635a8641SAndroid Build Coastguard Worker 
385*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(FieldTrial);
386*635a8641SAndroid Build Coastguard Worker };
387*635a8641SAndroid Build Coastguard Worker 
388*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
389*635a8641SAndroid Build Coastguard Worker // Class with a list of all active field trials.  A trial is active if it has
390*635a8641SAndroid Build Coastguard Worker // been registered, which includes evaluating its state based on its probaility.
391*635a8641SAndroid Build Coastguard Worker // Only one instance of this class exists and outside of testing, will live for
392*635a8641SAndroid Build Coastguard Worker // the entire life time of the process.
393*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT FieldTrialList {
394*635a8641SAndroid Build Coastguard Worker  public:
395*635a8641SAndroid Build Coastguard Worker   typedef SharedPersistentMemoryAllocator FieldTrialAllocator;
396*635a8641SAndroid Build Coastguard Worker 
397*635a8641SAndroid Build Coastguard Worker   // Type for function pointer passed to |AllParamsToString| used to escape
398*635a8641SAndroid Build Coastguard Worker   // special characters from |input|.
399*635a8641SAndroid Build Coastguard Worker   typedef std::string (*EscapeDataFunc)(const std::string& input);
400*635a8641SAndroid Build Coastguard Worker 
401*635a8641SAndroid Build Coastguard Worker   // Year that is guaranteed to not be expired when instantiating a field trial
402*635a8641SAndroid Build Coastguard Worker   // via |FactoryGetFieldTrial()|.  Set to two years from the build date.
403*635a8641SAndroid Build Coastguard Worker   static int kNoExpirationYear;
404*635a8641SAndroid Build Coastguard Worker 
405*635a8641SAndroid Build Coastguard Worker   // Observer is notified when a FieldTrial's group is selected.
406*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT Observer {
407*635a8641SAndroid Build Coastguard Worker    public:
408*635a8641SAndroid Build Coastguard Worker     // Notify observers when FieldTrials's group is selected.
409*635a8641SAndroid Build Coastguard Worker     virtual void OnFieldTrialGroupFinalized(const std::string& trial_name,
410*635a8641SAndroid Build Coastguard Worker                                             const std::string& group_name) = 0;
411*635a8641SAndroid Build Coastguard Worker 
412*635a8641SAndroid Build Coastguard Worker    protected:
413*635a8641SAndroid Build Coastguard Worker     virtual ~Observer();
414*635a8641SAndroid Build Coastguard Worker   };
415*635a8641SAndroid Build Coastguard Worker 
416*635a8641SAndroid Build Coastguard Worker   // This singleton holds the global list of registered FieldTrials.
417*635a8641SAndroid Build Coastguard Worker   //
418*635a8641SAndroid Build Coastguard Worker   // To support one-time randomized field trials, specify a non-null
419*635a8641SAndroid Build Coastguard Worker   // |entropy_provider| which should be a source of uniformly distributed
420*635a8641SAndroid Build Coastguard Worker   // entropy values. If one time randomization is not desired, pass in null for
421*635a8641SAndroid Build Coastguard Worker   // |entropy_provider|.
422*635a8641SAndroid Build Coastguard Worker   explicit FieldTrialList(
423*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<const FieldTrial::EntropyProvider> entropy_provider);
424*635a8641SAndroid Build Coastguard Worker 
425*635a8641SAndroid Build Coastguard Worker   // Destructor Release()'s references to all registered FieldTrial instances.
426*635a8641SAndroid Build Coastguard Worker   ~FieldTrialList();
427*635a8641SAndroid Build Coastguard Worker 
428*635a8641SAndroid Build Coastguard Worker   // Get a FieldTrial instance from the factory.
429*635a8641SAndroid Build Coastguard Worker   //
430*635a8641SAndroid Build Coastguard Worker   // |name| is used to register the instance with the FieldTrialList class,
431*635a8641SAndroid Build Coastguard Worker   // and can be used to find the trial (only one trial can be present for each
432*635a8641SAndroid Build Coastguard Worker   // name). |default_group_name| is the name of the default group which will
433*635a8641SAndroid Build Coastguard Worker   // be chosen if none of the subsequent appended groups get to be chosen.
434*635a8641SAndroid Build Coastguard Worker   // |default_group_number| can receive the group number of the default group as
435*635a8641SAndroid Build Coastguard Worker   // AppendGroup returns the number of the subsequence groups. |trial_name| and
436*635a8641SAndroid Build Coastguard Worker   // |default_group_name| may not be empty but |default_group_number| can be
437*635a8641SAndroid Build Coastguard Worker   // NULL if the value is not needed.
438*635a8641SAndroid Build Coastguard Worker   //
439*635a8641SAndroid Build Coastguard Worker   // Group probabilities that are later supplied must sum to less than or equal
440*635a8641SAndroid Build Coastguard Worker   // to the |total_probability|. Arguments |year|, |month| and |day_of_month|
441*635a8641SAndroid Build Coastguard Worker   // specify the expiration time. If the build time is after the expiration time
442*635a8641SAndroid Build Coastguard Worker   // then the field trial reverts to the 'default' group.
443*635a8641SAndroid Build Coastguard Worker   //
444*635a8641SAndroid Build Coastguard Worker   // Use this static method to get a startup-randomized FieldTrial or a
445*635a8641SAndroid Build Coastguard Worker   // previously created forced FieldTrial.
446*635a8641SAndroid Build Coastguard Worker   static FieldTrial* FactoryGetFieldTrial(
447*635a8641SAndroid Build Coastguard Worker       const std::string& trial_name,
448*635a8641SAndroid Build Coastguard Worker       FieldTrial::Probability total_probability,
449*635a8641SAndroid Build Coastguard Worker       const std::string& default_group_name,
450*635a8641SAndroid Build Coastguard Worker       const int year,
451*635a8641SAndroid Build Coastguard Worker       const int month,
452*635a8641SAndroid Build Coastguard Worker       const int day_of_month,
453*635a8641SAndroid Build Coastguard Worker       FieldTrial::RandomizationType randomization_type,
454*635a8641SAndroid Build Coastguard Worker       int* default_group_number);
455*635a8641SAndroid Build Coastguard Worker 
456*635a8641SAndroid Build Coastguard Worker   // Same as FactoryGetFieldTrial(), but allows specifying a custom seed to be
457*635a8641SAndroid Build Coastguard Worker   // used on one-time randomized field trials (instead of a hash of the trial
458*635a8641SAndroid Build Coastguard Worker   // name, which is used otherwise or if |randomization_seed| has value 0). The
459*635a8641SAndroid Build Coastguard Worker   // |randomization_seed| value (other than 0) should never be the same for two
460*635a8641SAndroid Build Coastguard Worker   // trials, else this would result in correlated group assignments.  Note:
461*635a8641SAndroid Build Coastguard Worker   // Using a custom randomization seed is only supported by the
462*635a8641SAndroid Build Coastguard Worker   // PermutedEntropyProvider (which is used when UMA is not enabled). If
463*635a8641SAndroid Build Coastguard Worker   // |override_entropy_provider| is not null, then it will be used for
464*635a8641SAndroid Build Coastguard Worker   // randomization instead of the provider given when the FieldTrialList was
465*635a8641SAndroid Build Coastguard Worker   // instantiated.
466*635a8641SAndroid Build Coastguard Worker   static FieldTrial* FactoryGetFieldTrialWithRandomizationSeed(
467*635a8641SAndroid Build Coastguard Worker       const std::string& trial_name,
468*635a8641SAndroid Build Coastguard Worker       FieldTrial::Probability total_probability,
469*635a8641SAndroid Build Coastguard Worker       const std::string& default_group_name,
470*635a8641SAndroid Build Coastguard Worker       const int year,
471*635a8641SAndroid Build Coastguard Worker       const int month,
472*635a8641SAndroid Build Coastguard Worker       const int day_of_month,
473*635a8641SAndroid Build Coastguard Worker       FieldTrial::RandomizationType randomization_type,
474*635a8641SAndroid Build Coastguard Worker       uint32_t randomization_seed,
475*635a8641SAndroid Build Coastguard Worker       int* default_group_number,
476*635a8641SAndroid Build Coastguard Worker       const FieldTrial::EntropyProvider* override_entropy_provider);
477*635a8641SAndroid Build Coastguard Worker 
478*635a8641SAndroid Build Coastguard Worker   // The Find() method can be used to test to see if a named trial was already
479*635a8641SAndroid Build Coastguard Worker   // registered, or to retrieve a pointer to it from the global map.
480*635a8641SAndroid Build Coastguard Worker   static FieldTrial* Find(const std::string& trial_name);
481*635a8641SAndroid Build Coastguard Worker 
482*635a8641SAndroid Build Coastguard Worker   // Returns the group number chosen for the named trial, or
483*635a8641SAndroid Build Coastguard Worker   // FieldTrial::kNotFinalized if the trial does not exist.
484*635a8641SAndroid Build Coastguard Worker   static int FindValue(const std::string& trial_name);
485*635a8641SAndroid Build Coastguard Worker 
486*635a8641SAndroid Build Coastguard Worker   // Returns the group name chosen for the named trial, or the empty string if
487*635a8641SAndroid Build Coastguard Worker   // the trial does not exist. The first call of this function on a given field
488*635a8641SAndroid Build Coastguard Worker   // trial will mark it as active, so that its state will be reported with usage
489*635a8641SAndroid Build Coastguard Worker   // metrics, crashes, etc.
490*635a8641SAndroid Build Coastguard Worker   static std::string FindFullName(const std::string& trial_name);
491*635a8641SAndroid Build Coastguard Worker 
492*635a8641SAndroid Build Coastguard Worker   // Returns true if the named trial has been registered.
493*635a8641SAndroid Build Coastguard Worker   static bool TrialExists(const std::string& trial_name);
494*635a8641SAndroid Build Coastguard Worker 
495*635a8641SAndroid Build Coastguard Worker   // Returns true if the named trial exists and has been activated.
496*635a8641SAndroid Build Coastguard Worker   static bool IsTrialActive(const std::string& trial_name);
497*635a8641SAndroid Build Coastguard Worker 
498*635a8641SAndroid Build Coastguard Worker   // Creates a persistent representation of active FieldTrial instances for
499*635a8641SAndroid Build Coastguard Worker   // resurrection in another process. This allows randomization to be done in
500*635a8641SAndroid Build Coastguard Worker   // one process, and secondary processes can be synchronized on the result.
501*635a8641SAndroid Build Coastguard Worker   // The resulting string contains the name and group name pairs of all
502*635a8641SAndroid Build Coastguard Worker   // registered FieldTrials for which the group has been chosen and externally
503*635a8641SAndroid Build Coastguard Worker   // observed (via |group()|) and which have not been disabled, with "/" used
504*635a8641SAndroid Build Coastguard Worker   // to separate all names and to terminate the string. This string is parsed
505*635a8641SAndroid Build Coastguard Worker   // by |CreateTrialsFromString()|.
506*635a8641SAndroid Build Coastguard Worker   static void StatesToString(std::string* output);
507*635a8641SAndroid Build Coastguard Worker 
508*635a8641SAndroid Build Coastguard Worker   // Creates a persistent representation of all FieldTrial instances for
509*635a8641SAndroid Build Coastguard Worker   // resurrection in another process. This allows randomization to be done in
510*635a8641SAndroid Build Coastguard Worker   // one process, and secondary processes can be synchronized on the result.
511*635a8641SAndroid Build Coastguard Worker   // The resulting string contains the name and group name pairs of all
512*635a8641SAndroid Build Coastguard Worker   // registered FieldTrials including disabled based on |include_expired|,
513*635a8641SAndroid Build Coastguard Worker   // with "/" used to separate all names and to terminate the string. All
514*635a8641SAndroid Build Coastguard Worker   // activated trials have their name prefixed with "*". This string is parsed
515*635a8641SAndroid Build Coastguard Worker   // by |CreateTrialsFromString()|.
516*635a8641SAndroid Build Coastguard Worker   static void AllStatesToString(std::string* output, bool include_expired);
517*635a8641SAndroid Build Coastguard Worker 
518*635a8641SAndroid Build Coastguard Worker   // Creates a persistent representation of all FieldTrial params for
519*635a8641SAndroid Build Coastguard Worker   // resurrection in another process. The returned string contains the trial
520*635a8641SAndroid Build Coastguard Worker   // name and group name pairs of all registered FieldTrials including disabled
521*635a8641SAndroid Build Coastguard Worker   // based on |include_expired| separated by '.'. The pair is followed by ':'
522*635a8641SAndroid Build Coastguard Worker   // separator and list of param name and values separated by '/'. It also takes
523*635a8641SAndroid Build Coastguard Worker   // |encode_data_func| function pointer for encodeing special charactors.
524*635a8641SAndroid Build Coastguard Worker   // This string is parsed by |AssociateParamsFromString()|.
525*635a8641SAndroid Build Coastguard Worker   static std::string AllParamsToString(bool include_expired,
526*635a8641SAndroid Build Coastguard Worker                                        EscapeDataFunc encode_data_func);
527*635a8641SAndroid Build Coastguard Worker 
528*635a8641SAndroid Build Coastguard Worker   // Fills in the supplied vector |active_groups| (which must be empty when
529*635a8641SAndroid Build Coastguard Worker   // called) with a snapshot of all registered FieldTrials for which the group
530*635a8641SAndroid Build Coastguard Worker   // has been chosen and externally observed (via |group()|) and which have
531*635a8641SAndroid Build Coastguard Worker   // not been disabled.
532*635a8641SAndroid Build Coastguard Worker   static void GetActiveFieldTrialGroups(
533*635a8641SAndroid Build Coastguard Worker       FieldTrial::ActiveGroups* active_groups);
534*635a8641SAndroid Build Coastguard Worker 
535*635a8641SAndroid Build Coastguard Worker   // Returns the field trials that are marked active in |trials_string|.
536*635a8641SAndroid Build Coastguard Worker   static void GetActiveFieldTrialGroupsFromString(
537*635a8641SAndroid Build Coastguard Worker       const std::string& trials_string,
538*635a8641SAndroid Build Coastguard Worker       FieldTrial::ActiveGroups* active_groups);
539*635a8641SAndroid Build Coastguard Worker 
540*635a8641SAndroid Build Coastguard Worker   // Returns the field trials that were active when the process was
541*635a8641SAndroid Build Coastguard Worker   // created. Either parses the field trial string or the shared memory
542*635a8641SAndroid Build Coastguard Worker   // holding field trial information.
543*635a8641SAndroid Build Coastguard Worker   // Must be called only after a call to CreateTrialsFromCommandLine().
544*635a8641SAndroid Build Coastguard Worker   static void GetInitiallyActiveFieldTrials(
545*635a8641SAndroid Build Coastguard Worker       const base::CommandLine& command_line,
546*635a8641SAndroid Build Coastguard Worker       FieldTrial::ActiveGroups* active_groups);
547*635a8641SAndroid Build Coastguard Worker 
548*635a8641SAndroid Build Coastguard Worker   // Use a state string (re: StatesToString()) to augment the current list of
549*635a8641SAndroid Build Coastguard Worker   // field trials to include the supplied trials, and using a 100% probability
550*635a8641SAndroid Build Coastguard Worker   // for each trial, force them to have the same group string. This is commonly
551*635a8641SAndroid Build Coastguard Worker   // used in a non-browser process, to carry randomly selected state in a
552*635a8641SAndroid Build Coastguard Worker   // browser process into this non-browser process, but could also be invoked
553*635a8641SAndroid Build Coastguard Worker   // through a command line argument to the browser process. Created field
554*635a8641SAndroid Build Coastguard Worker   // trials will be marked "used" for the purposes of active trial reporting
555*635a8641SAndroid Build Coastguard Worker   // if they are prefixed with |kActivationMarker|. Trial names in
556*635a8641SAndroid Build Coastguard Worker   // |ignored_trial_names| are ignored when parsing |trials_string|.
557*635a8641SAndroid Build Coastguard Worker   static bool CreateTrialsFromString(
558*635a8641SAndroid Build Coastguard Worker       const std::string& trials_string,
559*635a8641SAndroid Build Coastguard Worker       const std::set<std::string>& ignored_trial_names);
560*635a8641SAndroid Build Coastguard Worker 
561*635a8641SAndroid Build Coastguard Worker   // Achieves the same thing as CreateTrialsFromString, except wraps the logic
562*635a8641SAndroid Build Coastguard Worker   // by taking in the trials from the command line, either via shared memory
563*635a8641SAndroid Build Coastguard Worker   // handle or command line argument. A bit of a misnomer since on POSIX we
564*635a8641SAndroid Build Coastguard Worker   // simply get the trials from opening |fd_key| if using shared memory. On
565*635a8641SAndroid Build Coastguard Worker   // Windows, we expect the |cmd_line| switch for |field_trial_handle_switch| to
566*635a8641SAndroid Build Coastguard Worker   // contain the shared memory handle that contains the field trial allocator.
567*635a8641SAndroid Build Coastguard Worker   // We need the |field_trial_handle_switch| and |fd_key| arguments to be passed
568*635a8641SAndroid Build Coastguard Worker   // in since base/ can't depend on content/.
569*635a8641SAndroid Build Coastguard Worker   static void CreateTrialsFromCommandLine(const base::CommandLine& cmd_line,
570*635a8641SAndroid Build Coastguard Worker                                           const char* field_trial_handle_switch,
571*635a8641SAndroid Build Coastguard Worker                                           int fd_key);
572*635a8641SAndroid Build Coastguard Worker 
573*635a8641SAndroid Build Coastguard Worker   // Creates base::Feature overrides from the command line by first trying to
574*635a8641SAndroid Build Coastguard Worker   // use shared memory and then falling back to the command line if it fails.
575*635a8641SAndroid Build Coastguard Worker   static void CreateFeaturesFromCommandLine(
576*635a8641SAndroid Build Coastguard Worker       const base::CommandLine& command_line,
577*635a8641SAndroid Build Coastguard Worker       const char* enable_features_switch,
578*635a8641SAndroid Build Coastguard Worker       const char* disable_features_switch,
579*635a8641SAndroid Build Coastguard Worker       FeatureList* feature_list);
580*635a8641SAndroid Build Coastguard Worker 
581*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
582*635a8641SAndroid Build Coastguard Worker   // On Windows, we need to explicitly pass down any handles to be inherited.
583*635a8641SAndroid Build Coastguard Worker   // This function adds the shared memory handle to field trial state to the
584*635a8641SAndroid Build Coastguard Worker   // list of handles to be inherited.
585*635a8641SAndroid Build Coastguard Worker   static void AppendFieldTrialHandleIfNeeded(
586*635a8641SAndroid Build Coastguard Worker       base::HandlesToInheritVector* handles);
587*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
588*635a8641SAndroid Build Coastguard Worker   // TODO(fuchsia): Implement shared-memory configuration (crbug.com/752368).
589*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) && !defined(OS_NACL)
590*635a8641SAndroid Build Coastguard Worker   // On POSIX, we also need to explicitly pass down this file descriptor that
591*635a8641SAndroid Build Coastguard Worker   // should be shared with the child process. Returns an invalid handle if it
592*635a8641SAndroid Build Coastguard Worker   // was not initialized properly.
593*635a8641SAndroid Build Coastguard Worker   static base::SharedMemoryHandle GetFieldTrialHandle();
594*635a8641SAndroid Build Coastguard Worker #endif
595*635a8641SAndroid Build Coastguard Worker 
596*635a8641SAndroid Build Coastguard Worker   // Adds a switch to the command line containing the field trial state as a
597*635a8641SAndroid Build Coastguard Worker   // string (if not using shared memory to share field trial state), or the
598*635a8641SAndroid Build Coastguard Worker   // shared memory handle + length.
599*635a8641SAndroid Build Coastguard Worker   // Needs the |field_trial_handle_switch| argument to be passed in since base/
600*635a8641SAndroid Build Coastguard Worker   // can't depend on content/.
601*635a8641SAndroid Build Coastguard Worker   static void CopyFieldTrialStateToFlags(const char* field_trial_handle_switch,
602*635a8641SAndroid Build Coastguard Worker                                          const char* enable_features_switch,
603*635a8641SAndroid Build Coastguard Worker                                          const char* disable_features_switch,
604*635a8641SAndroid Build Coastguard Worker                                          base::CommandLine* cmd_line);
605*635a8641SAndroid Build Coastguard Worker 
606*635a8641SAndroid Build Coastguard Worker   // Create a FieldTrial with the given |name| and using 100% probability for
607*635a8641SAndroid Build Coastguard Worker   // the FieldTrial, force FieldTrial to have the same group string as
608*635a8641SAndroid Build Coastguard Worker   // |group_name|. This is commonly used in a non-browser process, to carry
609*635a8641SAndroid Build Coastguard Worker   // randomly selected state in a browser process into this non-browser process.
610*635a8641SAndroid Build Coastguard Worker   // It returns NULL if there is a FieldTrial that is already registered with
611*635a8641SAndroid Build Coastguard Worker   // the same |name| but has different finalized group string (|group_name|).
612*635a8641SAndroid Build Coastguard Worker   static FieldTrial* CreateFieldTrial(const std::string& name,
613*635a8641SAndroid Build Coastguard Worker                                       const std::string& group_name);
614*635a8641SAndroid Build Coastguard Worker 
615*635a8641SAndroid Build Coastguard Worker   // Add an observer to be notified when a field trial is irrevocably committed
616*635a8641SAndroid Build Coastguard Worker   // to being part of some specific field_group (and hence the group_name is
617*635a8641SAndroid Build Coastguard Worker   // also finalized for that field_trial). Returns false and does nothing if
618*635a8641SAndroid Build Coastguard Worker   // there is no FieldTrialList singleton.
619*635a8641SAndroid Build Coastguard Worker   static bool AddObserver(Observer* observer);
620*635a8641SAndroid Build Coastguard Worker 
621*635a8641SAndroid Build Coastguard Worker   // Remove an observer.
622*635a8641SAndroid Build Coastguard Worker   static void RemoveObserver(Observer* observer);
623*635a8641SAndroid Build Coastguard Worker 
624*635a8641SAndroid Build Coastguard Worker   // Similar to AddObserver(), but the passed observer will be notified
625*635a8641SAndroid Build Coastguard Worker   // synchronously when a field trial is activated and its group selected. It
626*635a8641SAndroid Build Coastguard Worker   // will be notified synchronously on the same thread where the activation and
627*635a8641SAndroid Build Coastguard Worker   // group selection happened. It is the responsibility of the observer to make
628*635a8641SAndroid Build Coastguard Worker   // sure that this is a safe operation and the operation must be fast, as this
629*635a8641SAndroid Build Coastguard Worker   // work is done synchronously as part of group() or related APIs. Only a
630*635a8641SAndroid Build Coastguard Worker   // single such observer is supported, exposed specifically for crash
631*635a8641SAndroid Build Coastguard Worker   // reporting. Must be called on the main thread before any other threads
632*635a8641SAndroid Build Coastguard Worker   // have been started.
633*635a8641SAndroid Build Coastguard Worker   static void SetSynchronousObserver(Observer* observer);
634*635a8641SAndroid Build Coastguard Worker 
635*635a8641SAndroid Build Coastguard Worker   // Removes the single synchronous observer.
636*635a8641SAndroid Build Coastguard Worker   static void RemoveSynchronousObserver(Observer* observer);
637*635a8641SAndroid Build Coastguard Worker 
638*635a8641SAndroid Build Coastguard Worker   // Grabs the lock if necessary and adds the field trial to the allocator. This
639*635a8641SAndroid Build Coastguard Worker   // should only be called from FinalizeGroupChoice().
640*635a8641SAndroid Build Coastguard Worker   static void OnGroupFinalized(bool is_locked, FieldTrial* field_trial);
641*635a8641SAndroid Build Coastguard Worker 
642*635a8641SAndroid Build Coastguard Worker   // Notify all observers that a group has been finalized for |field_trial|.
643*635a8641SAndroid Build Coastguard Worker   static void NotifyFieldTrialGroupSelection(FieldTrial* field_trial);
644*635a8641SAndroid Build Coastguard Worker 
645*635a8641SAndroid Build Coastguard Worker   // Return the number of active field trials.
646*635a8641SAndroid Build Coastguard Worker   static size_t GetFieldTrialCount();
647*635a8641SAndroid Build Coastguard Worker 
648*635a8641SAndroid Build Coastguard Worker   // Gets the parameters for |field_trial| from shared memory and stores them in
649*635a8641SAndroid Build Coastguard Worker   // |params|. This is only exposed for use by FieldTrialParamAssociator and
650*635a8641SAndroid Build Coastguard Worker   // shouldn't be used by anything else.
651*635a8641SAndroid Build Coastguard Worker   static bool GetParamsFromSharedMemory(
652*635a8641SAndroid Build Coastguard Worker       FieldTrial* field_trial,
653*635a8641SAndroid Build Coastguard Worker       std::map<std::string, std::string>* params);
654*635a8641SAndroid Build Coastguard Worker 
655*635a8641SAndroid Build Coastguard Worker   // Clears all the params in the allocator.
656*635a8641SAndroid Build Coastguard Worker   static void ClearParamsFromSharedMemoryForTesting();
657*635a8641SAndroid Build Coastguard Worker 
658*635a8641SAndroid Build Coastguard Worker   // Dumps field trial state to an allocator so that it can be analyzed after a
659*635a8641SAndroid Build Coastguard Worker   // crash.
660*635a8641SAndroid Build Coastguard Worker   static void DumpAllFieldTrialsToPersistentAllocator(
661*635a8641SAndroid Build Coastguard Worker       PersistentMemoryAllocator* allocator);
662*635a8641SAndroid Build Coastguard Worker 
663*635a8641SAndroid Build Coastguard Worker   // Retrieves field trial state from an allocator so that it can be analyzed
664*635a8641SAndroid Build Coastguard Worker   // after a crash. The pointers in the returned vector are into the persistent
665*635a8641SAndroid Build Coastguard Worker   // memory segment and so are only valid as long as the allocator is valid.
666*635a8641SAndroid Build Coastguard Worker   static std::vector<const FieldTrial::FieldTrialEntry*>
667*635a8641SAndroid Build Coastguard Worker   GetAllFieldTrialsFromPersistentAllocator(
668*635a8641SAndroid Build Coastguard Worker       PersistentMemoryAllocator const& allocator);
669*635a8641SAndroid Build Coastguard Worker 
670*635a8641SAndroid Build Coastguard Worker   // Returns true if a global field trial list is set. Only used for testing.
671*635a8641SAndroid Build Coastguard Worker   static bool IsGlobalSetForTesting();
672*635a8641SAndroid Build Coastguard Worker 
673*635a8641SAndroid Build Coastguard Worker  private:
674*635a8641SAndroid Build Coastguard Worker   // Allow tests to access our innards for testing purposes.
675*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, InstantiateAllocator);
676*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AddTrialsToAllocator);
677*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest,
678*635a8641SAndroid Build Coastguard Worker                            DoNotAddSimulatedFieldTrialsToAllocator);
679*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AssociateFieldTrialParams);
680*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, ClearParamsFromSharedMemory);
681*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest,
682*635a8641SAndroid Build Coastguard Worker                            SerializeSharedMemoryHandleMetadata);
683*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, CheckReadOnlySharedMemoryHandle);
684*635a8641SAndroid Build Coastguard Worker 
685*635a8641SAndroid Build Coastguard Worker   // Serialization is used to pass information about the handle to child
686*635a8641SAndroid Build Coastguard Worker   // processes. It passes a reference to the relevant OS resource, and it passes
687*635a8641SAndroid Build Coastguard Worker   // a GUID. Serialization and deserialization doesn't actually transport the
688*635a8641SAndroid Build Coastguard Worker   // underlying OS resource - that must be done by the Process launcher.
689*635a8641SAndroid Build Coastguard Worker   static std::string SerializeSharedMemoryHandleMetadata(
690*635a8641SAndroid Build Coastguard Worker       const SharedMemoryHandle& shm);
691*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) || defined(OS_FUCHSIA)
692*635a8641SAndroid Build Coastguard Worker   static SharedMemoryHandle DeserializeSharedMemoryHandleMetadata(
693*635a8641SAndroid Build Coastguard Worker       const std::string& switch_value);
694*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) && !defined(OS_NACL)
695*635a8641SAndroid Build Coastguard Worker   static SharedMemoryHandle DeserializeSharedMemoryHandleMetadata(
696*635a8641SAndroid Build Coastguard Worker       int fd,
697*635a8641SAndroid Build Coastguard Worker       const std::string& switch_value);
698*635a8641SAndroid Build Coastguard Worker #endif
699*635a8641SAndroid Build Coastguard Worker 
700*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) || defined(OS_FUCHSIA)
701*635a8641SAndroid Build Coastguard Worker   // Takes in |handle_switch| from the command line which represents the shared
702*635a8641SAndroid Build Coastguard Worker   // memory handle for field trials, parses it, and creates the field trials.
703*635a8641SAndroid Build Coastguard Worker   // Returns true on success, false on failure.
704*635a8641SAndroid Build Coastguard Worker   // |switch_value| also contains the serialized GUID.
705*635a8641SAndroid Build Coastguard Worker   static bool CreateTrialsFromSwitchValue(const std::string& switch_value);
706*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) && !defined(OS_NACL)
707*635a8641SAndroid Build Coastguard Worker   // On POSIX systems that use the zygote, we look up the correct fd that backs
708*635a8641SAndroid Build Coastguard Worker   // the shared memory segment containing the field trials by looking it up via
709*635a8641SAndroid Build Coastguard Worker   // an fd key in GlobalDescriptors. Returns true on success, false on failure.
710*635a8641SAndroid Build Coastguard Worker   // |switch_value| also contains the serialized GUID.
711*635a8641SAndroid Build Coastguard Worker   static bool CreateTrialsFromDescriptor(int fd_key,
712*635a8641SAndroid Build Coastguard Worker                                          const std::string& switch_value);
713*635a8641SAndroid Build Coastguard Worker #endif
714*635a8641SAndroid Build Coastguard Worker 
715*635a8641SAndroid Build Coastguard Worker   // Takes an unmapped SharedMemoryHandle, creates a SharedMemory object from it
716*635a8641SAndroid Build Coastguard Worker   // and maps it with the correct size.
717*635a8641SAndroid Build Coastguard Worker   static bool CreateTrialsFromSharedMemoryHandle(SharedMemoryHandle shm_handle);
718*635a8641SAndroid Build Coastguard Worker 
719*635a8641SAndroid Build Coastguard Worker   // Expects a mapped piece of shared memory |shm| that was created from the
720*635a8641SAndroid Build Coastguard Worker   // browser process's field_trial_allocator and shared via the command line.
721*635a8641SAndroid Build Coastguard Worker   // This function recreates the allocator, iterates through all the field
722*635a8641SAndroid Build Coastguard Worker   // trials in it, and creates them via CreateFieldTrial(). Returns true if
723*635a8641SAndroid Build Coastguard Worker   // successful and false otherwise.
724*635a8641SAndroid Build Coastguard Worker   static bool CreateTrialsFromSharedMemory(
725*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<base::SharedMemory> shm);
726*635a8641SAndroid Build Coastguard Worker 
727*635a8641SAndroid Build Coastguard Worker   // Instantiate the field trial allocator, add all existing field trials to it,
728*635a8641SAndroid Build Coastguard Worker   // and duplicates its handle to a read-only handle, which gets stored in
729*635a8641SAndroid Build Coastguard Worker   // |readonly_allocator_handle|.
730*635a8641SAndroid Build Coastguard Worker   static void InstantiateFieldTrialAllocatorIfNeeded();
731*635a8641SAndroid Build Coastguard Worker 
732*635a8641SAndroid Build Coastguard Worker   // Adds the field trial to the allocator. Caller must hold a lock before
733*635a8641SAndroid Build Coastguard Worker   // calling this.
734*635a8641SAndroid Build Coastguard Worker   static void AddToAllocatorWhileLocked(PersistentMemoryAllocator* allocator,
735*635a8641SAndroid Build Coastguard Worker                                         FieldTrial* field_trial);
736*635a8641SAndroid Build Coastguard Worker 
737*635a8641SAndroid Build Coastguard Worker   // Activate the corresponding field trial entry struct in shared memory.
738*635a8641SAndroid Build Coastguard Worker   static void ActivateFieldTrialEntryWhileLocked(FieldTrial* field_trial);
739*635a8641SAndroid Build Coastguard Worker 
740*635a8641SAndroid Build Coastguard Worker   // A map from FieldTrial names to the actual instances.
741*635a8641SAndroid Build Coastguard Worker   typedef std::map<std::string, FieldTrial*> RegistrationMap;
742*635a8641SAndroid Build Coastguard Worker 
743*635a8641SAndroid Build Coastguard Worker   // If one-time randomization is enabled, returns a weak pointer to the
744*635a8641SAndroid Build Coastguard Worker   // corresponding EntropyProvider. Otherwise, returns NULL.
745*635a8641SAndroid Build Coastguard Worker   static const FieldTrial::EntropyProvider*
746*635a8641SAndroid Build Coastguard Worker       GetEntropyProviderForOneTimeRandomization();
747*635a8641SAndroid Build Coastguard Worker 
748*635a8641SAndroid Build Coastguard Worker   // Helper function should be called only while holding lock_.
749*635a8641SAndroid Build Coastguard Worker   FieldTrial* PreLockedFind(const std::string& name);
750*635a8641SAndroid Build Coastguard Worker 
751*635a8641SAndroid Build Coastguard Worker   // Register() stores a pointer to the given trial in a global map.
752*635a8641SAndroid Build Coastguard Worker   // This method also AddRef's the indicated trial.
753*635a8641SAndroid Build Coastguard Worker   // This should always be called after creating a new FieldTrial instance.
754*635a8641SAndroid Build Coastguard Worker   static void Register(FieldTrial* trial);
755*635a8641SAndroid Build Coastguard Worker 
756*635a8641SAndroid Build Coastguard Worker   // Returns all the registered trials.
757*635a8641SAndroid Build Coastguard Worker   static RegistrationMap GetRegisteredTrials();
758*635a8641SAndroid Build Coastguard Worker 
759*635a8641SAndroid Build Coastguard Worker   static FieldTrialList* global_;  // The singleton of this class.
760*635a8641SAndroid Build Coastguard Worker 
761*635a8641SAndroid Build Coastguard Worker   // This will tell us if there is an attempt to register a field
762*635a8641SAndroid Build Coastguard Worker   // trial or check if one-time randomization is enabled without
763*635a8641SAndroid Build Coastguard Worker   // creating the FieldTrialList. This is not an error, unless a
764*635a8641SAndroid Build Coastguard Worker   // FieldTrialList is created after that.
765*635a8641SAndroid Build Coastguard Worker   static bool used_without_global_;
766*635a8641SAndroid Build Coastguard Worker 
767*635a8641SAndroid Build Coastguard Worker   // Lock for access to registered_ and field_trial_allocator_.
768*635a8641SAndroid Build Coastguard Worker   Lock lock_;
769*635a8641SAndroid Build Coastguard Worker   RegistrationMap registered_;
770*635a8641SAndroid Build Coastguard Worker 
771*635a8641SAndroid Build Coastguard Worker   std::map<std::string, std::string> seen_states_;
772*635a8641SAndroid Build Coastguard Worker 
773*635a8641SAndroid Build Coastguard Worker   // Entropy provider to be used for one-time randomized field trials. If NULL,
774*635a8641SAndroid Build Coastguard Worker   // one-time randomization is not supported.
775*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<const FieldTrial::EntropyProvider> entropy_provider_;
776*635a8641SAndroid Build Coastguard Worker 
777*635a8641SAndroid Build Coastguard Worker   // List of observers to be notified when a group is selected for a FieldTrial.
778*635a8641SAndroid Build Coastguard Worker   scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_;
779*635a8641SAndroid Build Coastguard Worker 
780*635a8641SAndroid Build Coastguard Worker   // Single synchronous observer to be notified when a trial group is chosen.
781*635a8641SAndroid Build Coastguard Worker   Observer* synchronous_observer_ = nullptr;
782*635a8641SAndroid Build Coastguard Worker 
783*635a8641SAndroid Build Coastguard Worker   // Allocator in shared memory containing field trial data. Used in both
784*635a8641SAndroid Build Coastguard Worker   // browser and child processes, but readonly in the child.
785*635a8641SAndroid Build Coastguard Worker   // In the future, we may want to move this to a more generic place if we want
786*635a8641SAndroid Build Coastguard Worker   // to start passing more data other than field trials.
787*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<FieldTrialAllocator> field_trial_allocator_ = nullptr;
788*635a8641SAndroid Build Coastguard Worker 
789*635a8641SAndroid Build Coastguard Worker   // Readonly copy of the handle to the allocator. Needs to be a member variable
790*635a8641SAndroid Build Coastguard Worker   // because it's needed from both CopyFieldTrialStateToFlags() and
791*635a8641SAndroid Build Coastguard Worker   // AppendFieldTrialHandleIfNeeded().
792*635a8641SAndroid Build Coastguard Worker   base::SharedMemoryHandle readonly_allocator_handle_;
793*635a8641SAndroid Build Coastguard Worker 
794*635a8641SAndroid Build Coastguard Worker   // Tracks whether CreateTrialsFromCommandLine() has been called.
795*635a8641SAndroid Build Coastguard Worker   bool create_trials_from_command_line_called_ = false;
796*635a8641SAndroid Build Coastguard Worker 
797*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(FieldTrialList);
798*635a8641SAndroid Build Coastguard Worker };
799*635a8641SAndroid Build Coastguard Worker 
800*635a8641SAndroid Build Coastguard Worker }  // namespace base
801*635a8641SAndroid Build Coastguard Worker 
802*635a8641SAndroid Build Coastguard Worker #endif  // BASE_METRICS_FIELD_TRIAL_H_
803