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 #include "components/metrics/demographics/demographic_metrics_test_utils.h"
6
7 #include "base/strings/stringprintf.h"
8 #include "base/time/default_clock.h"
9 #include "base/time/default_tick_clock.h"
10 #include "components/metrics/demographics/user_demographics.h"
11 #include "components/metrics/log_decoder.h"
12 #include "components/sync/engine/loopback_server/persistent_unique_client_entity.h"
13 #include "components/sync/protocol/entity_specifics.pb.h"
14 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
15
16 namespace metrics {
17 namespace test {
18
AddUserBirthYearAndGenderToSyncServer(base::WeakPtr<fake_server::FakeServer> fake_server,int birth_year,UserDemographicsProto::Gender gender)19 void AddUserBirthYearAndGenderToSyncServer(
20 base::WeakPtr<fake_server::FakeServer> fake_server,
21 int birth_year,
22 UserDemographicsProto::Gender gender) {
23 sync_pb::EntitySpecifics specifics;
24 specifics.mutable_priority_preference()->mutable_preference()->set_name(
25 kSyncDemographicsPrefName);
26 specifics.mutable_priority_preference()->mutable_preference()->set_value(
27 base::StringPrintf("{\"birth_year\":%d,\"gender\":%d}", birth_year,
28 static_cast<int>(gender)));
29 fake_server->InjectEntity(
30 syncer::PersistentUniqueClientEntity::CreateFromSpecificsForTesting(
31 /*non_unique_name=*/kSyncDemographicsPrefName,
32 /*client_tag=*/specifics.preference().name(), specifics,
33 /*creation_time=*/0,
34 /*last_modified_time=*/0));
35 }
36
UpdateNetworkTime(const base::Time & now,network_time::NetworkTimeTracker * time_tracker)37 void UpdateNetworkTime(const base::Time& now,
38 network_time::NetworkTimeTracker* time_tracker) {
39 // Simulate the latency in the network to get the network time from the remote
40 // server.
41 constexpr base::TimeDelta kLatency = base::Milliseconds(10);
42
43 // Simulate the time taken to call UpdateNetworkTime() since the moment the
44 // callback was created. When not testing with the fake sync server, the
45 // callback is called when doing an HTTP request to the sync server.
46 constexpr base::TimeDelta kCallbackDelay = base::Milliseconds(10);
47
48 // Simulate a network time that is a bit earlier than the now time.
49 base::Time network_time = now - kCallbackDelay - kLatency;
50
51 // Simulate the time in ticks at the moment the UpdateNetworkTime callback
52 // function is created, which time should be at least 1 millisecond behind the
53 // moment the callback is run to pass the DCHECK.
54 base::TimeTicks post_time = base::TimeTicks::Now() - kCallbackDelay;
55
56 time_tracker->UpdateNetworkTime(
57 network_time, /*resolution=*/base::Milliseconds(1), kLatency, post_time);
58 }
59
GetMaximumEligibleBirthYear(const base::Time & now)60 int GetMaximumEligibleBirthYear(const base::Time& now) {
61 constexpr int kEligibleAge = kUserDemographicsMinAgeInYears +
62 kUserDemographicsBirthYearNoiseOffsetRange;
63
64 base::Time::Exploded exploded_time;
65 now.UTCExplode(&exploded_time);
66
67 // Return the maximum birth year that is eligible for reporting the user's
68 // birth year and gender. The -1 year is the extra buffer that Sync uses to
69 // make sure that the user is at least 20 years old because the user gives
70 // only the year of their birth date. E.g., if today's date is 05 Jan 2020
71 // and the user was born 05 Mar 2000, the user's age would be computed as 20
72 // years old using the year resolution, but the user is in fact 19.
73 return exploded_time.year - kEligibleAge - 1;
74 }
75
GetNoisedBirthYear(const PrefService * local_state,int raw_birth_year)76 int GetNoisedBirthYear(const PrefService* local_state, int raw_birth_year) {
77 int birth_year_offset =
78 local_state->GetInteger(kUserDemographicsBirthYearOffsetPrefName);
79 return birth_year_offset + raw_birth_year;
80 }
81
BuildAndStoreLog(MetricsService * metrics_service)82 void BuildAndStoreLog(MetricsService* metrics_service) {
83 metrics_service->StageCurrentLogForTest();
84 }
85
HasUnsentLogs(MetricsService * metrics_service)86 bool HasUnsentLogs(MetricsService* metrics_service) {
87 return metrics_service->LogStoreForTest()->has_unsent_logs();
88 }
89
90 // Returns an UMA log if the MetricsService has a staged log.
GetLastUmaLog(MetricsService * metrics_service)91 std::unique_ptr<ChromeUserMetricsExtension> GetLastUmaLog(
92 MetricsService* metrics_service) {
93 // Decompress and deserialize the staged log.
94 std::unique_ptr<ChromeUserMetricsExtension> log =
95 std::make_unique<ChromeUserMetricsExtension>();
96 if (!DecodeLogDataToProto(metrics_service->LogStoreForTest()->staged_log(),
97 log.get())) {
98 return nullptr;
99 }
100 return log;
101 }
102
103 } // namespace test
104 } // namespace metrics
105