xref: /aosp_15_r20/external/cronet/components/metrics/entropy_state.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef COMPONENTS_METRICS_ENTROPY_STATE_H_
6*6777b538SAndroid Build Coastguard Worker #define COMPONENTS_METRICS_ENTROPY_STATE_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
12*6777b538SAndroid Build Coastguard Worker #include "components/prefs/pref_registry_simple.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker class PrefService;
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace metrics {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker // A class to get entropy source values from the PrefService.
19*6777b538SAndroid Build Coastguard Worker class EntropyState final {
20*6777b538SAndroid Build Coastguard Worker  public:
21*6777b538SAndroid Build Coastguard Worker   // Creates the EntropyState with the given |local_state| to get
22*6777b538SAndroid Build Coastguard Worker   // the entropy source value from this helper class.
23*6777b538SAndroid Build Coastguard Worker   explicit EntropyState(PrefService* local_state);
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker   EntropyState(const EntropyState&) = delete;
26*6777b538SAndroid Build Coastguard Worker   EntropyState& operator=(const EntropyState&) = delete;
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker   // Clears low_entropy_source and old_low_entropy_source in the prefs.
29*6777b538SAndroid Build Coastguard Worker   static void ClearPrefs(PrefService* local_state);
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker   // Registers low_entropy_source and old_low_entropy_source in the prefs.
32*6777b538SAndroid Build Coastguard Worker   static void RegisterPrefs(PrefRegistrySimple* registry);
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_LACROS)
35*6777b538SAndroid Build Coastguard Worker   // Overriding the entropy source preferences with new values as given by
36*6777b538SAndroid Build Coastguard Worker   // Ash upon initialization, before the MetricsService gets created.
37*6777b538SAndroid Build Coastguard Worker   // |limited_entropy_randomization_source| will only be overridden if it's
38*6777b538SAndroid Build Coastguard Worker   // valid. See IsValidLimitedEntropyRandomizationSource().
39*6777b538SAndroid Build Coastguard Worker   static void SetExternalPrefs(
40*6777b538SAndroid Build Coastguard Worker       PrefService* local_state,
41*6777b538SAndroid Build Coastguard Worker       int low_entropy_source,
42*6777b538SAndroid Build Coastguard Worker       int old_low_entropy_source,
43*6777b538SAndroid Build Coastguard Worker       int pseudo_low_entropy_source,
44*6777b538SAndroid Build Coastguard Worker       std::string_view limited_entropy_randomization_source);
45*6777b538SAndroid Build Coastguard Worker #endif
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker   // Returns the high entropy source for this client, which is composed of a
48*6777b538SAndroid Build Coastguard Worker   // client ID and the low entropy source. This is intended to be unique for
49*6777b538SAndroid Build Coastguard Worker   // each install. |initial_client_id| is the client_id that was used to
50*6777b538SAndroid Build Coastguard Worker   // randomize field trials and must not be empty.
51*6777b538SAndroid Build Coastguard Worker   std::string GetHighEntropySource(const std::string& initial_client_id);
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   // Returns the low entropy source that is used to randomize field trials on
54*6777b538SAndroid Build Coastguard Worker   // startup for this client. Generates a new value if there is none. See the
55*6777b538SAndroid Build Coastguard Worker   // |low_entropy_source_| comment for more info.
56*6777b538SAndroid Build Coastguard Worker   int GetLowEntropySource();
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker   // Returns the pseudo low entropy source for this client. Generates a new
59*6777b538SAndroid Build Coastguard Worker   // value if there is none. See the |pseudo_low_entropy_source_| comment
60*6777b538SAndroid Build Coastguard Worker   // for more info.
61*6777b538SAndroid Build Coastguard Worker   int GetPseudoLowEntropySource();
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   // Returns the old low entropy source for this client. Does not generate a new
64*6777b538SAndroid Build Coastguard Worker   // value, but instead returns |kLowEntropySourceNotSet|, if there is none. See
65*6777b538SAndroid Build Coastguard Worker   // the |old_low_entropy_source_| comment for more info.
66*6777b538SAndroid Build Coastguard Worker   int GetOldLowEntropySource();
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   // Returns the limited entropy randomization source that is used to randomize
69*6777b538SAndroid Build Coastguard Worker   // field trials in a limited entropy layer. Generates a new value if there is
70*6777b538SAndroid Build Coastguard Worker   // none. See the |limited_entropy_randomization_source_| comment for more
71*6777b538SAndroid Build Coastguard Worker   // info.
72*6777b538SAndroid Build Coastguard Worker   std::string_view GetLimitedEntropyRandomizationSource();
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   // The argument used to generate a non-identifying entropy source. We want no
75*6777b538SAndroid Build Coastguard Worker   // more than 13 bits of entropy, so use this max to return a number in the
76*6777b538SAndroid Build Coastguard Worker   // range [0, 7999] as the entropy source (12.97 bits of entropy).
77*6777b538SAndroid Build Coastguard Worker   //
78*6777b538SAndroid Build Coastguard Worker   // The value should be kept consistent with
79*6777b538SAndroid Build Coastguard Worker   // LowEntropySource.MAX_LOW_ENTROPY_SIZE in Java.
80*6777b538SAndroid Build Coastguard Worker   static constexpr int kMaxLowEntropySize = 8000;
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker  private:
83*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, LowEntropySourceNotReset);
84*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, PseudoLowEntropySourceNotReset);
85*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, HaveNoLowEntropySource);
86*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, HaveOnlyNewLowEntropySource);
87*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, HaveOnlyOldLowEntropySource);
88*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, CorruptNewLowEntropySources);
89*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest, CorruptOldLowEntropySources);
90*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest,
91*6777b538SAndroid Build Coastguard Worker                            ValidLimitedEntropyRandomizationSource);
92*6777b538SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(EntropyStateTest,
93*6777b538SAndroid Build Coastguard Worker                            InvalidLimitedEntropyRandomizationSource);
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker   // Default value for prefs::kMetricsLowEntropySource.
96*6777b538SAndroid Build Coastguard Worker   static constexpr int kLowEntropySourceNotSet = -1;
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   // Loads the low entropy source values from prefs. Creates the new source
99*6777b538SAndroid Build Coastguard Worker   // value if it doesn't exist, but doesn't create the old source value. After
100*6777b538SAndroid Build Coastguard Worker   // this function finishes, |low_entropy_source_| will be set, but
101*6777b538SAndroid Build Coastguard Worker   // |old_low_entropy_source_| may still be |kLowEntropySourceNotSet|.
102*6777b538SAndroid Build Coastguard Worker   void UpdateLowEntropySources();
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker   // Returns the limited entropy randomization source value if one is already
105*6777b538SAndroid Build Coastguard Worker   // set. Otherwise, attempts to generate a new one either when there isn't a
106*6777b538SAndroid Build Coastguard Worker   // previously set one stored in prefs, or when the command line flag
107*6777b538SAndroid Build Coastguard Worker   // --reset-variation-state is set. In both cases, the newly generated value
108*6777b538SAndroid Build Coastguard Worker   // will be set and stored stored in prefs before returning.
109*6777b538SAndroid Build Coastguard Worker   void UpdateLimitedEntropyRandomizationSource();
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   // Checks whether a value is on the range of allowed low entropy source
112*6777b538SAndroid Build Coastguard Worker   // values.
113*6777b538SAndroid Build Coastguard Worker   static bool IsValidLowEntropySource(int value);
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   // Checks whether the given value is a valid limited entropy randomization
116*6777b538SAndroid Build Coastguard Worker   // source.
117*6777b538SAndroid Build Coastguard Worker   static bool IsValidLimitedEntropyRandomizationSource(std::string_view value);
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // Generates a new limited entropy randomization source.
120*6777b538SAndroid Build Coastguard Worker   std::string GenerateLimitedEntropyRandomizationSource();
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   // The local state prefs store.
123*6777b538SAndroid Build Coastguard Worker   const raw_ptr<PrefService> local_state_;
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   // The non-identifying low entropy source values. These values seed the
126*6777b538SAndroid Build Coastguard Worker   // pseudorandom generators which pick experimental groups. The "old" value is
127*6777b538SAndroid Build Coastguard Worker   // thought to be biased in the wild, and is no longer used for experiments
128*6777b538SAndroid Build Coastguard Worker   // requiring low entropy. Clients which already have an "old" value continue
129*6777b538SAndroid Build Coastguard Worker   // incorporating it into the high entropy source, to avoid changing those
130*6777b538SAndroid Build Coastguard Worker   // group assignments. New clients only have the new source.
131*6777b538SAndroid Build Coastguard Worker   //
132*6777b538SAndroid Build Coastguard Worker   // The pseudo-low entropy source is not used for experiment diversion, but
133*6777b538SAndroid Build Coastguard Worker   // only for statistical validation. (Since it's not used for experiment
134*6777b538SAndroid Build Coastguard Worker   // diversion, it won't be subject to drift over time as experiment effects
135*6777b538SAndroid Build Coastguard Worker   // accumulate in actual low entropy source buckets.)
136*6777b538SAndroid Build Coastguard Worker   //
137*6777b538SAndroid Build Coastguard Worker   // During startup these are set to the values used for randomizing field
138*6777b538SAndroid Build Coastguard Worker   // trials and won't be changed within the session even after calling
139*6777b538SAndroid Build Coastguard Worker   // |ClearPrefs|.
140*6777b538SAndroid Build Coastguard Worker   int low_entropy_source_ = kLowEntropySourceNotSet;
141*6777b538SAndroid Build Coastguard Worker   int old_low_entropy_source_ = kLowEntropySourceNotSet;
142*6777b538SAndroid Build Coastguard Worker   int pseudo_low_entropy_source_ = kLowEntropySourceNotSet;
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker   // This value is used to seed the randomization for field trials in the
145*6777b538SAndroid Build Coastguard Worker   // limited entropy layer. During startup this value is set to one that's
146*6777b538SAndroid Build Coastguard Worker   // previously set. If a previously set value is not available, it will
147*6777b538SAndroid Build Coastguard Worker   // generate a new one. See more in the comments of
148*6777b538SAndroid Build Coastguard Worker   // |UpdateLimitedEntropyRandomizationSource|.
149*6777b538SAndroid Build Coastguard Worker   //
150*6777b538SAndroid Build Coastguard Worker   // Similar to the |low_entropy_source_| above, this value won't be changed
151*6777b538SAndroid Build Coastguard Worker   // within the session, even after calling |ClearPrefs|.
152*6777b538SAndroid Build Coastguard Worker   std::string limited_entropy_randomization_source_;
153*6777b538SAndroid Build Coastguard Worker };
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker }  // namespace metrics
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker #endif  // COMPONENTS_METRICS_ENTROPY_STATE_H_
158