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/raw_ptr.h" 10 #include "base/memory/scoped_refptr.h" 11 #include "base/no_destructor.h" 12 #include "base/task/sequenced_task_runner.h" 13 #include "components/metrics/structured/delegating_events_processor.h" 14 #include "components/metrics/structured/event.h" 15 #include "components/metrics/structured/events_processor_interface.h" 16 #include "components/metrics/structured/structured_metrics_client.h" 17 #include "components/metrics/structured/structured_metrics_validator.h" 18 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" 19 20 namespace metrics::structured { 21 namespace { 22 23 using ::metrics::ChromeUserMetricsExtension; 24 25 } 26 27 // Recorder is a singleton to help communicate with the 28 // StructuredMetricsProvider. It serves three purposes: 29 // 1. Begin the initialization of the StructuredMetricsProvider (see class 30 // comment for more details). 31 // 2. Add an event for the StructuredMetricsProvider to record. 32 // 3. Retrieving information about project's key, specifically the day it was 33 // last rotated. 34 // 35 // The StructuredMetricsProvider is owned by the MetricsService, but it needs to 36 // be accessible to any part of the codebase, via an EventBase subclass, to 37 // record events. The StructuredMetricsProvider registers itself as an observer 38 // of this singleton when recording is enabled, and calls to Record (for 39 // recording) or ProfileAdded (for initialization) are then forwarded to it. 40 // 41 // Recorder is embedded within StructuredMetricsClient for Ash Chrome and should 42 // only be used in Ash Chrome. 43 // 44 // TODO(b/282031543): Remove this class and merge remaining logic into 45 // structured_metrics_recorder.h since the Record() is exposed via 46 // StructuredMetricsClient interface now. 47 // 48 // TODO(b/339914565): Move recording off of the UI sequence onto an IO sequence. 49 class Recorder { 50 public: 51 class RecorderImpl { 52 public: 53 // Called on a call to Record. 54 virtual void OnEventRecord(const Event& event) = 0; 55 // Called when SystemProfile has finished loading OnSystemProfileInitialized()56 virtual void OnSystemProfileInitialized() {} 57 }; 58 59 Recorder(const Recorder&) = delete; 60 Recorder& operator=(const Recorder&) = delete; 61 62 static Recorder* GetInstance(); 63 64 // This signals to StructuredMetricsProvider that the event should be 65 // recorded. 66 void RecordEvent(Event&& event); 67 68 // Notifies observers that system profile has been loaded. 69 void OnSystemProfileInitialized(); 70 71 void SetUiTaskRunner( 72 const scoped_refptr<base::SequencedTaskRunner> ui_task_runner); 73 GetUiTaskRunner()74 base::SequencedTaskRunner* GetUiTaskRunner() { return ui_task_runner_.get(); } 75 76 void SetRecorder(RecorderImpl* recorder); 77 void UnsetRecorder(RecorderImpl* recorder); 78 79 // Adds |events_processor| to further add metadata to recorded events or 80 // listen to recorded events. 81 void AddEventsProcessor( 82 std::unique_ptr<EventsProcessorInterface> events_processor); 83 84 // Modifies |uma_proto| before the log is sent. 85 void OnProvideIndependentMetrics(ChromeUserMetricsExtension* uma_proto); 86 87 // Modifies |event| once after the proto has been built. 88 void OnEventRecorded(StructuredEventProto* event); 89 90 private: 91 friend class base::NoDestructor<Recorder>; 92 93 Recorder(); 94 ~Recorder(); 95 96 scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; 97 98 raw_ptr<RecorderImpl> recorder_; 99 100 DelegatingEventsProcessor delegating_events_processor_; 101 }; 102 103 } // namespace metrics::structured 104 105 #endif // COMPONENTS_METRICS_STRUCTURED_RECORDER_H_ 106