1 // Copyright 2017 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/field_trials_provider.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/strings/string_piece.h"
11 #include "components/variations/active_field_trials.h"
12 #include "components/variations/synthetic_trial_registry.h"
13 #include "third_party/metrics_proto/system_profile.pb.h"
14
15 namespace variations {
16
17 namespace {
18
WriteFieldTrials(const std::vector<ActiveGroupId> & field_trial_ids,metrics::SystemProfileProto * system_profile)19 void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids,
20 metrics::SystemProfileProto* system_profile) {
21 for (const ActiveGroupId& id : field_trial_ids) {
22 metrics::SystemProfileProto::FieldTrial* field_trial =
23 system_profile->add_field_trial();
24 field_trial->set_name_id(id.name);
25 field_trial->set_group_id(id.group);
26 }
27 }
28
29 } // namespace
30
FieldTrialsProvider(SyntheticTrialRegistry * registry,base::StringPiece suffix)31 FieldTrialsProvider::FieldTrialsProvider(SyntheticTrialRegistry* registry,
32 base::StringPiece suffix)
33 : registry_(registry), suffix_(suffix) {}
34 FieldTrialsProvider::~FieldTrialsProvider() = default;
35
GetFieldTrialIds(std::vector<ActiveGroupId> * field_trial_ids) const36 void FieldTrialsProvider::GetFieldTrialIds(
37 std::vector<ActiveGroupId>* field_trial_ids) const {
38 // As the trial groups are included in metrics reports, we must not include
39 // the low anonymity trials.
40 variations::GetFieldTrialActiveGroupIds(suffix_, field_trial_ids);
41 }
42
ProvideSystemProfileMetrics(metrics::SystemProfileProto * system_profile_proto)43 void FieldTrialsProvider::ProvideSystemProfileMetrics(
44 metrics::SystemProfileProto* system_profile_proto) {
45 // ProvideSystemProfileMetricsWithLogCreationTime() should be called instead.
46 NOTREACHED();
47 }
48
ProvideSystemProfileMetricsWithLogCreationTime(base::TimeTicks log_creation_time,metrics::SystemProfileProto * system_profile_proto)49 void FieldTrialsProvider::ProvideSystemProfileMetricsWithLogCreationTime(
50 base::TimeTicks log_creation_time,
51 metrics::SystemProfileProto* system_profile_proto) {
52 // TODO(crbug.com/40697205): Maybe call ProvideCurrentSessionData() instead
53 // from places in which ProvideSystemProfileMetricsWithLogCreationTime() is
54 // called, e.g. startup_data.cc and background_tracing_metrics_provider.cc.
55
56 log_creation_time_ = log_creation_time;
57
58 const std::string& version = variations::GetSeedVersion();
59 if (!version.empty())
60 system_profile_proto->set_variations_seed_version(version);
61
62 // TODO(crbug.com/40133600): Determine whether this can be deleted.
63 GetAndWriteFieldTrials(system_profile_proto);
64 }
65
ProvideCurrentSessionData(metrics::ChromeUserMetricsExtension * uma_proto)66 void FieldTrialsProvider::ProvideCurrentSessionData(
67 metrics::ChromeUserMetricsExtension* uma_proto) {
68 // This function is called from both
69 // ProvideSystemProfileMetricsWithLogCreationTime() and
70 // ProvideCurrentSessionData() so that field trials activated in other metrics
71 // providers are captured. We need both calls because in some scenarios in
72 // which this class is used, only the former function gets called.
73 DCHECK(!log_creation_time_.is_null());
74 GetAndWriteFieldTrials(uma_proto->mutable_system_profile());
75 }
76
SetLogCreationTimeForTesting(base::TimeTicks time)77 void FieldTrialsProvider::SetLogCreationTimeForTesting(base::TimeTicks time) {
78 log_creation_time_ = time;
79 }
80
GetAndWriteFieldTrials(metrics::SystemProfileProto * system_profile_proto) const81 void FieldTrialsProvider::GetAndWriteFieldTrials(
82 metrics::SystemProfileProto* system_profile_proto) const {
83 system_profile_proto->clear_field_trial();
84
85 std::vector<ActiveGroupId> field_trials;
86 GetFieldTrialIds(&field_trials);
87 WriteFieldTrials(field_trials, system_profile_proto);
88
89 // May be null in tests.
90 if (registry_) {
91 std::vector<ActiveGroupId> synthetic_trials;
92 registry_->GetSyntheticFieldTrialsOlderThan(log_creation_time_,
93 &synthetic_trials, suffix_);
94 WriteFieldTrials(synthetic_trials, system_profile_proto);
95 }
96 }
97
98 } // namespace variations
99