File: structured_metrics_service.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (229 lines) | stat: -rw-r--r-- 8,316 bytes parent folder | download | duplicates (3)
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
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_METRICS_STRUCTURED_STRUCTURED_METRICS_SERVICE_H_
#define COMPONENTS_METRICS_STRUCTURED_STRUCTURED_METRICS_SERVICE_H_

#include <memory>

#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/threading/sequence_bound.h"
#include "components/metrics/structured/reporting/structured_metrics_reporting_service.h"
#include "components/metrics/structured/storage_manager.h"
#include "components/metrics/structured/structured_metrics_recorder.h"
#include "components/metrics/structured/structured_metrics_scheduler.h"
#include "components/metrics/unsent_log_store.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"

FORWARD_DECLARE_TEST(StructuredMetricsServiceTest, RotateLogs);

class PrefRegistrySimple;

namespace metrics {
class StructuredMetricsServiceTestBase;
class TestStructuredMetricsServiceDisabled;
class TestStructuredMetricsService;

FORWARD_DECLARE_TEST(TestStructuredMetricsServiceDisabled,
                     ValidStateWhenDisabled);

FORWARD_DECLARE_TEST(TestStructuredMetricsService, CreateLogs);
}  // namespace metrics

namespace metrics::structured {

class OobeStructuredMetricsWatcher;
class StructuredMetricsServiceTest;
class StructuredMetricsMixin;

FORWARD_DECLARE_TEST(StructuredMetricsServiceTest, RotateLogs);

// The Structured Metrics Service is responsible for collecting and uploading
// Structured Metric events.
class StructuredMetricsService final : public StorageManager::StorageDelegate {
 public:
  StructuredMetricsService(MetricsServiceClient* client,
                           PrefService* local_state,
                           scoped_refptr<StructuredMetricsRecorder> recorder);

  ~StructuredMetricsService() override;

  StructuredMetricsService(const StructuredMetricsService&) = delete;
  StructuredMetricsService& operator=(StructuredMetricsService&) = delete;

  void EnableRecording();
  void DisableRecording();

  void EnableReporting();
  void DisableReporting();

  // Flushes any event currently in the recorder to prefs.
  void Flush(metrics::MetricsLogsEventManager::CreateReason reason);

  // Clears all event and log data.
  void Purge();

  MetricsServiceClient* GetMetricsServiceClient() const;

  bool reporting_active() const {
    return reporting_service_->reporting_active();
  }

  bool recording_enabled() const { return recorder_->recording_enabled(); }

  StructuredMetricsRecorder* recorder() { return recorder_.get(); }

  static void RegisterPrefs(PrefRegistrySimple* registry);

  metrics::LogStore* log_store() { return reporting_service_->log_store(); }

 private:
  friend class StructuredMetricsServiceTest;
  friend class StructuredMetricsMixin;
#if BUILDFLAG(IS_CHROMEOS)
  friend class OobeStructuredMetricsWatcher;
#endif
  friend class metrics::StructuredMetricsServiceTestBase;

  FRIEND_TEST_ALL_PREFIXES(metrics::structured::StructuredMetricsServiceTest,
                           RotateLogs);
  FRIEND_TEST_ALL_PREFIXES(metrics::TestStructuredMetricsService, CreateLogs);
  FRIEND_TEST_ALL_PREFIXES(metrics::TestStructuredMetricsServiceDisabled,
                           ValidStateWhenDisabled);

  // Sets the instance of the recorder used for test.
  void SetRecorderForTest(scoped_refptr<StructuredMetricsRecorder> recorder);

  // Callback function to get the upload interval.
  base::TimeDelta GetUploadTimeInterval();

  // Creates a new log and sends any currently stages logs.
  void RotateLogsAndSend();

  // Collects the events from the recorder and builds a new log on a separate
  // task.
  //
  // An upload is triggered once the task is completed.
  void BuildAndStoreLog(metrics::MetricsLogsEventManager::CreateReason reason,
                        bool notify_scheduler);

  // Collects the events from the recorder and builds a new log on the current
  // thread.
  //
  // An upload is triggered after the log has been stored.
  // Used on Windows, Mac, and Linux and during shutdown.
  void BuildAndStoreLogSync(
      metrics::MetricsLogsEventManager::CreateReason reason,
      bool notify_scheduler);

  // Populates an UMA proto with data that must be accessed form the UI
  // sequence. A task to collect events is posted which updates the created UMA
  // proto. On Windows, Mac, and Linux logs are built synchronously.
  //
  // Must be called from the UI sequence.
  void CreateLogs(metrics::MetricsLogsEventManager::CreateReason reason,
                  bool notify_scheduler);

  // Adds metadata to the uma proto, stores a temporary log into the log store,
  // and starts an upload.
  void StoreLogAndStartUpload(
      metrics::MetricsLogsEventManager::CreateReason reason,
      bool notify_scheduler,
      ChromeUserMetricsExtension uma_proto);

  // Starts the initialization process for |this|.
  void Initialize();

  // Fills out the UMA proto to be sent.
  void InitializeUmaProto(ChromeUserMetricsExtension& uma_proto);

  // Triggers an upload of recorded events outside of the normal cadence.
  // This doesn't interfere with the normal cadence.
  void ManualUpload();

  // Queue an upload if there are logs stored in the log store. This is meant to
  // be used to start an upload when the service starts, so we do not have to
  // wait until first upload to send events from the previous session.
  //
  // Reporting is assumed to be enabled by function. Must be checked before
  // called.
  void MaybeStartUpload();

  // Sets callback to be performed after a logs is created and stored. When set
  // uploads will be blocked.
  void SetCreateLogsCallbackInTests(base::OnceClosure callback);

  // StorageManager::StorageDelegate:
  void OnFlushed(const FlushedKey& key) override;
  void OnDeleted(const FlushedKey& key, DeleteReason reason) override;

  // Helper function to serialize a ChromeUserMetricsExtension proto.
  static std::string SerializeLog(const ChromeUserMetricsExtension& uma_proto);

  // Retrieves the storage parameters to control the reporting service.
  static UnsentLogStore::UnsentLogStoreLimits GetLogStoreLimits();

  // Manages on-device recording of events.
  scoped_refptr<StructuredMetricsRecorder> recorder_;

  // Service for uploading completed logs.
  std::unique_ptr<reporting::StructuredMetricsReportingService>
      reporting_service_;

  // Schedules when logs will be created.
  std::unique_ptr<StructuredMetricsScheduler> scheduler_;

  // Marks that initialization has completed.
  bool initialize_complete_ = false;

  // Represents if structured metrics and the service is enabled. This isn't
  // to indicate if the service is recording.
  bool structured_metrics_enabled_ = false;

  // Flag to make sure MaybeStartUpload() isn't called twice.
  bool initial_upload_started_ = false;

  // The metrics client |this| is service is associated.
  raw_ptr<MetricsServiceClient> client_;

  // Callback to be performed once a log is created and stored.
  base::OnceClosure create_log_callback_for_tests_;

  SEQUENCE_CHECKER(sequence_checker_);

// Access to |recorder_| through |task_runner_| is only needed on Ash Chrome.
// Other platforms can continue to access |recorder_| directly.
#if BUILDFLAG(IS_CHROMEOS)
  // An IO task runner for creating logs.
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  // A helper class for performing asynchronous IO task on the
  // StructuredMetricsRecorder.
  class ServiceIOHelper {
   public:
    explicit ServiceIOHelper(scoped_refptr<StructuredMetricsRecorder> recorder);

    ~ServiceIOHelper();

    // Reads the events from |recorder_|.
    ChromeUserMetricsExtension ProvideEvents();

   private:
    // Access to the recorder is thead-safe.
    scoped_refptr<StructuredMetricsRecorder> recorder_;
  };

  // Holds a refptr to |recorder_| and provides access through |task_runner_|.
  base::SequenceBound<ServiceIOHelper> io_helper_;
#endif
  base::WeakPtrFactory<StructuredMetricsService> weak_factory_{this};
};

}  // namespace metrics::structured

#endif  // COMPONENTS_METRICS_STRUCTURED_STRUCTURED_METRICS_SERVICE_H_