rmad: Setup for sending power cable status signal
BUG=b:209387919
TEST=emerge-octopus rmad
Change-Id: I6a1b03d5ccb86c766a4b8f30d13f54c9eff85db8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3317267
Reviewed-by: Gene Chang <genechang@google.com>
Commit-Queue: Cheng-Han Yang <chenghan@chromium.org>
Tested-by: Cheng-Han Yang <chenghan@chromium.org>
diff --git a/rmad/dbus_service.cc b/rmad/dbus_service.cc
index 38c4fa8..49af755 100644
--- a/rmad/dbus_service.cc
+++ b/rmad/dbus_service.cc
@@ -465,6 +465,10 @@
std::make_unique<base::RepeatingCallback<bool(const FinalizeStatus&)>>(
base::BindRepeating(&DBusService::SendFinalizeProgressSignal,
base::Unretained(this))));
+ rmad_interface_->RegisterSignalSender(
+ RmadState::StateCase::kRepairComplete,
+ std::make_unique<base::RepeatingCallback<bool(bool)>>(base::BindRepeating(
+ &DBusService::SendPowerCableStateSignal, base::Unretained(this))));
}
bool DBusService::HandleIsRmaRequiredMethod() {
diff --git a/rmad/dbus_service_test.cc b/rmad/dbus_service_test.cc
index bef2381..9b7c0a9 100644
--- a/rmad/dbus_service_test.cc
+++ b/rmad/dbus_service_test.cc
@@ -199,7 +199,7 @@
return dbus_service_->SendHardwareWriteProtectionStateSignal(enabled);
}
- bool SignalPowerCable(bool plugged_in) {
+ bool SignalPowerCableState(bool plugged_in) {
return dbus_service_->SendPowerCableStateSignal(plugged_in);
}
@@ -500,7 +500,7 @@
EXPECT_TRUE(SignalHardwareWriteProtection(true));
}
-TEST_F(DBusServiceTest, SignalPowerCable) {
+TEST_F(DBusServiceTest, SignalPowerCableState) {
SetUpDBusService(true, RoVerificationStatus::NOT_TRIGGERED, true);
EXPECT_CALL(*GetMockExportedObject(), SendSignal(_))
.WillRepeatedly(Invoke([](dbus::Signal* signal) {
@@ -511,7 +511,7 @@
EXPECT_TRUE(reader.PopBool(&plugged_in));
EXPECT_TRUE(plugged_in);
}));
- EXPECT_TRUE(SignalPowerCable(true));
+ EXPECT_TRUE(SignalPowerCableState(true));
}
} // namespace rmad
diff --git a/rmad/state_handler/repair_complete_state_handler.cc b/rmad/state_handler/repair_complete_state_handler.cc
index 438ebb1..1dd4fd7 100644
--- a/rmad/state_handler/repair_complete_state_handler.cc
+++ b/rmad/state_handler/repair_complete_state_handler.cc
@@ -56,9 +56,16 @@
if (!state_.has_repair_complete() && !RetrieveState()) {
state_.set_allocated_repair_complete(new RepairCompleteState);
}
+ power_cable_timer_.Start(
+ FROM_HERE, kReportPowerCableInterval, this,
+ &RepairCompleteStateHandler::SendPowerCableStateSignal);
return RMAD_ERROR_OK;
}
+void RepairCompleteStateHandler::CleanUpState() {
+ power_cable_timer_.Stop();
+}
+
BaseStateHandler::GetNextStateCaseReply
RepairCompleteStateHandler::GetNextStateCase(const RmadState& state) {
if (!state.has_repair_complete()) {
@@ -102,20 +109,20 @@
switch (state.repair_complete().shutdown()) {
case RepairCompleteState::RMAD_REPAIR_COMPLETE_REBOOT:
// Wait for a while before reboot.
- timer_.Start(FROM_HERE, kShutdownDelay, this,
- &RepairCompleteStateHandler::Reboot);
+ action_timer_.Start(FROM_HERE, kShutdownDelay, this,
+ &RepairCompleteStateHandler::Reboot);
return {.error = RMAD_ERROR_EXPECT_REBOOT,
.state_case = GetStateCase()};
case RepairCompleteState::RMAD_REPAIR_COMPLETE_SHUTDOWN:
// Wait for a while before shutdown.
- timer_.Start(FROM_HERE, kShutdownDelay, this,
- &RepairCompleteStateHandler::Shutdown);
+ action_timer_.Start(FROM_HERE, kShutdownDelay, this,
+ &RepairCompleteStateHandler::Shutdown);
return {.error = RMAD_ERROR_EXPECT_SHUTDOWN,
.state_case = GetStateCase()};
case RepairCompleteState::RMAD_REPAIR_COMPLETE_BATTERY_CUTOFF:
// Wait for a while before cutoff.
- timer_.Start(FROM_HERE, kShutdownDelay, this,
- &RepairCompleteStateHandler::Cutoff);
+ action_timer_.Start(FROM_HERE, kShutdownDelay, this,
+ &RepairCompleteStateHandler::Cutoff);
return {.error = RMAD_ERROR_EXPECT_SHUTDOWN,
.state_case = GetStateCase()};
default:
@@ -134,8 +141,8 @@
LOG(ERROR) << "Failed to request powerwash";
return NextStateCaseWrapper(RMAD_ERROR_POWERWASH_FAILED);
}
- timer_.Start(FROM_HERE, kShutdownDelay, this,
- &RepairCompleteStateHandler::Reboot);
+ action_timer_.Start(FROM_HERE, kShutdownDelay, this,
+ &RepairCompleteStateHandler::Reboot);
return NextStateCaseWrapper(GetStateCase(), RMAD_ERROR_EXPECT_REBOOT,
AdditionalActivity::REBOOT);
}
@@ -170,4 +177,10 @@
}
}
+void RepairCompleteStateHandler::SendPowerCableStateSignal() {
+ // TODO(chenghan): This is currently fake.
+ CHECK(power_cable_signal_sender_);
+ power_cable_signal_sender_->Run(true);
+}
+
} // namespace rmad
diff --git a/rmad/state_handler/repair_complete_state_handler.h b/rmad/state_handler/repair_complete_state_handler.h
index b34d30f..3ebfb0f 100644
--- a/rmad/state_handler/repair_complete_state_handler.h
+++ b/rmad/state_handler/repair_complete_state_handler.h
@@ -8,6 +8,7 @@
#include "rmad/state_handler/base_state_handler.h"
#include <memory>
+#include <utility>
#include <base/files/file_path.h>
#include <base/timer/timer.h>
@@ -22,6 +23,9 @@
// Wait for 5 seconds before reboot/shutdown/cutoff.
static constexpr base::TimeDelta kShutdownDelay =
base::TimeDelta::FromSeconds(5);
+ // Report power cable state every second.
+ static constexpr base::TimeDelta kReportPowerCableInterval =
+ base::TimeDelta::FromSeconds(1);
explicit RepairCompleteStateHandler(scoped_refptr<JsonStore> json_store);
// Used to inject |working_dir_path_| and mocked |power_manager_client_|,
@@ -35,7 +39,13 @@
ASSIGN_STATE(RmadState::StateCase::kRepairComplete);
SET_UNREPEATABLE;
+ void RegisterSignalSender(
+ std::unique_ptr<base::RepeatingCallback<bool(bool)>> callback) override {
+ power_cable_signal_sender_ = std::move(callback);
+ }
+
RmadErrorCode InitializeState() override;
+ void CleanUpState() override;
GetNextStateCaseReply GetNextStateCase(const RmadState& state) override;
protected:
@@ -45,11 +55,15 @@
void Reboot();
void Shutdown();
void Cutoff();
+ void SendPowerCableStateSignal();
base::FilePath working_dir_path_;
std::unique_ptr<PowerManagerClient> power_manager_client_;
std::unique_ptr<MetricsUtils> metrics_utils_;
- base::OneShotTimer timer_;
+ std::unique_ptr<base::RepeatingCallback<bool(bool)>>
+ power_cable_signal_sender_;
+ base::OneShotTimer action_timer_;
+ base::RepeatingTimer power_cable_timer_;
};
namespace fake {
diff --git a/rmad/state_handler/repair_complete_state_handler_test.cc b/rmad/state_handler/repair_complete_state_handler_test.cc
index e1945dd..c08e186 100644
--- a/rmad/state_handler/repair_complete_state_handler_test.cc
+++ b/rmad/state_handler/repair_complete_state_handler_test.cc
@@ -29,6 +29,12 @@
class RepairCompleteStateHandlerTest : public StateHandlerTest {
public:
+ // Helper class to mock the callback function to send signal.
+ class SignalSender {
+ public:
+ MOCK_METHOD(bool, SendPowerCableStateSignal, (bool), (const));
+ };
+
scoped_refptr<RepairCompleteStateHandler> CreateStateHandler(
bool* reboot_called,
bool* shutdown_called,
@@ -54,9 +60,17 @@
ON_CALL(*mock_metrics_utils, Record(_, _))
.WillByDefault(DoAll(Assign(metrics_called, true),
Return(record_metrics_success)));
- return base::MakeRefCounted<RepairCompleteStateHandler>(
+ auto handler = base::MakeRefCounted<RepairCompleteStateHandler>(
json_store_, GetTempDirPath(), std::move(mock_power_manager_client),
std::move(mock_metrics_utils));
+ auto callback = std::make_unique<base::RepeatingCallback<bool(bool)>>(
+ base::BindRepeating(&SignalSender::SendPowerCableStateSignal,
+ base::Unretained(&signal_sender_)));
+ handler->RegisterSignalSender(std::move(callback));
+
+ ON_CALL(signal_sender_, SendPowerCableStateSignal(_))
+ .WillByDefault(Return(true));
+ return handler;
}
base::FilePath GetPowerwashRequestFilePath() const {
@@ -76,6 +90,8 @@
}
protected:
+ NiceMock<SignalSender> signal_sender_;
+
// Variables for TaskRunner.
base::test::SingleThreadTaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
@@ -533,6 +549,9 @@
EXPECT_FALSE(base::PathExists(GetPowerwashRequestFilePath()));
EXPECT_FALSE(base::PathExists(GetCutoffRequestFilePath()));
+ // Stop the polling timer.
+ handler->CleanUpState();
+
// Check that the power cycle won't be called if the state file cannot be
// cleared.
task_environment_.FastForwardUntilNoTasksRemain();