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/structured_metrics_features.h" 14 #include "components/metrics/structured/structured_metrics_validator.h" 15 16 namespace metrics::structured { 17 18 Recorder::Recorder() = default; 19 Recorder::~Recorder() = default; 20 GetInstance()21Recorder* Recorder::GetInstance() { 22 static base::NoDestructor<Recorder> recorder; 23 return recorder.get(); 24 } 25 RecordEvent(Event && event)26void Recorder::RecordEvent(Event&& event) { 27 // All calls to StructuredMetricsProvider (the observer) must be on the UI 28 // sequence, so re-call Record if needed. If a UI task runner hasn't been set 29 // yet, ignore this Record. 30 if (!ui_task_runner_) { 31 LogInternalError(StructuredMetricsError::kUninitializedClient); 32 return; 33 } 34 35 if (!ui_task_runner_->RunsTasksInCurrentSequence()) { 36 ui_task_runner_->PostTask( 37 FROM_HERE, base::BindOnce(&Recorder::RecordEvent, 38 base::Unretained(this), std::move(event))); 39 return; 40 } 41 42 DCHECK(base::CurrentUIThread::IsSet()); 43 44 delegating_events_processor_.OnEventsRecord(&event); 45 46 // Make a copy of an event that all observers can share. 47 const auto event_clone = event.Clone(); 48 for (auto& observer : observers_) { 49 observer.OnEventRecord(event_clone); 50 } 51 52 if (observers_.empty()) { 53 // Other values of EventRecordingState are recorded in 54 // StructuredMetricsProvider::OnRecord. 55 LogEventRecordingState(EventRecordingState::kProviderMissing); 56 } 57 } 58 ProfileAdded(const base::FilePath & profile_path)59void Recorder::ProfileAdded(const base::FilePath& profile_path) { 60 // All calls to the StructuredMetricsProvider (the observer) must be on the UI 61 // sequence. 62 DCHECK(base::CurrentUIThread::IsSet()); 63 // TODO(crbug.com/1016655 ): investigate whether we can verify that 64 // |profile_path| corresponds to a valid (non-guest, non-signin) profile. 65 for (auto& observer : observers_) { 66 observer.OnProfileAdded(profile_path); 67 } 68 } 69 LastKeyRotation(const Event & event)70absl::optional<int> Recorder::LastKeyRotation(const Event& event) { 71 auto project_validator = validator::GetProjectValidator(event.project_name()); 72 if (!project_validator.has_value()) { 73 return absl::nullopt; 74 } 75 76 auto project_name_hash = project_validator.value()->project_hash(); 77 78 absl::optional<int> result; 79 // |observers_| will contain at most one observer, despite being an 80 // ObserverList. 81 for (auto& observer : observers_) { 82 result = observer.LastKeyRotation(project_name_hash); 83 } 84 return result; 85 } 86 OnReportingStateChanged(bool enabled)87void Recorder::OnReportingStateChanged(bool enabled) { 88 for (auto& observer : observers_) { 89 observer.OnReportingStateChanged(enabled); 90 } 91 } 92 OnSystemProfileInitialized()93void Recorder::OnSystemProfileInitialized() { 94 for (auto& observer : observers_) { 95 observer.OnSystemProfileInitialized(); 96 } 97 } 98 SetUiTaskRunner(const scoped_refptr<base::SequencedTaskRunner> ui_task_runner)99void Recorder::SetUiTaskRunner( 100 const scoped_refptr<base::SequencedTaskRunner> ui_task_runner) { 101 ui_task_runner_ = ui_task_runner; 102 } 103 AddObserver(RecorderImpl * observer)104void Recorder::AddObserver(RecorderImpl* observer) { 105 observers_.AddObserver(observer); 106 } 107 RemoveObserver(RecorderImpl * observer)108void Recorder::RemoveObserver(RecorderImpl* observer) { 109 observers_.RemoveObserver(observer); 110 } 111 AddEventsProcessor(std::unique_ptr<EventsProcessorInterface> events_processor)112void Recorder::AddEventsProcessor( 113 std::unique_ptr<EventsProcessorInterface> events_processor) { 114 delegating_events_processor_.AddEventsProcessor(std::move(events_processor)); 115 } 116 117 } // namespace metrics::structured 118