blob: 2bb734f8ecae6bde56f39a21edb9496c3250aa40 [file] [log] [blame]
// Copyright 2018 The Chromium OS 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 "diagnostics/wilco_dtc_supportd/daemon.h"
#include <cstdlib>
#include <base/barrier_closure.h>
#include <base/callback.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/run_loop.h>
#include <base/threading/thread_task_runner_handle.h>
#include <base/time/time.h>
#include <dbus/wilco_dtc_supportd/dbus-constants.h>
#include <mojo/core/embedder/embedder.h>
#include "diagnostics/constants/grpc_constants.h"
#include "diagnostics/wilco_dtc_supportd/service_util.h"
namespace diagnostics {
// The time (in TimeDelta) after which ForceShutdown will be called if graceful
// shutdown wasn't done within that time.
constexpr base::TimeDelta kForceShutdownDelayTimeDelta =
base::TimeDelta::FromSeconds(2);
Daemon::Daemon()
: DBusServiceDaemon(kWilcoDtcSupportdServiceName /* service_name */),
mojo_service_factory_(
&mojo_grpc_adapter_,
base::Bind(&brillo::Daemon::Quit, base::Unretained(this))),
wilco_dtc_supportd_core_(&wilco_dtc_supportd_core_delegate_impl_,
&grpc_client_manager_,
{GetWilcoDtcSupportdGrpcHostVsockUri(),
kWilcoDtcSupportdGrpcDomainSocketUri},
&mojo_service_factory_) {}
Daemon::~Daemon() = default;
int Daemon::OnInit() {
VLOG(0) << "Starting";
const int exit_code = DBusServiceDaemon::OnInit();
if (exit_code != EXIT_SUCCESS)
return exit_code;
grpc_client_manager_.Start(GetUiMessageReceiverWilcoDtcGrpcHostVsockUri(),
{GetWilcoDtcGrpcHostVsockUri()});
if (!wilco_dtc_supportd_core_.Start()) {
LOG(ERROR) << "Shutting down due to fatal initialization failure";
ShutDownServicesInRunLoop(&wilco_dtc_supportd_core_, &grpc_client_manager_);
return EXIT_FAILURE;
}
// Init the Mojo Embedder API.
mojo::core::Init();
ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
base::ThreadTaskRunnerHandle::Get() /* io_thread_task_runner */,
mojo::core::ScopedIPCSupport::ShutdownPolicy::
CLEAN /* blocking shutdown */);
return EXIT_SUCCESS;
}
void Daemon::RegisterDBusObjectsAsync(
brillo::dbus_utils::AsyncEventSequencer* sequencer) {
DCHECK(bus_);
dbus_service_.RegisterDBusObjectsAsync(bus_, sequencer);
wilco_dtc_supportd_core_.CreateDbusAdapters(bus_);
}
void Daemon::OnShutdown(int* error_code) {
// Gracefully tear down pieces that require asynchronous shutdown.
VLOG(1) << "Shutting down";
// Allow time for Core to gracefully shut down all threads.
force_shutdown_timer_.Start(FROM_HERE, kForceShutdownDelayTimeDelta, this,
&Daemon::ForceShutdown);
dbus_service_.ShutDown();
ShutDownServicesInRunLoop(&wilco_dtc_supportd_core_, &grpc_client_manager_);
VLOG(0) << "Shutting down with code " << *error_code;
}
void Daemon::ForceShutdown() {
LOG(ERROR) << "ForceShutdown's the whole process due to a failure while "
"gracefully shutting down";
std::exit(EXIT_FAILURE);
}
} // namespace diagnostics