blob: 763a78704fa5dea8b522efa9a75701033ce47919 [file] [log] [blame]
Vincent Boisselle275215f2019-06-27 19:33:511// 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
Mikel Astiz417050a2020-10-16 06:35:505#include "components/metrics/demographics/demographic_metrics_provider.h"
Vincent Boisselle743efdb2019-07-13 16:59:036
Vincent Boisselle275215f2019-06-27 19:33:517#include "base/feature_list.h"
Vincent Boissellef2acc1a2019-10-18 01:43:518#include "base/metrics/histogram_functions.h"
Vincent Boisselle30da39772019-07-24 18:55:479#include "base/optional.h"
Mikel Astizf9d22bc2020-10-30 07:59:4510#include "components/sync/driver/sync_service_utils.h"
Vincent Boissellef2acc1a2019-10-18 01:43:5111#include "third_party/metrics_proto/ukm/report.pb.h"
Vincent Boisselle275215f2019-06-27 19:33:5112
13namespace metrics {
14
Mikel Astizf9d22bc2020-10-30 07:59:4515namespace {
16
17bool CanUploadDemographicsToGoogle(syncer::SyncService* sync_service) {
18 DCHECK(sync_service);
19
20 // Require that the user has opted into sync the feature, without just relying
21 // on PRIORITY_PREFERENCES start sync-ing.
22 if (!sync_service->IsSyncFeatureEnabled()) {
23 return false;
24 }
25
26 switch (GetUploadToGoogleState(sync_service, syncer::PRIORITY_PREFERENCES)) {
27 case syncer::UploadState::NOT_ACTIVE:
28 return false;
29 case syncer::UploadState::INITIALIZING:
30 // Note that INITIALIZING is considered good enough, because sync is known
31 // to be enabled, and transient errors don't really matter here.
32 case syncer::UploadState::ACTIVE:
33 return true;
34 }
35}
36
37} // namespace
38
Vincent Boisselle30da39772019-07-24 18:55:4739// static
40const base::Feature DemographicMetricsProvider::kDemographicMetricsReporting = {
Caitlin Fischer53c61a4e2020-04-17 19:18:3141 "DemographicMetricsReporting", base::FEATURE_ENABLED_BY_DEFAULT};
Vincent Boisselle743efdb2019-07-13 16:59:0342
43DemographicMetricsProvider::DemographicMetricsProvider(
Vincent Boissellef2acc1a2019-10-18 01:43:5144 std::unique_ptr<ProfileClient> profile_client,
45 MetricsLogUploader::MetricServiceType metrics_service_type)
46 : profile_client_(std::move(profile_client)),
47 metrics_service_type_(metrics_service_type) {
Vincent Boisselle30da39772019-07-24 18:55:4748 DCHECK(profile_client_);
Vincent Boisselle743efdb2019-07-13 16:59:0349}
50
Vincent Boisselle30da39772019-07-24 18:55:4751DemographicMetricsProvider::~DemographicMetricsProvider() {}
52
Mikel Astizf4226912020-10-19 19:10:3753base::Optional<UserDemographics>
Vincent Boissellef2acc1a2019-10-18 01:43:5154DemographicMetricsProvider::ProvideSyncedUserNoisedBirthYearAndGender() {
Vincent Boisselle743efdb2019-07-13 16:59:0355 // Skip if feature disabled.
56 if (!base::FeatureList::IsEnabled(kDemographicMetricsReporting))
Vincent Boissellef2acc1a2019-10-18 01:43:5157 return base::nullopt;
Vincent Boisselle743efdb2019-07-13 16:59:0358
Vincent Boisselle30da39772019-07-24 18:55:4759 // Skip if not exactly one Profile on disk. Having more than one Profile that
60 // is using the browser can make demographics less relevant. This approach
61 // cannot determine if there is more than 1 distinct user using the Profile.
Vincent Boisselle7577df02019-08-01 19:07:0462 if (profile_client_->GetNumberOfProfilesOnDisk() != 1) {
Vincent Boissellef2acc1a2019-10-18 01:43:5163 LogUserDemographicsStatusInHistogram(
Mikel Astizf4226912020-10-19 19:10:3764 UserDemographicsStatus::kMoreThanOneProfile);
Vincent Boissellef2acc1a2019-10-18 01:43:5165 return base::nullopt;
Vincent Boisselle7577df02019-08-01 19:07:0466 }
Vincent Boisselle743efdb2019-07-13 16:59:0367
Vincent Boisselle30da39772019-07-24 18:55:4768 syncer::SyncService* sync_service = profile_client_->GetSyncService();
69 // Skip if no sync service.
Vincent Boisselle7577df02019-08-01 19:07:0470 if (!sync_service) {
Vincent Boissellef2acc1a2019-10-18 01:43:5171 LogUserDemographicsStatusInHistogram(
Mikel Astizf4226912020-10-19 19:10:3772 UserDemographicsStatus::kNoSyncService);
Vincent Boissellef2acc1a2019-10-18 01:43:5173 return base::nullopt;
Vincent Boisselle7577df02019-08-01 19:07:0474 }
Vincent Boisselle30da39772019-07-24 18:55:4775
Mikel Astizf9d22bc2020-10-30 07:59:4576 if (!CanUploadDemographicsToGoogle(sync_service)) {
Mikel Astizf4226912020-10-19 19:10:3777 LogUserDemographicsStatusInHistogram(
78 UserDemographicsStatus::kSyncNotEnabled);
79 return base::nullopt;
80 }
81
82 UserDemographicsResult demographics_result =
83 GetUserNoisedBirthYearAndGenderFromPrefs(
84 profile_client_->GetNetworkTime(), profile_client_->GetPrefService());
Vincent Boissellef2acc1a2019-10-18 01:43:5185 LogUserDemographicsStatusInHistogram(demographics_result.status());
86
87 if (demographics_result.IsSuccess())
88 return demographics_result.value();
89
90 return base::nullopt;
91}
92
93void DemographicMetricsProvider::ProvideCurrentSessionData(
94 ChromeUserMetricsExtension* uma_proto) {
95 ProvideSyncedUserNoisedBirthYearAndGender(uma_proto);
96}
97
98void DemographicMetricsProvider::
99 ProvideSyncedUserNoisedBirthYearAndGenderToReport(ukm::Report* report) {
100 ProvideSyncedUserNoisedBirthYearAndGender(report);
101}
102
103void DemographicMetricsProvider::LogUserDemographicsStatusInHistogram(
Mikel Astizf4226912020-10-19 19:10:37104 UserDemographicsStatus status) {
Vincent Boissellef2acc1a2019-10-18 01:43:51105 switch (metrics_service_type_) {
106 case MetricsLogUploader::MetricServiceType::UMA:
107 base::UmaHistogramEnumeration("UMA.UserDemographics.Status", status);
108 return;
109 case MetricsLogUploader::MetricServiceType::UKM:
110 base::UmaHistogramEnumeration("UKM.UserDemographics.Status", status);
111 return;
Vincent Boisselle30da39772019-07-24 18:55:47112 }
Vincent Boissellef2acc1a2019-10-18 01:43:51113 NOTREACHED();
Vincent Boisselle30da39772019-07-24 18:55:47114}
Vincent Boisselle275215f2019-06-27 19:33:51115
116} // namespace metrics