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_switches.h"
16 #include "components/metrics/url_constants.h"
17
18 namespace metrics {
19 namespace {
20
21 // The minimum time in seconds between consecutive metrics report uploads.
22 constexpr int kMetricsUploadIntervalSecMinimum = 20;
23
24 // If a metrics log upload fails, and the transmission is over this byte count,
25 // then we will discard the log, and not try to retransmit it. We also don't
26 // persist the log to the prefs for transmission during the next chrome session
27 // if this limit is exceeded.
28 #if BUILDFLAG(IS_CHROMEOS)
29 // Increase CrOS limit to accommodate SampledProfile data (crbug.com/1210595).
30 constexpr size_t kMaxOngoingLogSize = 1024 * 1024; // 1 MiB
31 #else
32 constexpr size_t kMaxOngoingLogSize = 100 * 1024; // 100 KiB
33 #endif // BUILDFLAG(IS_CHROMEOS)
34
35 // The number of bytes of logs to save of each type (initial/ongoing). This
36 // ensures that a reasonable amount of history will be stored even if there is a
37 // long series of very small logs.
38 constexpr size_t kMinLogQueueSize = 300 * 1024; // 300 KiB
39
40 // The minimum number of "initial" logs to save, and hope to send during a
41 // future Chrome session. Initial logs contain crash stats, and are pretty
42 // small.
43 constexpr size_t kMinInitialLogQueueCount = 20;
44
45 // The minimum number of ongoing logs to save persistently, and hope to send
46 // during a this or future sessions. Note that each log may be pretty large, as
47 // presumably the related "initial" log wasn't sent (probably nothing was, as
48 // the user was probably off-line). As a result, the log probably kept
49 // accumulating while the "initial" log was stalled, and couldn't be sent. As a
50 // result, we don't want to save too many of these mega-logs. A "standard
51 // shutdown" will create a small log, including just the data that was not yet
52 // been transmitted, and that is normal (to have exactly one ongoing_log_ at
53 // startup).
54 constexpr size_t kMinOngoingLogQueueCount = 8;
55
56 } // namespace
57
MetricsServiceClient()58 MetricsServiceClient::MetricsServiceClient() {}
59
~MetricsServiceClient()60 MetricsServiceClient::~MetricsServiceClient() {}
61
GetUkmService()62 ukm::UkmService* MetricsServiceClient::GetUkmService() {
63 return nullptr;
64 }
65
ShouldUploadMetricsForUserId(uint64_t user_id)66 bool MetricsServiceClient::ShouldUploadMetricsForUserId(uint64_t user_id) {
67 return true;
68 }
69
GetMetricsServerUrl()70 GURL MetricsServiceClient::GetMetricsServerUrl() {
71 #ifndef NDEBUG
72 // Only allow overriding the server URL through the command line in debug
73 // builds. This is to prevent, for example, rerouting metrics due to malware.
74 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
75 if (command_line->HasSwitch(switches::kUmaServerUrl))
76 return GURL(command_line->GetSwitchValueASCII(switches::kUmaServerUrl));
77 #endif // NDEBUG
78 return GURL(kNewMetricsServerUrl);
79 }
80
GetInsecureMetricsServerUrl()81 GURL MetricsServiceClient::GetInsecureMetricsServerUrl() {
82 #ifndef NDEBUG
83 // Only allow overriding the server URL through the command line in debug
84 // builds. This is to prevent, for example, rerouting metrics due to malware.
85 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
86 if (command_line->HasSwitch(switches::kUmaInsecureServerUrl)) {
87 return GURL(
88 command_line->GetSwitchValueASCII(switches::kUmaInsecureServerUrl));
89 }
90 #endif // NDEBUG
91 return GURL(kNewMetricsServerUrlInsecure);
92 }
93
GetUploadInterval()94 base::TimeDelta MetricsServiceClient::GetUploadInterval() {
95 const base::CommandLine* command_line =
96 base::CommandLine::ForCurrentProcess();
97 // If an upload interval is set from the command line, use that value but
98 // subject it to a minimum threshold to mitigate the risk of DDoS attack.
99 if (command_line->HasSwitch(metrics::switches::kMetricsUploadIntervalSec)) {
100 const std::string switch_value = command_line->GetSwitchValueASCII(
101 metrics::switches::kMetricsUploadIntervalSec);
102 int custom_upload_interval;
103 if (base::StringToInt(switch_value, &custom_upload_interval)) {
104 return base::Seconds(
105 std::max(custom_upload_interval, kMetricsUploadIntervalSecMinimum));
106 }
107 LOG(DFATAL) << "Malformed value for --metrics-upload-interval. "
108 << "Expected int, got: " << switch_value;
109 }
110 return GetStandardUploadInterval();
111 }
112
ShouldStartUpFastForTesting() const113 bool MetricsServiceClient::ShouldStartUpFastForTesting() const {
114 return false;
115 }
116
IsReportingPolicyManaged()117 bool MetricsServiceClient::IsReportingPolicyManaged() {
118 return false;
119 }
120
GetMetricsReportingDefaultState()121 EnableMetricsDefault MetricsServiceClient::GetMetricsReportingDefaultState() {
122 return EnableMetricsDefault::DEFAULT_UNKNOWN;
123 }
124
IsOnCellularConnection()125 bool MetricsServiceClient::IsOnCellularConnection() {
126 return false;
127 }
128
IsExternalExperimentAllowlistEnabled()129 bool MetricsServiceClient::IsExternalExperimentAllowlistEnabled() {
130 return true;
131 }
132
IsUkmAllowedForAllProfiles()133 bool MetricsServiceClient::IsUkmAllowedForAllProfiles() {
134 return false;
135 }
136
AreNotificationListenersEnabledOnAllProfiles()137 bool MetricsServiceClient::AreNotificationListenersEnabledOnAllProfiles() {
138 return false;
139 }
140
GetAppPackageNameIfLoggable()141 std::string MetricsServiceClient::GetAppPackageNameIfLoggable() {
142 return std::string();
143 }
144
GetUploadSigningKey()145 std::string MetricsServiceClient::GetUploadSigningKey() {
146 return std::string();
147 }
148
ShouldResetClientIdsOnClonedInstall()149 bool MetricsServiceClient::ShouldResetClientIdsOnClonedInstall() {
150 return false;
151 }
152
153 base::CallbackListSubscription
AddOnClonedInstallDetectedCallback(base::OnceClosure callback)154 MetricsServiceClient::AddOnClonedInstallDetectedCallback(
155 base::OnceClosure callback) {
156 return base::CallbackListSubscription();
157 }
158
GetStorageLimits() const159 MetricsLogStore::StorageLimits MetricsServiceClient::GetStorageLimits() const {
160 return {
161 /*min_initial_log_queue_count=*/kMinInitialLogQueueCount,
162 /*min_initial_log_queue_size=*/kMinLogQueueSize,
163 /*min_ongoing_log_queue_count=*/kMinOngoingLogQueueCount,
164 /*min_ongoing_log_queue_size=*/kMinLogQueueSize,
165 /*max_ongoing_log_size=*/kMaxOngoingLogSize,
166 };
167 }
168
SetUpdateRunningServicesCallback(const base::RepeatingClosure & callback)169 void MetricsServiceClient::SetUpdateRunningServicesCallback(
170 const base::RepeatingClosure& callback) {
171 update_running_services_ = callback;
172 }
173
UpdateRunningServices()174 void MetricsServiceClient::UpdateRunningServices() {
175 if (update_running_services_)
176 update_running_services_.Run();
177 }
178
IsMetricsReportingForceEnabled() const179 bool MetricsServiceClient::IsMetricsReportingForceEnabled() const {
180 return ::metrics::IsMetricsReportingForceEnabled();
181 }
182
GetCurrentUserMetricsConsent() const183 absl::optional<bool> MetricsServiceClient::GetCurrentUserMetricsConsent()
184 const {
185 return absl::nullopt;
186 }
187
GetCurrentUserId() const188 absl::optional<std::string> MetricsServiceClient::GetCurrentUserId() const {
189 return absl::nullopt;
190 }
191
192 } // namespace metrics
193