File: metrics_service_client.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (255 lines) | stat: -rw-r--r-- 8,639 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/metrics/metrics_service_client.h"

#include <algorithm>
#include <optional>
#include <string>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "components/metrics/metrics_features.h"
#include "components/metrics/metrics_switches.h"
#include "components/metrics/server_urls.h"
#include "metrics_service_client.h"

namespace metrics {

namespace {

// The number of initial/ongoing logs to persist in the queue before logs are
// dropped.
// Note: Both the count threshold and the bytes threshold (see
// `kLogBytesTrimThreshold` below) must be reached for logs to be
// dropped/trimmed.
//
// Note that each ongoing log may be pretty large, since "initial" logs must
// first be sent before any ongoing logs are transmitted. "Initial" logs will
// not be sent if a user is offline. As a result, the current ongoing log will
// accumulate until the "initial" log can be transmitted. We don't want to save
// too many of these mega-logs (this should be capped by
// kLogBytesTrimThreshold).
//
// A "standard shutdown" will create a small log, including just the data that
// was not yet been transmitted, and that is normal (to have exactly one
// ongoing log at startup).
//
// Refer to //components/metrics/unsent_log_store.h for more details on when
// logs are dropped.
const base::FeatureParam<int> kInitialLogCountTrimThreshold{
    &features::kMetricsLogTrimming, "initial_log_count_trim_threshold", 20};
const base::FeatureParam<int> kOngoingLogCountTrimThreshold{
    &features::kMetricsLogTrimming, "ongoing_log_count_trim_threshold", 8};

// The number bytes of the queue to be persisted before logs are dropped. This
// will be applied to both log queues (initial/ongoing). This ensures that a
// reasonable amount of history will be stored even if there is a long series of
// very small logs.
// Note: Both the count threshold (see `kInitialLogCountTrimThreshold` and
// `kOngoingLogCountTrimThreshold` above) and the bytes threshold must be
// reached for logs to be dropped/trimmed.
//
// Refer to //components/metrics/unsent_log_store.h for more details on when
// logs are dropped.
const base::FeatureParam<int> kLogBytesTrimThreshold{
    &features::kMetricsLogTrimming, "log_bytes_trim_threshold",
    300 * 1024  // 300 KiB
};

// If an initial/ongoing metrics log upload fails, and the transmission is over
// this byte count, then we will discard the log, and not try to retransmit it.
// We also don't persist the log to the prefs for transmission during the next
// chrome session if this limit is exceeded.
const base::FeatureParam<int> kMaxInitialLogSizeBytes{
    &features::kMetricsLogTrimming, "max_initial_log_size_bytes",
    0  // Initial logs can be of any size.
};
const base::FeatureParam<int> kMaxOngoingLogSizeBytes{
    &features::kMetricsLogTrimming, "max_ongoing_log_size_bytes",
#if BUILDFLAG(IS_CHROMEOS)
    // Increase CrOS limit to accommodate SampledProfile data (crbug/1210595).
    1024 * 1024  // 1 MiB
#else
    100 * 1024  // 100 KiB
#endif  // BUILDFLAG(IS_CHROMEOS)
};

// The minimum time in seconds between consecutive metrics report uploads.
constexpr int kMetricsUploadIntervalSecMinimum = 20;

}  // namespace

MetricsServiceClient::MetricsServiceClient() = default;

MetricsServiceClient::~MetricsServiceClient() = default;

ukm::UkmService* MetricsServiceClient::GetUkmService() {
  return nullptr;
}

metrics::dwa::DwaService* MetricsServiceClient::GetDwaService() {
  return nullptr;
}

IdentifiabilityStudyState*
MetricsServiceClient::GetIdentifiabilityStudyState() {
  return nullptr;
}

structured::StructuredMetricsService*
MetricsServiceClient::GetStructuredMetricsService() {
  return nullptr;
}

bool MetricsServiceClient::ShouldUploadMetricsForUserId(uint64_t user_id) {
  return true;
}

GURL MetricsServiceClient::GetMetricsServerUrl() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kUmaServerUrl)) {
    return GURL(command_line->GetSwitchValueASCII(switches::kUmaServerUrl));
  }
  // Explicitly prefix with metrics namespace due to name collision.
  return metrics::GetMetricsServerUrl();
}

GURL MetricsServiceClient::GetInsecureMetricsServerUrl() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kUmaInsecureServerUrl)) {
    return GURL(
        command_line->GetSwitchValueASCII(switches::kUmaInsecureServerUrl));
  }
  // Explicitly prefix with metrics namespace due to name collision.
  return metrics::GetInsecureMetricsServerUrl();
}

base::TimeDelta MetricsServiceClient::GetUploadInterval() {
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  // If an upload interval is set from the command line, use that value but
  // subject it to a minimum threshold to mitigate the risk of DDoS attack.
  if (command_line->HasSwitch(metrics::switches::kMetricsUploadIntervalSec)) {
    const std::string switch_value = command_line->GetSwitchValueASCII(
        metrics::switches::kMetricsUploadIntervalSec);
    int custom_upload_interval;
    if (base::StringToInt(switch_value, &custom_upload_interval)) {
      return base::Seconds(
          std::max(custom_upload_interval, kMetricsUploadIntervalSecMinimum));
    }
    LOG(DFATAL) << "Malformed value for --metrics-upload-interval. "
                << "Expected int, got: " << switch_value;
  }

  // Use a custom interval if available.
  if (auto custom_interval = GetCustomUploadInterval();
      custom_interval.has_value()) {
    return *custom_interval;
  }

  return GetStandardUploadInterval();
}

std::optional<base::TimeDelta> MetricsServiceClient::GetCustomUploadInterval()
    const {
  return std::nullopt;
}

bool MetricsServiceClient::ShouldStartUpFast() const {
  return false;
}

bool MetricsServiceClient::IsReportingPolicyManaged() {
  return false;
}

EnableMetricsDefault MetricsServiceClient::GetMetricsReportingDefaultState() {
  return EnableMetricsDefault::DEFAULT_UNKNOWN;
}

bool MetricsServiceClient::IsOnCellularConnection() {
  return false;
}

bool MetricsServiceClient::IsUkmAllowedForAllProfiles() {
  return false;
}

bool MetricsServiceClient::IsDwaAllowedForAllProfiles() {
  return false;
}

bool MetricsServiceClient::AreNotificationListenersEnabledOnAllProfiles() {
  return false;
}

std::string MetricsServiceClient::GetAppPackageNameIfLoggable() {
  return std::string();
}

std::string MetricsServiceClient::GetUploadSigningKey() {
  return std::string();
}

bool MetricsServiceClient::ShouldResetClientIdsOnClonedInstall() {
  return false;
}

base::CallbackListSubscription
MetricsServiceClient::AddOnClonedInstallDetectedCallback(
    base::OnceClosure callback) {
  return base::CallbackListSubscription();
}

MetricsLogStore::StorageLimits MetricsServiceClient::GetStorageLimits() const {
  return {
      .initial_log_queue_limits =
          UnsentLogStore::UnsentLogStoreLimits{
              .min_log_count =
                  static_cast<size_t>(kInitialLogCountTrimThreshold.Get()),
              .min_queue_size_bytes =
                  static_cast<size_t>(kLogBytesTrimThreshold.Get()),
              .max_log_size_bytes =
                  static_cast<size_t>(kMaxInitialLogSizeBytes.Get()),
          },
      .ongoing_log_queue_limits =
          UnsentLogStore::UnsentLogStoreLimits{
              .min_log_count =
                  static_cast<size_t>(kOngoingLogCountTrimThreshold.Get()),
              .min_queue_size_bytes =
                  static_cast<size_t>(kLogBytesTrimThreshold.Get()),
              .max_log_size_bytes =
                  static_cast<size_t>(kMaxOngoingLogSizeBytes.Get()),
          },
  };
}

void MetricsServiceClient::SetUpdateRunningServicesCallback(
    const base::RepeatingClosure& callback) {
  update_running_services_ = callback;
}

void MetricsServiceClient::UpdateRunningServices() {
  if (update_running_services_) {
    update_running_services_.Run();
  }
}

bool MetricsServiceClient::IsMetricsReportingForceEnabled() const {
  return ::metrics::IsMetricsReportingForceEnabled();
}

std::optional<bool> MetricsServiceClient::GetCurrentUserMetricsConsent() const {
  return std::nullopt;
}

std::optional<std::string> MetricsServiceClient::GetCurrentUserId() const {
  return std::nullopt;
}

}  // namespace metrics