Vincent Boisselle | 275215f | 2019-06-27 19:33:51 | [diff] [blame] | 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 | |
Mikel Astiz | 417050a | 2020-10-16 06:35:50 | [diff] [blame] | 5 | #include "components/metrics/demographics/demographic_metrics_provider.h" |
Vincent Boisselle | 743efdb | 2019-07-13 16:59:03 | [diff] [blame] | 6 | |
Vincent Boisselle | 275215f | 2019-06-27 19:33:51 | [diff] [blame] | 7 | #include "base/feature_list.h" |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 8 | #include "base/metrics/histogram_functions.h" |
Toby Huang | 3f2085ea | 2020-12-04 20:03:46 | [diff] [blame] | 9 | #include "build/chromeos_buildflags.h" |
Mikel Astiz | f9d22bc | 2020-10-30 07:59:45 | [diff] [blame] | 10 | #include "components/sync/driver/sync_service_utils.h" |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 11 | #include "third_party/abseil-cpp/absl/types/optional.h" |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 12 | #include "third_party/metrics_proto/ukm/report.pb.h" |
Vincent Boisselle | 275215f | 2019-06-27 19:33:51 | [diff] [blame] | 13 | |
| 14 | namespace metrics { |
| 15 | |
Mikel Astiz | f9d22bc | 2020-10-30 07:59:45 | [diff] [blame] | 16 | namespace { |
| 17 | |
| 18 | bool CanUploadDemographicsToGoogle(syncer::SyncService* sync_service) { |
| 19 | DCHECK(sync_service); |
| 20 | |
| 21 | // Require that the user has opted into sync the feature, without just relying |
| 22 | // on PRIORITY_PREFERENCES start sync-ing. |
| 23 | if (!sync_service->IsSyncFeatureEnabled()) { |
| 24 | return false; |
| 25 | } |
| 26 | |
| 27 | switch (GetUploadToGoogleState(sync_service, syncer::PRIORITY_PREFERENCES)) { |
| 28 | case syncer::UploadState::NOT_ACTIVE: |
| 29 | return false; |
| 30 | case syncer::UploadState::INITIALIZING: |
| 31 | // Note that INITIALIZING is considered good enough, because sync is known |
| 32 | // to be enabled, and transient errors don't really matter here. |
| 33 | case syncer::UploadState::ACTIVE: |
| 34 | return true; |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | } // namespace |
| 39 | |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 40 | // static |
| 41 | const base::Feature DemographicMetricsProvider::kDemographicMetricsReporting = { |
Caitlin Fischer | 53c61a4e | 2020-04-17 19:18:31 | [diff] [blame] | 42 | "DemographicMetricsReporting", base::FEATURE_ENABLED_BY_DEFAULT}; |
Vincent Boisselle | 743efdb | 2019-07-13 16:59:03 | [diff] [blame] | 43 | |
| 44 | DemographicMetricsProvider::DemographicMetricsProvider( |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 45 | std::unique_ptr<ProfileClient> profile_client, |
| 46 | MetricsLogUploader::MetricServiceType metrics_service_type) |
| 47 | : profile_client_(std::move(profile_client)), |
| 48 | metrics_service_type_(metrics_service_type) { |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 49 | DCHECK(profile_client_); |
Vincent Boisselle | 743efdb | 2019-07-13 16:59:03 | [diff] [blame] | 50 | } |
| 51 | |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 52 | DemographicMetricsProvider::~DemographicMetricsProvider() {} |
| 53 | |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 54 | absl::optional<UserDemographics> |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 55 | DemographicMetricsProvider::ProvideSyncedUserNoisedBirthYearAndGender() { |
Vincent Boisselle | 743efdb | 2019-07-13 16:59:03 | [diff] [blame] | 56 | // Skip if feature disabled. |
| 57 | if (!base::FeatureList::IsEnabled(kDemographicMetricsReporting)) |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 58 | return absl::nullopt; |
Vincent Boisselle | 743efdb | 2019-07-13 16:59:03 | [diff] [blame] | 59 | |
Toby Huang | 3f2085ea | 2020-12-04 20:03:46 | [diff] [blame] | 60 | #if !BUILDFLAG(IS_CHROMEOS_ASH) |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 61 | // Skip if not exactly one Profile on disk. Having more than one Profile that |
| 62 | // is using the browser can make demographics less relevant. This approach |
| 63 | // cannot determine if there is more than 1 distinct user using the Profile. |
Toby Huang | 3f2085ea | 2020-12-04 20:03:46 | [diff] [blame] | 64 | |
| 65 | // ChromeOS almost always has more than one profile on disk, so this check |
| 66 | // doesn't work. We have a profile selection strategy for ChromeOS, so skip |
| 67 | // this check for ChromeOS. |
| 68 | // TODO(crbug/1145655): LaCros will behave similarly to desktop Chrome and |
| 69 | // reduce the number of profiles on disk to one, so remove these #if guards |
| 70 | // after LaCros release. |
Vincent Boisselle | 7577df0 | 2019-08-01 19:07:04 | [diff] [blame] | 71 | if (profile_client_->GetNumberOfProfilesOnDisk() != 1) { |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 72 | LogUserDemographicsStatusInHistogram( |
Mikel Astiz | f422691 | 2020-10-19 19:10:37 | [diff] [blame] | 73 | UserDemographicsStatus::kMoreThanOneProfile); |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 74 | return absl::nullopt; |
Vincent Boisselle | 7577df0 | 2019-08-01 19:07:04 | [diff] [blame] | 75 | } |
Toby Huang | 3f2085ea | 2020-12-04 20:03:46 | [diff] [blame] | 76 | #endif // !BUILDFLAG(IS_CHROMEOS_ASH) |
Vincent Boisselle | 743efdb | 2019-07-13 16:59:03 | [diff] [blame] | 77 | |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 78 | syncer::SyncService* sync_service = profile_client_->GetSyncService(); |
| 79 | // Skip if no sync service. |
Vincent Boisselle | 7577df0 | 2019-08-01 19:07:04 | [diff] [blame] | 80 | if (!sync_service) { |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 81 | LogUserDemographicsStatusInHistogram( |
Mikel Astiz | f422691 | 2020-10-19 19:10:37 | [diff] [blame] | 82 | UserDemographicsStatus::kNoSyncService); |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 83 | return absl::nullopt; |
Vincent Boisselle | 7577df0 | 2019-08-01 19:07:04 | [diff] [blame] | 84 | } |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 85 | |
Mikel Astiz | f9d22bc | 2020-10-30 07:59:45 | [diff] [blame] | 86 | if (!CanUploadDemographicsToGoogle(sync_service)) { |
Mikel Astiz | f422691 | 2020-10-19 19:10:37 | [diff] [blame] | 87 | LogUserDemographicsStatusInHistogram( |
| 88 | UserDemographicsStatus::kSyncNotEnabled); |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 89 | return absl::nullopt; |
Mikel Astiz | f422691 | 2020-10-19 19:10:37 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | UserDemographicsResult demographics_result = |
| 93 | GetUserNoisedBirthYearAndGenderFromPrefs( |
| 94 | profile_client_->GetNetworkTime(), profile_client_->GetPrefService()); |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 95 | LogUserDemographicsStatusInHistogram(demographics_result.status()); |
| 96 | |
| 97 | if (demographics_result.IsSuccess()) |
| 98 | return demographics_result.value(); |
| 99 | |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame^] | 100 | return absl::nullopt; |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | void DemographicMetricsProvider::ProvideCurrentSessionData( |
| 104 | ChromeUserMetricsExtension* uma_proto) { |
| 105 | ProvideSyncedUserNoisedBirthYearAndGender(uma_proto); |
| 106 | } |
| 107 | |
| 108 | void DemographicMetricsProvider:: |
| 109 | ProvideSyncedUserNoisedBirthYearAndGenderToReport(ukm::Report* report) { |
| 110 | ProvideSyncedUserNoisedBirthYearAndGender(report); |
| 111 | } |
| 112 | |
| 113 | void DemographicMetricsProvider::LogUserDemographicsStatusInHistogram( |
Mikel Astiz | f422691 | 2020-10-19 19:10:37 | [diff] [blame] | 114 | UserDemographicsStatus status) { |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 115 | switch (metrics_service_type_) { |
| 116 | case MetricsLogUploader::MetricServiceType::UMA: |
| 117 | base::UmaHistogramEnumeration("UMA.UserDemographics.Status", status); |
Toby Huang | be62369 | 2020-12-08 22:17:14 | [diff] [blame] | 118 | // If the user demographics data was retrieved successfully, then the user |
| 119 | // must be between the ages of |kUserDemographicsMinAgeInYears|+1=21 and |
| 120 | // |kUserDemographicsMaxAgeinYears|=85, so the user is not a minor. |
| 121 | base::UmaHistogramBoolean("UMA.UserDemographics.IsNoisedAgeOver21Under85", |
| 122 | status == UserDemographicsStatus::kSuccess); |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 123 | return; |
| 124 | case MetricsLogUploader::MetricServiceType::UKM: |
| 125 | base::UmaHistogramEnumeration("UKM.UserDemographics.Status", status); |
| 126 | return; |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 127 | } |
Vincent Boisselle | f2acc1a | 2019-10-18 01:43:51 | [diff] [blame] | 128 | NOTREACHED(); |
Vincent Boisselle | 30da3977 | 2019-07-24 18:55:47 | [diff] [blame] | 129 | } |
Vincent Boisselle | 275215f | 2019-06-27 19:33:51 | [diff] [blame] | 130 | |
| 131 | } // namespace metrics |