| // Copyright 2024 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "heartd/daemon/mojo_service.h" | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <base/functional/bind.h> | |
| #include <base/logging.h> | |
| #include <chromeos/mojo/service_constants.h> | |
| #include <mojo_service_manager/lib/connect.h> | |
| #include "heartd/daemon/action_runner.h" | |
| #include "heartd/daemon/sheriffs/sheriff.h" | |
| #include "heartd/daemon/utils/mojo_output.h" | |
| #include "heartd/mojom/heartd.mojom.h" | |
| namespace heartd { | |
| namespace { | |
| namespace mojom = ::ash::heartd::mojom; | |
| } // namespace | |
| HeartdMojoService::HeartdMojoService(HeartbeatManager* heartbeat_manager, | |
| ActionRunner* action_runner, | |
| TopSheriff* top_sheriff) | |
| : heartbeat_manager_(heartbeat_manager), | |
| action_runner_(action_runner), | |
| top_sheriff_(top_sheriff) { | |
| auto pending_remote = | |
| chromeos::mojo_service_manager::ConnectToMojoServiceManager(); | |
| CHECK(pending_remote) << "Failed to connect to mojo service manager."; | |
| service_manager_.Bind(std::move(pending_remote)); | |
| service_manager_.set_disconnect_with_reason_handler( | |
| base::BindOnce([](uint32_t error, const std::string& message) { | |
| LOG(INFO) << "Disconnected from mojo service manager (the mojo broker " | |
| "process). Error: " | |
| << error << ", message: " << message | |
| << ". Shutdown and wait for respawn."; | |
| })); | |
| heartbeat_service_provider_.Register( | |
| service_manager_.get(), chromeos::mojo_services::kHeartdHeartbeatService); | |
| heartd_control_provider_.Register(service_manager_.get(), | |
| chromeos::mojo_services::kHeartdControl); | |
| heartbeat_verifier_ = new HeartbeatVerifier(heartbeat_manager_); | |
| top_sheriff_->AddSheriff(std::unique_ptr<Sheriff>(heartbeat_verifier_)); | |
| } | |
| HeartdMojoService::~HeartdMojoService() = default; | |
| void HeartdMojoService::Register( | |
| mojom::ServiceName name, | |
| mojom::HeartbeatServiceArgumentPtr argument, | |
| mojo::PendingReceiver<mojom::Pacemaker> receiver, | |
| RegisterCallback callback) { | |
| if (heartbeat_manager_->IsPacemakerBound(name)) { | |
| LOG(ERROR) << "Repeated registration: " << ToStr(name); | |
| std::move(callback).Run(false); | |
| return; | |
| } | |
| heartbeat_manager_->EstablishHeartbeatTracker(name, std::move(receiver), | |
| std::move(argument)); | |
| heartbeat_verifier_->GetToWork(); | |
| std::move(callback).Run(true); | |
| } | |
| void HeartdMojoService::EnableNormalRebootAction() { | |
| LOG(INFO) << "Heartbeat service enables normal reboot action"; | |
| action_runner_->EnableNormalRebootAction(); | |
| } | |
| void HeartdMojoService::EnableForceRebootAction() { | |
| LOG(INFO) << "Heartbeat service enables force reboot action"; | |
| action_runner_->EnableForceRebootAction(); | |
| } | |
| void HeartdMojoService::RunAction(mojom::ActionType action, | |
| RunActionCallback callback) { | |
| LOG(INFO) << "Heartbeat service runs action: " << ToStr(action); | |
| // Just use kKiosk as the service name, since this interface is used by test. | |
| action_runner_->Run(mojom::ServiceName::kKiosk, action); | |
| std::move(callback).Run(true); | |
| } | |
| } // namespace heartd |