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 #include "components/metrics/structured/recorder.h" 6 7 #include <utility> 8 9 #include "base/no_destructor.h" 10 #include "base/task/current_thread.h" 11 #include "base/task/sequenced_task_runner.h" 12 #include "components/metrics/structured/histogram_util.h" 13 #include "components/metrics/structured/lib/histogram_util.h" 14 #include "components/metrics/structured/structured_metrics_features.h" 15 16 namespace metrics::structured { 17 18 Recorder::Recorder() = default; 19 20 Recorder::~Recorder() = default; 21 GetInstance()22Recorder* Recorder::GetInstance() { 23 static base::NoDestructor<Recorder> recorder; 24 return recorder.get(); 25 } 26 RecordEvent(Event && event)27void Recorder::RecordEvent(Event&& event) { 28 // All calls to StructuredMetricsProvider (the observer) must be on the UI 29 // sequence, so re-call Record if needed. If a UI task runner hasn't been set 30 // yet, ignore this Record. 31 if (!ui_task_runner_) { 32 LogInternalError(StructuredMetricsError::kUninitializedClient); 33 return; 34 } 35 36 if (!ui_task_runner_->RunsTasksInCurrentSequence()) { 37 ui_task_runner_->PostTask( 38 FROM_HERE, base::BindOnce(&Recorder::RecordEvent, 39 base::Unretained(this), std::move(event))); 40 return; 41 } 42 43 DCHECK(base::CurrentUIThread::IsSet()); 44 45 delegating_events_processor_.OnEventsRecord(&event); 46 47 // Make a copy of an event that all observers can share. 48 const auto event_clone = event.Clone(); 49 for (auto& observer : observers_) { 50 observer.OnEventRecord(event_clone); 51 } 52 53 if (observers_.empty()) { 54 // Other values of EventRecordingState are recorded in 55 // StructuredMetricsProvider::OnRecord. 56 LogEventRecordingState(EventRecordingState::kProviderMissing); 57 } 58 } 59 OnSystemProfileInitialized()60void Recorder::OnSystemProfileInitialized() { 61 for (auto& observer : observers_) { 62 observer.OnSystemProfileInitialized(); 63 } 64 } 65 SetUiTaskRunner(const scoped_refptr<base::SequencedTaskRunner> ui_task_runner)66void Recorder::SetUiTaskRunner( 67 const scoped_refptr<base::SequencedTaskRunner> ui_task_runner) { 68 ui_task_runner_ = ui_task_runner; 69 } 70 AddObserver(RecorderImpl * observer)71void Recorder::AddObserver(RecorderImpl* observer) { 72 observers_.AddObserver(observer); 73 } 74 RemoveObserver(RecorderImpl * observer)75void Recorder::RemoveObserver(RecorderImpl* observer) { 76 observers_.RemoveObserver(observer); 77 } 78 AddEventsProcessor(std::unique_ptr<EventsProcessorInterface> events_processor)79void Recorder::AddEventsProcessor( 80 std::unique_ptr<EventsProcessorInterface> events_processor) { 81 delegating_events_processor_.AddEventsProcessor(std::move(events_processor)); 82 } 83 OnProvideIndependentMetrics(ChromeUserMetricsExtension * uma_proto)84void Recorder::OnProvideIndependentMetrics( 85 ChromeUserMetricsExtension* uma_proto) { 86 delegating_events_processor_.OnProvideIndependentMetrics(uma_proto); 87 } 88 OnEventRecorded(StructuredEventProto * event)89void Recorder::OnEventRecorded(StructuredEventProto* event) { 90 delegating_events_processor_.OnEventRecorded(event); 91 } 92 93 } // namespace metrics::structured 94