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