xref: /aosp_15_r20/external/cronet/components/metrics/demographics/demographic_metrics_provider.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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_DEMOGRAPHIC_METRICS_PROVIDER_H_
6 #define COMPONENTS_METRICS_DEMOGRAPHICS_DEMOGRAPHIC_METRICS_PROVIDER_H_
7 
8 #include <memory>
9 #include <optional>
10 
11 #include "base/feature_list.h"
12 #include "base/time/time.h"
13 #include "components/metrics/demographics/user_demographics.h"
14 #include "components/metrics/metrics_log_uploader.h"
15 #include "components/metrics/metrics_provider.h"
16 #include "components/metrics/ukm_demographic_metrics_provider.h"
17 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
18 #include "third_party/metrics_proto/user_demographics.pb.h"
19 
20 class PrefService;
21 
22 namespace syncer {
23 class SyncService;
24 }
25 
26 namespace metrics {
27 
28 // Feature switch to report user's noised birth year and gender.
29 BASE_DECLARE_FEATURE(kDemographicMetricsReporting);
30 
31 // Provider of the synced user’s noised birth year and gender to the UMA metrics
32 // server. The synced user's birth year and gender were provided to Google when
33 // the user created their Google account, to use in accordance with Google's
34 // privacy policy. The provided birth year and gender are used in aggregate and
35 // anonymized form to measure usage of Chrome features by age groups and gender
36 // - helping Chrome ensure features are useful to a wide range of users. Users
37 // can avoid aggregation of usage data by birth year and gender by either a)
38 // turning off sending usage statistics to Google or b) turning off sync.
39 class DemographicMetricsProvider : public MetricsProvider,
40                                    public UkmDemographicMetricsProvider {
41  public:
42   // Interface that represents the client that retrieves Profile information.
43   class ProfileClient {
44    public:
45     virtual ~ProfileClient() = default;
46 
47     // Gets the total number of profiles that are on disk (loaded + not loaded)
48     // for the browser.
49     virtual int GetNumberOfProfilesOnDisk() = 0;
50 
51     // Gets a pointer to the SyncService of the profile, which is required to
52     // determine whether priority preferences carrying demographics information
53     // is being synced.
54     virtual syncer::SyncService* GetSyncService() = 0;
55 
56     // Gets a pointer to the PrefService for the Local State of the device.
57     virtual PrefService* GetLocalState() = 0;
58 
59     // Gets a pointer to the PrefService of the user profile.
60     virtual PrefService* GetProfilePrefs() = 0;
61 
62     // Gets the network time that represents now.
63     // TODO(crbug/1145655): Remove this function and replace with
64     // base::Time::Now().
65     virtual base::Time GetNetworkTime() const = 0;
66   };
67 
68   DemographicMetricsProvider(
69       std::unique_ptr<ProfileClient> profile_client,
70       MetricsLogUploader::MetricServiceType metrics_service_type);
71 
72   DemographicMetricsProvider(const DemographicMetricsProvider&) = delete;
73   DemographicMetricsProvider& operator=(const DemographicMetricsProvider&) =
74       delete;
75 
76   ~DemographicMetricsProvider() override;
77 
78   // Provides the synced user's noised birth year and gender to a metrics report
79   // of type ReportType. This function is templated to support any type of proto
80   // metrics report, e.g., ukm::Report and metrics::ChromeUserMetricsExtension.
81   // The ReportType should be a proto message class that has a
82   // metrics::UserDemographicsProto message field.
83   template <class ReportType>
ProvideSyncedUserNoisedBirthYearAndGender(ReportType * report)84   void ProvideSyncedUserNoisedBirthYearAndGender(ReportType* report) {
85     DCHECK(report);
86 
87     std::optional<UserDemographics> user_demographics =
88         ProvideSyncedUserNoisedBirthYearAndGender();
89     if (user_demographics.has_value()) {
90       report->mutable_user_demographics()->set_birth_year(
91           user_demographics.value().birth_year);
92       report->mutable_user_demographics()->set_gender(
93           user_demographics.value().gender);
94     }
95   }
96 
97   // MetricsProvider:
98   void ProvideCurrentSessionData(
99       ChromeUserMetricsExtension* uma_proto) override;
100 
101   // UkmDemographicMetricsProvider:
102   void ProvideSyncedUserNoisedBirthYearAndGenderToReport(
103       ukm::Report* report) override;
104 
105  private:
106   // Provides the synced user's noised birth year and gender.
107   std::optional<UserDemographics> ProvideSyncedUserNoisedBirthYearAndGender();
108 
109   void LogUserDemographicsStatusInHistogram(UserDemographicsStatus status);
110 
111   std::unique_ptr<ProfileClient> profile_client_;
112 
113   // The type of the metrics service for which to emit the user demographics
114   // status histogram (e.g., UMA).
115   const MetricsLogUploader::MetricServiceType metrics_service_type_;
116 };
117 
118 }  // namespace metrics
119 
120 #endif  // COMPONENTS_METRICS_DEMOGRAPHICS_DEMOGRAPHIC_METRICS_PROVIDER_H_
121