blob: 08c3643cf79ab12c509c877355a73edc64e5ca1c [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/policy/reporting/metrics_reporting/apps/app_events_observer.h"
#include <memory>
#include "base/memory/ptr_util.h"
#include "base/observer_list_types.h"
#include "base/sequence_checker.h"
#include "chrome/browser/apps/app_service/metrics/app_platform_metrics.h"
#include "chrome/browser/ash/policy/reporting/metrics_reporting/apps/app_platform_metrics_retriever.h"
#include "chrome/browser/profiles/profile.h"
#include "components/reporting/metrics/metric_event_observer.h"
#include "components/reporting/proto/synced/metric_data.pb.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/protos/app_types.pb.h"
namespace reporting {
// static
std::unique_ptr<AppEventsObserver> AppEventsObserver::CreateForProfile(
Profile* profile) {
DCHECK(profile);
auto app_platform_metrics_retriever =
std::make_unique<AppPlatformMetricsRetriever>(profile->GetWeakPtr());
return base::WrapUnique(
new AppEventsObserver(std::move(app_platform_metrics_retriever)));
}
// static
std::unique_ptr<AppEventsObserver> AppEventsObserver::CreateForTest(
std::unique_ptr<AppPlatformMetricsRetriever>
app_platform_metrics_retriever) {
return base::WrapUnique(
new AppEventsObserver(std::move(app_platform_metrics_retriever)));
}
AppEventsObserver::AppEventsObserver(
std::unique_ptr<AppPlatformMetricsRetriever> app_platform_metrics_retriever)
: app_platform_metrics_retriever_(
std::move(app_platform_metrics_retriever)) {
DCHECK(app_platform_metrics_retriever_);
app_platform_metrics_retriever_->GetAppPlatformMetrics(base::BindOnce(
&AppEventsObserver::InitEventObserver, weak_ptr_factory_.GetWeakPtr()));
}
AppEventsObserver::~AppEventsObserver() = default;
void AppEventsObserver::SetOnEventObservedCallback(
MetricRepeatingCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
on_metric_observed_ = std::move(callback);
}
void AppEventsObserver::SetReportingEnabled(bool is_enabled) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
is_enabled_ = is_enabled;
}
void AppEventsObserver::InitEventObserver(
::apps::AppPlatformMetrics* app_platform_metrics) {
// Runs on the same sequence as the `AppPlatformMetricsRetriever` because they
// both use the UI thread.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!app_platform_metrics) {
// This can happen if the `AppPlatformMetrics` component initialization
// failed (for example, component was destructed). We just abort
// initialization of the event observer when this happens.
return;
}
observer_.Observe(app_platform_metrics);
}
void AppEventsObserver::OnAppInstalled(const std::string& app_id,
::apps::AppType app_type,
::apps::InstallSource app_install_source,
::apps::InstallReason app_install_reason,
::apps::InstallTime app_install_time) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!is_enabled_) {
return;
}
MetricData metric_data;
metric_data.mutable_event_data()->set_type(MetricEventType::APP_INSTALLED);
auto* const app_install_data = metric_data.mutable_telemetry_data()
->mutable_app_telemetry()
->mutable_app_install_data();
app_install_data->set_app_id(app_id);
app_install_data->set_app_type(
::apps::ConvertAppTypeToProtoApplicationType(app_type));
app_install_data->set_app_install_source(
::apps::ConvertInstallSourceToProtoApplicationInstallSource(
app_install_source));
app_install_data->set_app_install_reason(
::apps::ConvertInstallReasonToProtoApplicationInstallReason(
app_install_reason));
app_install_data->set_app_install_time(
::apps::ConvertInstallTimeToProtoApplicationInstallTime(
app_install_time));
on_metric_observed_.Run(std::move(metric_data));
}
void AppEventsObserver::OnAppLaunched(const std::string& app_id,
::apps::AppType app_type,
::apps::LaunchSource app_launch_source) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!is_enabled_) {
return;
}
MetricData metric_data;
metric_data.mutable_event_data()->set_type(MetricEventType::APP_LAUNCHED);
auto* const app_launch_data = metric_data.mutable_telemetry_data()
->mutable_app_telemetry()
->mutable_app_launch_data();
app_launch_data->set_app_id(app_id);
app_launch_data->set_app_type(
::apps::ConvertAppTypeToProtoApplicationType(app_type));
app_launch_data->set_app_launch_source(
::apps::ConvertLaunchSourceToProtoApplicationLaunchSource(
app_launch_source));
on_metric_observed_.Run(std::move(metric_data));
}
void AppEventsObserver::OnAppUninstalled(
const std::string& app_id,
::apps::AppType app_type,
::apps::UninstallSource app_uninstall_source) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!is_enabled_) {
return;
}
MetricData metric_data;
metric_data.mutable_event_data()->set_type(MetricEventType::APP_UNINSTALLED);
auto* const app_uninstall_data = metric_data.mutable_telemetry_data()
->mutable_app_telemetry()
->mutable_app_uninstall_data();
app_uninstall_data->set_app_id(app_id);
app_uninstall_data->set_app_type(
::apps::ConvertAppTypeToProtoApplicationType(app_type));
app_uninstall_data->set_app_uninstall_source(
::apps::ConvertUninstallSourceToProtoApplicationUninstallSource(
app_uninstall_source));
on_metric_observed_.Run(std::move(metric_data));
}
void AppEventsObserver::OnAppPlatformMetricsDestroyed() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
observer_.Reset();
}
} // namespace reporting