• 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 #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()21 Recorder* Recorder::GetInstance() {
22   static base::NoDestructor<Recorder> recorder;
23   return recorder.get();
24 }
25 
RecordEvent(Event && event)26 void 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)59 void 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)70 absl::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)87 void Recorder::OnReportingStateChanged(bool enabled) {
88   for (auto& observer : observers_) {
89     observer.OnReportingStateChanged(enabled);
90   }
91 }
92 
OnSystemProfileInitialized()93 void Recorder::OnSystemProfileInitialized() {
94   for (auto& observer : observers_) {
95     observer.OnSystemProfileInitialized();
96   }
97 }
98 
SetUiTaskRunner(const scoped_refptr<base::SequencedTaskRunner> ui_task_runner)99 void Recorder::SetUiTaskRunner(
100     const scoped_refptr<base::SequencedTaskRunner> ui_task_runner) {
101   ui_task_runner_ = ui_task_runner;
102 }
103 
AddObserver(RecorderImpl * observer)104 void Recorder::AddObserver(RecorderImpl* observer) {
105   observers_.AddObserver(observer);
106 }
107 
RemoveObserver(RecorderImpl * observer)108 void Recorder::RemoveObserver(RecorderImpl* observer) {
109   observers_.RemoveObserver(observer);
110 }
111 
AddEventsProcessor(std::unique_ptr<EventsProcessorInterface> events_processor)112 void 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