minadbd: Support `adb reboot` under sideload/rescue modes.
Bug: 128415917
Test: Run the following commands under sideload and rescue modes
respectively.
$ adb reboot
$ adb reboot bootloader
$ adb reboot recovery
$ adb reboot rescue
$ adb reboot invalid
Change-Id: I84daf63e3360b7b4a0af5e055149a4f54e10ba90
Merged-In: I84daf63e3360b7b4a0af5e055149a4f54e10ba90
(cherry picked from commit 10f441a9dbb91be3124f455439631abcf8e96cde)
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp
index f6aff71..9b1999d 100644
--- a/minadbd/minadbd_services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -64,7 +64,7 @@
sideload_mount_point = path;
}
-static bool WriteCommandToFd(MinadbdCommands cmd, int fd) {
+static bool WriteCommandToFd(MinadbdCommand cmd, int fd) {
char message[kMinadbdMessageSize];
memcpy(message, kMinadbdCommandPrefix, strlen(kMinadbdStatusPrefix));
android::base::put_unaligned(message + strlen(kMinadbdStatusPrefix), cmd);
@@ -109,7 +109,7 @@
LOG(INFO) << "sideload-host file size " << file_size << ", block size " << block_size;
- if (!WriteCommandToFd(MinadbdCommands::kInstall, minadbd_socket)) {
+ if (!WriteCommandToFd(MinadbdCommand::kInstall, minadbd_socket)) {
return kMinadbdSocketIOError;
}
@@ -175,7 +175,45 @@
}
}
+// Reboots into the given target. We don't reboot directly from minadbd, but going through recovery
+// instead. This allows recovery to finish all the pending works (clear BCB, save logs etc) before
+// the reboot.
+static void RebootHostService(unique_fd /* sfd */, const std::string& target) {
+ MinadbdCommand command;
+ if (target == "bootloader") {
+ command = MinadbdCommand::kRebootBootloader;
+ } else if (target == "rescue") {
+ command = MinadbdCommand::kRebootRescue;
+ } else if (target == "recovery") {
+ command = MinadbdCommand::kRebootRecovery;
+ } else if (target == "fastboot") {
+ command = MinadbdCommand::kRebootFastboot;
+ } else {
+ command = MinadbdCommand::kRebootAndroid;
+ }
+ if (!WriteCommandToFd(command, minadbd_socket)) {
+ exit(kMinadbdSocketIOError);
+ }
+ MinadbdCommandStatus status;
+ if (!WaitForCommandStatus(minadbd_socket, &status)) {
+ exit(kMinadbdMessageFormatError);
+ }
+}
+
unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport */) {
+ // Common services that are supported both in sideload and rescue modes.
+ if (ConsumePrefix(&name, "reboot:")) {
+ // "reboot:<target>", where target must be one of the following.
+ std::string args(name);
+ if (args.empty() || args == "bootloader" || args == "rescue" || args == "recovery" ||
+ args == "fastboot") {
+ return create_service_thread("reboot",
+ std::bind(RebootHostService, std::placeholders::_1, args));
+ }
+ return unique_fd{};
+ }
+
+ // Rescue-specific services.
if (rescue_mode) {
if (ConsumePrefix(&name, "rescue-install:")) {
// rescue-install:<file-size>:<block-size>
@@ -191,6 +229,7 @@
return unique_fd{};
}
+ // Sideload-specific services.
if (name.starts_with("sideload:")) {
// This exit status causes recovery to print a special error message saying to use a newer adb
// (that supports sideload-host).