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