// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "fuchsia/base/legacymetrics_client.h" #include #include #include #include #include #include "base/fuchsia/default_context.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "fuchsia/base/legacymetrics_histogram_flattener.h" namespace cr_fuchsia { LegacyMetricsClient::LegacyMetricsClient() = default; LegacyMetricsClient::~LegacyMetricsClient() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } void LegacyMetricsClient::Start(base::TimeDelta report_interval) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_GT(report_interval, base::TimeDelta::FromSeconds(0)); DCHECK(!metrics_recorder_) << "Start() called more than once."; report_interval_ = report_interval; metrics_recorder_ = base::fuchsia::ComponentContextForCurrentProcess() ->svc() ->Connect(); metrics_recorder_.set_error_handler(fit::bind_member( this, &LegacyMetricsClient::OnMetricsRecorderDisconnected)); user_events_recorder_ = std::make_unique(); ScheduleNextReport(); } void LegacyMetricsClient::SetReportAdditionalMetricsCallback( ReportAdditionalMetricsCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!metrics_recorder_) << "SetReportAdditionalMetricsCallback() must be called before Start()."; DCHECK(!report_additional_callback_); DCHECK(callback); report_additional_callback_ = std::move(callback); } void LegacyMetricsClient::ScheduleNextReport() { DVLOG(1) << "Scheduling next report in " << report_interval_.InSeconds() << "seconds."; timer_.Start(FROM_HERE, report_interval_, this, &LegacyMetricsClient::Report); } void LegacyMetricsClient::Report() { DCHECK(metrics_recorder_); DVLOG(1) << __func__ << "called."; std::vector events; // Add events from the additional metrics callback, if set. if (report_additional_callback_) report_additional_callback_.Run(&events); // Include histograms. for (auto& histogram : GetLegacyMetricsDeltas()) { fuchsia::legacymetrics::Event histogram_event; histogram_event.set_histogram(std::move(histogram)); events.push_back(std::move(histogram_event)); } // Include user events. if (user_events_recorder_->HasEvents()) { for (auto& event : user_events_recorder_->TakeEvents()) { fuchsia::legacymetrics::Event user_event; user_event.set_user_action_event(std::move(event)); events.push_back(std::move(user_event)); } } if (events.empty()) { ScheduleNextReport(); return; } metrics_recorder_->Record(std::move(events), [this]() { VLOG(1) << "Report finished."; ScheduleNextReport(); }); } void LegacyMetricsClient::OnMetricsRecorderDisconnected(zx_status_t status) { ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) << "MetricsRecorder connection lost."; // Stop recording & reporting user events. user_events_recorder_.reset(); timer_.AbandonAndStop(); } } // namespace cr_fuchsia