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