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/structured/structured_metrics_provider.h"
6
7 #include <sstream>
8 #include <utility>
9
10 #include "base/logging.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "base/task/current_thread.h"
13 #include "components/metrics/structured/histogram_util.h"
14 #include "components/metrics/structured/structured_metrics_features.h"
15 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
16
17 namespace metrics::structured {
18 namespace {
19
20 using ::metrics::ChromeUserMetricsExtension;
21 using ::metrics::SystemProfileProto;
22
23 } // namespace
24
StructuredMetricsProvider(raw_ptr<StructuredMetricsRecorder> structured_metrics_recorder)25 StructuredMetricsProvider::StructuredMetricsProvider(
26 raw_ptr<StructuredMetricsRecorder> structured_metrics_recorder)
27 : StructuredMetricsProvider(base::Minutes(GetUploadCadenceMinutes()),
28 structured_metrics_recorder) {}
29
StructuredMetricsProvider(base::TimeDelta min_independent_metrics_interval,raw_ptr<StructuredMetricsRecorder> structured_metrics_recorder)30 StructuredMetricsProvider::StructuredMetricsProvider(
31 base::TimeDelta min_independent_metrics_interval,
32 raw_ptr<StructuredMetricsRecorder> structured_metrics_recorder)
33 : min_independent_metrics_interval_(min_independent_metrics_interval),
34 structured_metrics_recorder_(structured_metrics_recorder) {
35 DCHECK(structured_metrics_recorder_);
36 }
37
38 StructuredMetricsProvider::~StructuredMetricsProvider() = default;
39
Purge()40 void StructuredMetricsProvider::Purge() {
41 recorder().Purge();
42 }
43
OnRecordingEnabled()44 void StructuredMetricsProvider::OnRecordingEnabled() {
45 recording_enabled_ = true;
46 recorder().EnableRecording();
47 }
48
OnRecordingDisabled()49 void StructuredMetricsProvider::OnRecordingDisabled() {
50 recording_enabled_ = false;
51 recorder().DisableRecording();
52 }
53
ProvideCurrentSessionData(ChromeUserMetricsExtension * uma_proto)54 void StructuredMetricsProvider::ProvideCurrentSessionData(
55 ChromeUserMetricsExtension* uma_proto) {
56 DCHECK(base::CurrentUIThread::IsSet());
57 // When StructuredMetricsService is enabled then the StructuredMetricsProvider
58 // will not upload metrics.
59 if (base::FeatureList::IsEnabled(kEnabledStructuredMetricsService)) {
60 return;
61 }
62 recorder().ProvideUmaEventMetrics(*uma_proto);
63 }
64
HasIndependentMetrics()65 bool StructuredMetricsProvider::HasIndependentMetrics() {
66 // If the StructuredMetricsService is enabled then we should not upload using
67 // |this|. When enabled this function will always return false, resulting in
68 // ProviderIndependentMetrics never being called.
69 if (base::FeatureList::IsEnabled(kEnabledStructuredMetricsService)) {
70 return false;
71 }
72
73 if (!IsIndependentMetricsUploadEnabled()) {
74 return false;
75 }
76
77 if (!recorder().CanProvideMetrics()) {
78 return false;
79 }
80
81 if (base::Time::Now() - last_provided_independent_metrics_ <
82 min_independent_metrics_interval_) {
83 return false;
84 }
85
86 return recorder().event_storage()->HasEvents();
87 }
88
ProvideIndependentMetrics(base::OnceClosure serialize_log_callback,base::OnceCallback<void (bool)> done_callback,ChromeUserMetricsExtension * uma_proto,base::HistogramSnapshotManager *)89 void StructuredMetricsProvider::ProvideIndependentMetrics(
90 base::OnceClosure serialize_log_callback,
91 base::OnceCallback<void(bool)> done_callback,
92 ChromeUserMetricsExtension* uma_proto,
93 base::HistogramSnapshotManager*) {
94 DCHECK(base::CurrentUIThread::IsSet());
95
96 // When StructuredMetricsService is enabled then the StructuredMetricsProvider
97 // will not upload metrics.
98 if (base::FeatureList::IsEnabled(kEnabledStructuredMetricsService)) {
99 NOTREACHED();
100 std::move(done_callback).Run(false);
101 return;
102 }
103
104 if (!recording_enabled_) {
105 std::move(done_callback).Run(false);
106 return;
107 }
108
109 last_provided_independent_metrics_ = base::Time::Now();
110
111 recorder().ProvideEventMetrics(*uma_proto);
112
113 // Independent events should not be associated with the client_id, so clear
114 // it.
115 uma_proto->clear_client_id();
116
117 // Do not call |serialize_log_callback| on a background thread here because
118 // ProvideEventMetrics() above has already removed the data from disk. Doing
119 // so could imply data loss, e.g. if |done_callback| is never posted back due
120 // to the user shutting down the browser (so the log is never stored).
121
122 std::move(done_callback).Run(true);
123 }
124
125 } // namespace metrics::structured
126