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