blob: 6207e6181cada96b36fd26068366b60d5c8c0924 [file] [log] [blame]
// Copyright 2021 The Fuchsia 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 "src/developer/forensics/feedback/main_service.h"
#include <fuchsia/feedback/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <memory>
#include <vector>
#include "src/developer/forensics/feedback/annotations/constants.h"
#include "src/developer/forensics/feedback/annotations/device_id_provider.h"
#include "src/developer/forensics/feedback/annotations/provider.h"
#include "src/developer/forensics/feedback/redactor_factory.h"
#include "src/developer/forensics/utils/cobalt/logger.h"
#include "src/lib/backoff/exponential_backoff.h"
#include "src/lib/timekeeper/system_clock.h"
namespace forensics::feedback {
namespace {
std::unique_ptr<CachedAsyncAnnotationProvider> MakeDeviceIdProvider(
const std::optional<std::string>& local_device_id_path, async_dispatcher_t* dispatcher,
const std::shared_ptr<sys::ServiceDirectory>& services) {
if (local_device_id_path.has_value()) {
FX_LOGS(INFO) << "Using local device id provider";
return std::make_unique<LocalDeviceIdProvider>(local_device_id_path.value());
}
FX_LOGS(INFO) << "Using remote device id provider";
return std::make_unique<RemoteDeviceIdProvider>(dispatcher, services,
AnnotationProviders::AnnotationProviderBackoff());
}
} // namespace
MainService::MainService(async_dispatcher_t* dispatcher,
std::shared_ptr<sys::ServiceDirectory> services, timekeeper::Clock* clock,
inspect::Node* inspect_root, cobalt::Logger* cobalt,
const Annotations& startup_annotations, Options options)
: dispatcher_(dispatcher),
services_(services),
clock_(clock),
inspect_root_(inspect_root),
cobalt_(cobalt),
redactor_(RedactorFromConfig(inspect_root)),
inspect_node_manager_(inspect_root),
annotations_(dispatcher_, services_,
options.feedback_data_options.config.annotation_allowlist, startup_annotations,
MakeDeviceIdProvider(options.local_device_id_path, dispatcher_, services_)),
feedback_data_(dispatcher_, services_, clock_, inspect_root_, cobalt_, redactor_.get(),
annotations_.GetAnnotationManager(), options.feedback_data_options),
crash_reports_(dispatcher_, services_, clock_, inspect_root_,
annotations_.GetAnnotationManager(), feedback_data_.DataProvider(),
options.crash_reports_options),
last_reboot_(dispatcher_, services_, cobalt_, redactor_.get(), crash_reports_.CrashReporter(),
options.last_reboot_options),
last_reboot_info_provider_stats_(&inspect_node_manager_,
"/fidl/fuchsia.feedback.LastRebootInfoProvider"),
crash_reporter_stats_(&inspect_node_manager_, "/fidl/fuchsia.feedback.CrashReporter"),
crash_reporting_product_register_stats_(
&inspect_node_manager_, "/fidl/fuchsia.feedback.CrashReportingProductRegister"),
component_data_register_stats_(&inspect_node_manager_,
"/fidl/fuchsia.feedback.ComponentDataRegister"),
data_provider_stats_(&inspect_node_manager_, "/fidl/fuchsia.feedback.DataProvider"),
data_provider_controller_stats_(&inspect_node_manager_,
"/fidl/fuchsia.feedback.DataProviderController") {}
void MainService::ReportMigrationError(const std::map<std::string, std::string>& annotations) {
fuchsia::feedback::CrashReport crash_report;
crash_report.set_program_name("feedback")
.set_crash_signature("fuchsia-feedback-component-merge-failure");
std::vector<fuchsia::feedback::Annotation> report_annotations;
for (const auto& [k, v] : annotations) {
report_annotations.push_back(fuchsia::feedback::Annotation{
.key = k,
.value = v,
});
}
crash_report.set_annotations(std::move(report_annotations));
crash_reports_.CrashReporter()->File(std::move(crash_report),
[](fuchsia::feedback::CrashReporter_File_Result) {});
}
void MainService::ShutdownImminent(::fit::deferred_callback stop_respond) {
crash_reports_.ShutdownImminent();
feedback_data_.ShutdownImminent(std::move(stop_respond));
}
template <>
::fidl::InterfaceRequestHandler<fuchsia::feedback::LastRebootInfoProvider>
MainService::GetHandler() {
return [this](::fidl::InterfaceRequest<fuchsia::feedback::LastRebootInfoProvider> request) {
last_reboot_info_provider_stats_.NewConnection();
last_reboot_.Handle(std::move(request), [this](zx_status_t) {
last_reboot_info_provider_stats_.CloseConnection();
});
};
}
template <>
::fidl::InterfaceRequestHandler<fuchsia::feedback::CrashReporter> MainService::GetHandler() {
return [this](::fidl::InterfaceRequest<fuchsia::feedback::CrashReporter> request) {
crash_reporter_stats_.NewConnection();
crash_reports_.Handle(std::move(request),
[this](zx_status_t) { crash_reporter_stats_.CloseConnection(); });
};
}
template <>
::fidl::InterfaceRequestHandler<fuchsia::feedback::CrashReportingProductRegister>
MainService::GetHandler() {
return
[this](::fidl::InterfaceRequest<fuchsia::feedback::CrashReportingProductRegister> request) {
crash_reporting_product_register_stats_.NewConnection();
crash_reports_.Handle(std::move(request), [this](zx_status_t) {
crash_reporting_product_register_stats_.CloseConnection();
});
};
}
template <>
::fidl::InterfaceRequestHandler<fuchsia::feedback::ComponentDataRegister>
MainService::GetHandler() {
return [this](::fidl::InterfaceRequest<fuchsia::feedback::ComponentDataRegister> request) {
component_data_register_stats_.NewConnection();
annotations_.Handle(std::move(request),
[this](zx_status_t) { component_data_register_stats_.CloseConnection(); });
};
}
template <>
::fidl::InterfaceRequestHandler<fuchsia::feedback::DataProvider> MainService::GetHandler() {
return [this](::fidl::InterfaceRequest<fuchsia::feedback::DataProvider> request) {
data_provider_stats_.NewConnection();
feedback_data_.Handle(std::move(request),
[this](zx_status_t) { data_provider_stats_.CloseConnection(); });
};
}
template <>
::fidl::InterfaceRequestHandler<fuchsia::feedback::DataProviderController>
MainService::GetHandler() {
return [this](::fidl::InterfaceRequest<fuchsia::feedback::DataProviderController> request) {
data_provider_controller_stats_.NewConnection();
feedback_data_.Handle(std::move(request), [this](zx_status_t) {
data_provider_controller_stats_.CloseConnection();
});
};
}
} // namespace forensics::feedback