118 lines
3.5 KiB
C++
118 lines
3.5 KiB
C++
// Copyright 2019 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "components/metrics/structured/recorder.h"
|
|
|
|
#include <utility>
|
|
|
|
#include "base/no_destructor.h"
|
|
#include "base/task/current_thread.h"
|
|
#include "base/task/sequenced_task_runner.h"
|
|
#include "components/metrics/structured/histogram_util.h"
|
|
#include "components/metrics/structured/structured_metrics_features.h"
|
|
#include "components/metrics/structured/structured_metrics_validator.h"
|
|
|
|
namespace metrics::structured {
|
|
|
|
Recorder::Recorder() = default;
|
|
Recorder::~Recorder() = default;
|
|
|
|
Recorder* Recorder::GetInstance() {
|
|
static base::NoDestructor<Recorder> recorder;
|
|
return recorder.get();
|
|
}
|
|
|
|
void Recorder::RecordEvent(Event&& event) {
|
|
// All calls to StructuredMetricsProvider (the observer) must be on the UI
|
|
// sequence, so re-call Record if needed. If a UI task runner hasn't been set
|
|
// yet, ignore this Record.
|
|
if (!ui_task_runner_) {
|
|
LogInternalError(StructuredMetricsError::kUninitializedClient);
|
|
return;
|
|
}
|
|
|
|
if (!ui_task_runner_->RunsTasksInCurrentSequence()) {
|
|
ui_task_runner_->PostTask(
|
|
FROM_HERE, base::BindOnce(&Recorder::RecordEvent,
|
|
base::Unretained(this), std::move(event)));
|
|
return;
|
|
}
|
|
|
|
DCHECK(base::CurrentUIThread::IsSet());
|
|
|
|
delegating_events_processor_.OnEventsRecord(&event);
|
|
|
|
// Make a copy of an event that all observers can share.
|
|
const auto event_clone = event.Clone();
|
|
for (auto& observer : observers_) {
|
|
observer.OnEventRecord(event_clone);
|
|
}
|
|
|
|
if (observers_.empty()) {
|
|
// Other values of EventRecordingState are recorded in
|
|
// StructuredMetricsProvider::OnRecord.
|
|
LogEventRecordingState(EventRecordingState::kProviderMissing);
|
|
}
|
|
}
|
|
|
|
void Recorder::ProfileAdded(const base::FilePath& profile_path) {
|
|
// All calls to the StructuredMetricsProvider (the observer) must be on the UI
|
|
// sequence.
|
|
DCHECK(base::CurrentUIThread::IsSet());
|
|
// TODO(crbug.com/1016655 ): investigate whether we can verify that
|
|
// |profile_path| corresponds to a valid (non-guest, non-signin) profile.
|
|
for (auto& observer : observers_) {
|
|
observer.OnProfileAdded(profile_path);
|
|
}
|
|
}
|
|
|
|
absl::optional<int> Recorder::LastKeyRotation(const Event& event) {
|
|
auto project_validator = validator::GetProjectValidator(event.project_name());
|
|
if (!project_validator.has_value()) {
|
|
return absl::nullopt;
|
|
}
|
|
|
|
auto project_name_hash = project_validator.value()->project_hash();
|
|
|
|
absl::optional<int> result;
|
|
// |observers_| will contain at most one observer, despite being an
|
|
// ObserverList.
|
|
for (auto& observer : observers_) {
|
|
result = observer.LastKeyRotation(project_name_hash);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void Recorder::OnReportingStateChanged(bool enabled) {
|
|
for (auto& observer : observers_) {
|
|
observer.OnReportingStateChanged(enabled);
|
|
}
|
|
}
|
|
|
|
void Recorder::OnSystemProfileInitialized() {
|
|
for (auto& observer : observers_) {
|
|
observer.OnSystemProfileInitialized();
|
|
}
|
|
}
|
|
|
|
void Recorder::SetUiTaskRunner(
|
|
const scoped_refptr<base::SequencedTaskRunner> ui_task_runner) {
|
|
ui_task_runner_ = ui_task_runner;
|
|
}
|
|
|
|
void Recorder::AddObserver(RecorderImpl* observer) {
|
|
observers_.AddObserver(observer);
|
|
}
|
|
|
|
void Recorder::RemoveObserver(RecorderImpl* observer) {
|
|
observers_.RemoveObserver(observer);
|
|
}
|
|
|
|
void Recorder::AddEventsProcessor(
|
|
std::unique_ptr<EventsProcessorInterface> events_processor) {
|
|
delegating_events_processor_.AddEventsProcessor(std::move(events_processor));
|
|
}
|
|
|
|
} // namespace metrics::structured
|