1 // Copyright 2019 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_DEMOGRAPHICS_USER_DEMOGRAPHICS_H_ 6 #define COMPONENTS_METRICS_DEMOGRAPHICS_USER_DEMOGRAPHICS_H_ 7 8 #include "base/time/time.h" 9 #include "build/build_config.h" 10 #include "third_party/metrics_proto/user_demographics.pb.h" 11 12 class PrefService; 13 class PrefRegistrySimple; 14 15 namespace metrics { 16 17 // Default value for user gender when no value has been set. 18 constexpr int kUserDemographicsGenderDefaultValue = -1; 19 20 // Default value for user gender enum when no value has been set. 21 constexpr UserDemographicsProto_Gender kUserDemographicGenderDefaultEnumValue = 22 UserDemographicsProto_Gender_Gender_MIN; 23 24 // Default value for user birth year when no value has been set. 25 constexpr int kUserDemographicsBirthYearDefaultValue = -1; 26 27 // Default value for birth year offset when no value has been set. Set to a 28 // really high value that |kUserDemographicsBirthYearNoiseOffsetRange| will 29 // never go over. 30 constexpr int kUserDemographicsBirthYearNoiseOffsetDefaultValue = 100; 31 32 // Boundary of the +/- range in years within witch to randomly pick an offset to 33 // add to the user birth year. This adds noise to the birth year to not allow 34 // someone to accurately know a user's age. Possible offsets range from -2 to 2. 35 constexpr int kUserDemographicsBirthYearNoiseOffsetRange = 2; 36 37 // Minimal user age in years to provide demographics for. 38 constexpr int kUserDemographicsMinAgeInYears = 20; 39 40 // Max user age to provide demopgrahics for. 41 constexpr int kUserDemographicsMaxAgeInYears = 85; 42 43 // Preference names, exposed publicly for testing. 44 #if BUILDFLAG(IS_CHROMEOS_ASH) 45 extern const char kSyncOsDemographicsPrefName[]; 46 #endif 47 extern const char kSyncDemographicsPrefName[]; 48 extern const char kUserDemographicsBirthYearOffsetPrefName[]; 49 // Deprecated (2022/09) 50 extern const char kDeprecatedDemographicsBirthYearOffsetPrefName[]; 51 52 // These are not prefs, they are paths inside of kSyncDemographics. 53 extern const char kSyncDemographicsBirthYearPath[]; 54 extern const char kSyncDemographicsGenderPath[]; 55 56 // Container of user demographics. 57 struct UserDemographics { 58 int birth_year = 0; 59 UserDemographicsProto_Gender gender = UserDemographicsProto::Gender_MIN; 60 }; 61 62 // Represents the status of providing user demographics (noised birth year and 63 // gender) that are logged to UMA. Entries of the enum should not be renumbered 64 // and numeric values should never be reused. Please keep in sync with 65 // "UserDemographicsStatus" in src/tools/metrics/histograms/enums.xml. There 66 // should only be one entry representing demographic data that is ineligible to 67 // be provided. A finer grained division of kIneligibleDemographicsData (e.g., 68 // INVALID_BIRTH_YEAR) might help inferring categories of demographics that 69 // should not be exposed to protect privacy. 70 enum class UserDemographicsStatus { 71 // Could get the user's noised birth year and gender. 72 kSuccess = 0, 73 // Sync is not enabled. 74 kSyncNotEnabled = 1, 75 // User's birth year and gender are ineligible to be provided either because 76 // some of them don't exist (missing data) or some of them are not eligible to 77 // be provided. 78 kIneligibleDemographicsData = 2, 79 // Could not get the time needed to compute the user's age. 80 kCannotGetTime = 3, 81 // There is more than one Profile for the Chrome browser. This entry is used 82 // by the DemographicMetricsProvider client. 83 kMoreThanOneProfile = 4, 84 // There is no sync service available for the loaded Profile. This entry is 85 // used by the DemographicMetricsProvider client. 86 kNoSyncService = 5, 87 // Upper boundary of the enum that is needed for the histogram. 88 kMaxValue = kNoSyncService 89 }; 90 91 // Container and handler for data related to the retrieval of user demographics. 92 // Holds either valid demographics data or an error code. 93 class UserDemographicsResult { 94 public: 95 // Builds a UserDemographicsResult that contains user demographics and has a 96 // UserDemographicsStatus::kSuccess status. 97 static UserDemographicsResult ForValue(UserDemographics value); 98 99 // Builds a UserDemographicsResult that does not have user demographics (only 100 // default values) and has a status other than 101 // UserDemographicsStatus::kSuccess. 102 static UserDemographicsResult ForStatus(UserDemographicsStatus status); 103 104 // Determines whether demographics could be successfully retrieved. 105 bool IsSuccess() const; 106 107 // Gets the status of the result. 108 UserDemographicsStatus status() const; 109 110 // Gets the value of the result which will contain data when status() is 111 // UserDemographicsStatus::kSuccess. 112 const UserDemographics& value() const; 113 114 private: 115 UserDemographicsResult(UserDemographics value, UserDemographicsStatus status); 116 117 UserDemographics value_; 118 UserDemographicsStatus status_ = UserDemographicsStatus::kMaxValue; 119 }; 120 121 // Registers the local state preferences that are needed to persist demographics 122 // information exposed via GetUserNoisedBirthYearAndGenderFromPrefs(). 123 void RegisterDemographicsLocalStatePrefs(PrefRegistrySimple* registry); 124 125 // Registers the profile preferences that are needed to persist demographics 126 // information exposed via GetUserNoisedBirthYearAndGenderFromPrefs(). 127 void RegisterDemographicsProfilePrefs(PrefRegistrySimple* registry); 128 129 // Clears the profile's demographics-related preferences containing user data. 130 // This excludes the internal birth year offset. 131 void ClearDemographicsPrefs(PrefService* profile_prefs); 132 133 // Gets the synced user’s birth year and gender from |profile_prefs|, and noise 134 // from |local_state|. See docs for metrics::DemographicMetricsProvider in 135 // components/metrics/demographic_metrics_provider.h for more details. Returns 136 // an error status with an empty value when the user's birth year or gender 137 // cannot be provided. You need to provide an accurate |now| time that 138 // represents the current time. 139 UserDemographicsResult GetUserNoisedBirthYearAndGenderFromPrefs( 140 base::Time now, 141 PrefService* local_state, 142 PrefService* profile_prefs); 143 144 } // namespace metrics 145 146 #endif // COMPONENTS_METRICS_DEMOGRAPHICS_USER_DEMOGRAPHICS_H_ 147