1 // Copyright 2014 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/metrics_service_client.h"
6
7 #include <algorithm>
8 #include <optional>
9 #include <string>
10
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "build/build_config.h"
16 #include "components/metrics/metrics_features.h"
17 #include "components/metrics/metrics_switches.h"
18 #include "components/metrics/url_constants.h"
19 #include "metrics_service_client.h"
20
21 namespace metrics {
22
23 namespace {
24
25 // The number of initial/ongoing logs to persist in the queue before logs are
26 // dropped.
27 // Note: Both the count threshold and the bytes threshold (see
28 // `kLogBytesTrimThreshold` below) must be reached for logs to be
29 // dropped/trimmed.
30 //
31 // Note that each ongoing log may be pretty large, since "initial" logs must
32 // first be sent before any ongoing logs are transmitted. "Initial" logs will
33 // not be sent if a user is offline. As a result, the current ongoing log will
34 // accumulate until the "initial" log can be transmitted. We don't want to save
35 // too many of these mega-logs (this should be capped by
36 // kLogBytesTrimThreshold).
37 //
38 // A "standard shutdown" will create a small log, including just the data that
39 // was not yet been transmitted, and that is normal (to have exactly one
40 // ongoing log at startup).
41 //
42 // Refer to //components/metrics/unsent_log_store.h for more details on when
43 // logs are dropped.
44 const base::FeatureParam<int> kInitialLogCountTrimThreshold{
45 &features::kMetricsLogTrimming, "initial_log_count_trim_threshold", 20};
46 const base::FeatureParam<int> kOngoingLogCountTrimThreshold{
47 &features::kMetricsLogTrimming, "ongoing_log_count_trim_threshold", 8};
48
49 // The number bytes of the queue to be persisted before logs are dropped. This
50 // will be applied to both log queues (initial/ongoing). This ensures that a
51 // reasonable amount of history will be stored even if there is a long series of
52 // very small logs.
53 // Note: Both the count threshold (see `kInitialLogCountTrimThreshold` and
54 // `kOngoingLogCountTrimThreshold` above) and the bytes threshold must be
55 // reached for logs to be dropped/trimmed.
56 //
57 // Refer to //components/metrics/unsent_log_store.h for more details on when
58 // logs are dropped.
59 const base::FeatureParam<int> kLogBytesTrimThreshold{
60 &features::kMetricsLogTrimming, "log_bytes_trim_threshold",
61 300 * 1024 // 300 KiB
62 };
63
64 // If an initial/ongoing metrics log upload fails, and the transmission is over
65 // this byte count, then we will discard the log, and not try to retransmit it.
66 // We also don't persist the log to the prefs for transmission during the next
67 // chrome session if this limit is exceeded.
68 const base::FeatureParam<int> kMaxInitialLogSizeBytes{
69 &features::kMetricsLogTrimming, "max_initial_log_size_bytes",
70 0 // Initial logs can be of any size.
71 };
72 const base::FeatureParam<int> kMaxOngoingLogSizeBytes{
73 &features::kMetricsLogTrimming, "max_ongoing_log_size_bytes",
74 #if BUILDFLAG(IS_CHROMEOS)
75 // Increase CrOS limit to accommodate SampledProfile data (crbug/1210595).
76 1024 * 1024 // 1 MiB
77 #else
78 100 * 1024 // 100 KiB
79 #endif // BUILDFLAG(IS_CHROMEOS)
80 };
81
82 // The minimum time in seconds between consecutive metrics report uploads.
83 constexpr int kMetricsUploadIntervalSecMinimum = 20;
84
85 } // namespace
86
87 MetricsServiceClient::MetricsServiceClient() = default;
88
89 MetricsServiceClient::~MetricsServiceClient() = default;
90
GetUkmService()91 ukm::UkmService* MetricsServiceClient::GetUkmService() {
92 return nullptr;
93 }
94
95 IdentifiabilityStudyState*
GetIdentifiabilityStudyState()96 MetricsServiceClient::GetIdentifiabilityStudyState() {
97 return nullptr;
98 }
99
100 structured::StructuredMetricsService*
GetStructuredMetricsService()101 MetricsServiceClient::GetStructuredMetricsService() {
102 return nullptr;
103 }
104
ShouldUploadMetricsForUserId(uint64_t user_id)105 bool MetricsServiceClient::ShouldUploadMetricsForUserId(uint64_t user_id) {
106 return true;
107 }
108
GetMetricsServerUrl()109 GURL MetricsServiceClient::GetMetricsServerUrl() {
110 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
111 if (command_line->HasSwitch(switches::kUmaServerUrl)) {
112 return GURL(command_line->GetSwitchValueASCII(switches::kUmaServerUrl));
113 }
114 return GURL(kNewMetricsServerUrl);
115 }
116
GetInsecureMetricsServerUrl()117 GURL MetricsServiceClient::GetInsecureMetricsServerUrl() {
118 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
119 if (command_line->HasSwitch(switches::kUmaInsecureServerUrl)) {
120 return GURL(
121 command_line->GetSwitchValueASCII(switches::kUmaInsecureServerUrl));
122 }
123 return GURL(kNewMetricsServerUrlInsecure);
124 }
125
GetUploadInterval()126 base::TimeDelta MetricsServiceClient::GetUploadInterval() {
127 const base::CommandLine* command_line =
128 base::CommandLine::ForCurrentProcess();
129 // If an upload interval is set from the command line, use that value but
130 // subject it to a minimum threshold to mitigate the risk of DDoS attack.
131 if (command_line->HasSwitch(metrics::switches::kMetricsUploadIntervalSec)) {
132 const std::string switch_value = command_line->GetSwitchValueASCII(
133 metrics::switches::kMetricsUploadIntervalSec);
134 int custom_upload_interval;
135 if (base::StringToInt(switch_value, &custom_upload_interval)) {
136 return base::Seconds(
137 std::max(custom_upload_interval, kMetricsUploadIntervalSecMinimum));
138 }
139 LOG(DFATAL) << "Malformed value for --metrics-upload-interval. "
140 << "Expected int, got: " << switch_value;
141 }
142
143 // Use a custom interval if available.
144 if (auto custom_interval = GetCustomUploadInterval();
145 custom_interval.has_value()) {
146 return *custom_interval;
147 }
148
149 return GetStandardUploadInterval();
150 }
151
GetCustomUploadInterval() const152 std::optional<base::TimeDelta> MetricsServiceClient::GetCustomUploadInterval()
153 const {
154 return std::nullopt;
155 }
156
ShouldStartUpFastForTesting() const157 bool MetricsServiceClient::ShouldStartUpFastForTesting() const {
158 return false;
159 }
160
IsReportingPolicyManaged()161 bool MetricsServiceClient::IsReportingPolicyManaged() {
162 return false;
163 }
164
GetMetricsReportingDefaultState()165 EnableMetricsDefault MetricsServiceClient::GetMetricsReportingDefaultState() {
166 return EnableMetricsDefault::DEFAULT_UNKNOWN;
167 }
168
IsOnCellularConnection()169 bool MetricsServiceClient::IsOnCellularConnection() {
170 return false;
171 }
172
IsUkmAllowedForAllProfiles()173 bool MetricsServiceClient::IsUkmAllowedForAllProfiles() {
174 return false;
175 }
176
AreNotificationListenersEnabledOnAllProfiles()177 bool MetricsServiceClient::AreNotificationListenersEnabledOnAllProfiles() {
178 return false;
179 }
180
GetAppPackageNameIfLoggable()181 std::string MetricsServiceClient::GetAppPackageNameIfLoggable() {
182 return std::string();
183 }
184
GetUploadSigningKey()185 std::string MetricsServiceClient::GetUploadSigningKey() {
186 return std::string();
187 }
188
ShouldResetClientIdsOnClonedInstall()189 bool MetricsServiceClient::ShouldResetClientIdsOnClonedInstall() {
190 return false;
191 }
192
193 base::CallbackListSubscription
AddOnClonedInstallDetectedCallback(base::OnceClosure callback)194 MetricsServiceClient::AddOnClonedInstallDetectedCallback(
195 base::OnceClosure callback) {
196 return base::CallbackListSubscription();
197 }
198
GetStorageLimits() const199 MetricsLogStore::StorageLimits MetricsServiceClient::GetStorageLimits() const {
200 return {
201 .initial_log_queue_limits =
202 UnsentLogStore::UnsentLogStoreLimits{
203 .min_log_count =
204 static_cast<size_t>(kInitialLogCountTrimThreshold.Get()),
205 .min_queue_size_bytes =
206 static_cast<size_t>(kLogBytesTrimThreshold.Get()),
207 .max_log_size_bytes =
208 static_cast<size_t>(kMaxInitialLogSizeBytes.Get()),
209 },
210 .ongoing_log_queue_limits =
211 UnsentLogStore::UnsentLogStoreLimits{
212 .min_log_count =
213 static_cast<size_t>(kOngoingLogCountTrimThreshold.Get()),
214 .min_queue_size_bytes =
215 static_cast<size_t>(kLogBytesTrimThreshold.Get()),
216 .max_log_size_bytes =
217 static_cast<size_t>(kMaxOngoingLogSizeBytes.Get()),
218 },
219 };
220 }
221
SetUpdateRunningServicesCallback(const base::RepeatingClosure & callback)222 void MetricsServiceClient::SetUpdateRunningServicesCallback(
223 const base::RepeatingClosure& callback) {
224 update_running_services_ = callback;
225 }
226
UpdateRunningServices()227 void MetricsServiceClient::UpdateRunningServices() {
228 if (update_running_services_) {
229 update_running_services_.Run();
230 }
231 }
232
IsMetricsReportingForceEnabled() const233 bool MetricsServiceClient::IsMetricsReportingForceEnabled() const {
234 return ::metrics::IsMetricsReportingForceEnabled();
235 }
236
GetCurrentUserMetricsConsent() const237 std::optional<bool> MetricsServiceClient::GetCurrentUserMetricsConsent() const {
238 return std::nullopt;
239 }
240
GetCurrentUserId() const241 std::optional<std::string> MetricsServiceClient::GetCurrentUserId() const {
242 return std::nullopt;
243 }
244
245 } // namespace metrics
246