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