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