• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 #ifndef COMPONENTS_METRICS_STRUCTURED_RECORDER_H_
6 #define COMPONENTS_METRICS_STRUCTURED_RECORDER_H_
7 
8 #include "base/callback_list.h"
9 #include "base/memory/scoped_refptr.h"
10 #include "base/no_destructor.h"
11 #include "base/observer_list.h"
12 #include "base/observer_list_types.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "components/metrics/structured/event.h"
15 #include "components/metrics/structured/structured_metrics_client.h"
16 #include "components/metrics/structured/structured_metrics_validator.h"
17 #include "third_party/abseil-cpp/absl/types/optional.h"
18 
19 namespace base {
20 class FilePath;
21 }
22 
23 namespace metrics::structured {
24 namespace {
25 
26 using ::metrics::ChromeUserMetricsExtension;
27 
28 }
29 
30 // Recorder is a singleton to help communicate with the
31 // StructuredMetricsProvider. It serves three purposes:
32 // 1. Begin the initialization of the StructuredMetricsProvider (see class
33 // comment for more details).
34 // 2. Add an event for the StructuredMetricsProvider to record.
35 // 3. Retrieving information about project's key, specifically the day it was
36 // last rotated.
37 //
38 // The StructuredMetricsProvider is owned by the MetricsService, but it needs to
39 // be accessible to any part of the codebase, via an EventBase subclass, to
40 // record events. The StructuredMetricsProvider registers itself as an observer
41 // of this singleton when recording is enabled, and calls to Record (for
42 // recording) or ProfileAdded (for initialization) are then forwarded to it.
43 //
44 // Recorder is embedded within StructuredMetricsClient for Ash Chrome and should
45 // only be used in Ash Chrome.
46 //
47 // TODO(b/282031543): Remove this class and merge remaining logic into
48 // structured_metrics_recorder.h since the Record() is exposed via
49 // StructuredMetricsClient interface now.
50 class Recorder {
51  public:
52   class RecorderImpl : public base::CheckedObserver {
53    public:
54     // Called on a call to Record.
55     virtual void OnEventRecord(const Event& event) = 0;
56     // Called on a call to ProfileAdded.
57     virtual void OnProfileAdded(const base::FilePath& profile_path) = 0;
58     // Called on a call to OnReportingStateChanged.
59     virtual void OnReportingStateChanged(bool enabled) = 0;
60     // Called when SystemProfile has finished loading
OnSystemProfileInitialized()61     virtual void OnSystemProfileInitialized() {}
62   };
63 
64   Recorder(const Recorder&) = delete;
65   Recorder& operator=(const Recorder&) = delete;
66 
67   static Recorder* GetInstance();
68 
69   // This signals to StructuredMetricsProvider that the event should be
70   // recorded.
71   void RecordEvent(Event&& event);
72 
73   // Notifies the StructuredMetricsProvider that a profile has been added with
74   // path |profile_path|. The first call to ProfileAdded initializes the
75   // provider using the keys stored in |profile_path|, so care should be taken
76   // to ensure the first call provides a |profile_path| suitable for metrics
77   // collection.
78   // TODO(crbug.com/1016655): When structured metrics expands beyond Chrome OS,
79   // investigate whether initialization can be simplified for Chrome.
80   void ProfileAdded(const base::FilePath& profile_path);
81 
82   // Notifies observers that metrics reporting has been enabled or disabled.
83   void OnReportingStateChanged(bool enabled);
84 
85   // Notifies observers that system profile has been loaded.
86   void OnSystemProfileInitialized();
87 
88   void SetUiTaskRunner(
89       const scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
90 
91   void AddObserver(RecorderImpl* observer);
92   void RemoveObserver(RecorderImpl* observer);
93 
94   // Adds |events_processor| to further add metadata to recorded events or
95   // listen to recorded events.
96   void AddEventsProcessor(
97       std::unique_ptr<EventsProcessorInterface> events_processor);
98 
99   // Modifies |uma_proto| before the log is sent.
100   void OnProvideIndependentMetrics(ChromeUserMetricsExtension* uma_proto);
101 
102   // Modifies |event| once after the proto has been built.
103   void OnEventRecorded(StructuredEventProto* event);
104 
105  private:
106   friend class base::NoDestructor<Recorder>;
107 
108   Recorder();
109   ~Recorder();
110 
111   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
112 
113   base::ObserverList<RecorderImpl> observers_;
114 
115   DelegatingEventsProcessor delegating_events_processor_;
116 };
117 
118 }  // namespace metrics::structured
119 
120 #endif  // COMPONENTS_METRICS_STRUCTURED_RECORDER_H_
121