Allow entering rescue mode via recovery UI.
Only enabled on debuggable builds.
Bug: 128415917
Test: Sideload package on taimen.
Test: Choose "Enter rescue" from recovery UI.
Change-Id: I913dbdbcffd3179e6fa72ca862f74ca8f1364b02
Merged-In: I913dbdbcffd3179e6fa72ca862f74ca8f1364b02
(cherry picked from commit c6dc325e88a25201aa3856e6532c3ed14203a376)
diff --git a/install/adb_install.cpp b/install/adb_install.cpp
index 548b6e5..f430920 100644
--- a/install/adb_install.cpp
+++ b/install/adb_install.cpp
@@ -31,6 +31,7 @@
#include <atomic>
#include <functional>
#include <map>
+#include <vector>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -42,6 +43,7 @@
#include "fuse_sideload.h"
#include "install/install.h"
#include "minadbd_types.h"
+#include "otautil/sysutil.h"
#include "recovery_ui/ui.h"
using CommandFunction = std::function<bool()>;
@@ -228,7 +230,7 @@
// b11. exit the listening loop
//
static void CreateMinadbdServiceAndExecuteCommands(
- const std::map<MinadbdCommands, CommandFunction>& command_map) {
+ const std::map<MinadbdCommands, CommandFunction>& command_map, bool rescue_mode) {
signal(SIGPIPE, SIG_IGN);
android::base::unique_fd recovery_socket;
@@ -245,9 +247,16 @@
}
if (child == 0) {
recovery_socket.reset();
- execl("/system/bin/minadbd", "minadbd", "--socket_fd",
- std::to_string(minadbd_socket.release()).c_str(), nullptr);
-
+ std::vector<std::string> minadbd_commands = {
+ "/system/bin/minadbd",
+ "--socket_fd",
+ std::to_string(minadbd_socket.release()),
+ };
+ if (rescue_mode) {
+ minadbd_commands.push_back("--rescue");
+ }
+ auto exec_args = StringVectorToNullTerminatedArray(minadbd_commands);
+ execv(exec_args[0], exec_args.data());
_exit(EXIT_FAILURE);
}
@@ -280,7 +289,7 @@
signal(SIGPIPE, SIG_DFL);
}
-int apply_from_adb(RecoveryUI* ui) {
+int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode) {
// Save the usb state to restore after the sideload operation.
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
// Clean up state and stop adbd.
@@ -289,16 +298,20 @@
return INSTALL_ERROR;
}
- ui->Print(
- "\n\nNow send the package you want to apply\n"
- "to the device with \"adb sideload <filename>\"...\n");
+ if (!rescue_mode) {
+ ui->Print(
+ "\n\nNow send the package you want to apply\n"
+ "to the device with \"adb sideload <filename>\"...\n");
+ } else {
+ ui->Print("\n\nWaiting for rescue commands...\n");
+ }
int install_result = INSTALL_ERROR;
std::map<MinadbdCommands, CommandFunction> command_map{
{ MinadbdCommands::kInstall, std::bind(&AdbInstallPackageHandler, ui, &install_result) },
};
- CreateMinadbdServiceAndExecuteCommands(command_map);
+ CreateMinadbdServiceAndExecuteCommands(command_map, rescue_mode);
// Clean up before switching to the older state, for example setting the state
// to none sets sys/class/android_usb/android0/enable to 0.
diff --git a/install/include/install/adb_install.h b/install/include/install/adb_install.h
index f7b065b..208d0c7 100644
--- a/install/include/install/adb_install.h
+++ b/install/include/install/adb_install.h
@@ -18,4 +18,4 @@
#include <recovery_ui/ui.h>
-int apply_from_adb(RecoveryUI* ui);
+int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode);
diff --git a/minadbd/minadbd.cpp b/minadbd/minadbd.cpp
index 57158ad..c80d549 100644
--- a/minadbd/minadbd.cpp
+++ b/minadbd/minadbd.cpp
@@ -31,10 +31,13 @@
#include "minadbd_services.h"
#include "minadbd_types.h"
+using namespace std::string_literals;
+
int main(int argc, char** argv) {
android::base::InitLogging(argv, &android::base::StderrLogger);
// TODO(xunchang) implement a command parser
- if (argc != 3 || strcmp("--socket_fd", argv[1]) != 0) {
+ if ((argc != 3 && argc != 4) || argv[1] != "--socket_fd"s ||
+ (argc == 4 && argv[3] != "--rescue"s)) {
LOG(ERROR) << "minadbd has invalid arguments, argc: " << argc;
exit(kMinadbdArgumentsParsingError);
}
@@ -50,7 +53,12 @@
}
SetMinadbdSocketFd(socket_fd);
- adb_device_banner = "sideload";
+ if (argc == 4) {
+ SetMinadbdRescueMode(true);
+ adb_device_banner = "rescue";
+ } else {
+ adb_device_banner = "sideload";
+ }
signal(SIGPIPE, SIG_IGN);
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp
index 79e6fc4..f0bb70a 100644
--- a/minadbd/minadbd_services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -45,10 +45,16 @@
#include "sysdeps.h"
static int minadbd_socket = -1;
+static bool rescue_mode = false;
+
void SetMinadbdSocketFd(int socket_fd) {
minadbd_socket = socket_fd;
}
+void SetMinadbdRescueMode(bool rescue) {
+ rescue_mode = rescue;
+}
+
static bool WriteCommandToFd(MinadbdCommands cmd, int fd) {
char message[kMinadbdMessageSize];
memcpy(message, kMinadbdCommandPrefix, strlen(kMinadbdStatusPrefix));
diff --git a/minadbd/minadbd_services.h b/minadbd/minadbd_services.h
index 6835bd7..20e3410 100644
--- a/minadbd/minadbd_services.h
+++ b/minadbd/minadbd_services.h
@@ -17,3 +17,5 @@
#pragma once
void SetMinadbdSocketFd(int socket_fd);
+
+void SetMinadbdRescueMode(bool);
diff --git a/recovery.cpp b/recovery.cpp
index 0e6e497..ce29cb2 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -538,12 +538,20 @@
break;
}
case Device::APPLY_ADB_SIDELOAD:
- case Device::APPLY_SDCARD: {
+ case Device::APPLY_SDCARD:
+ case Device::ENTER_RESCUE: {
save_current_log = true;
- bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
- if (adb) {
- status = apply_from_adb(ui);
+
+ bool adb = true;
+ if (chosen_action == Device::ENTER_RESCUE) {
+ // Switch to graphics screen.
+ ui->ShowText(false);
+ status = ApplyFromAdb(ui, true /* rescue_mode */);
+ ui->ShowText(true);
+ } else if (chosen_action == Device::APPLY_ADB_SIDELOAD) {
+ status = ApplyFromAdb(ui, false /* rescue_mode */);
} else {
+ adb = false;
status = ApplyFromSdcard(device, ui);
}
@@ -926,7 +934,7 @@
if (!sideload_auto_reboot) {
ui->ShowText(true);
}
- status = apply_from_adb(ui);
+ status = ApplyFromAdb(ui, false /* rescue_mode */);
ui->Print("\nInstall from ADB complete (status: %d).\n", status);
if (sideload_auto_reboot) {
ui->Print("Rebooting automatically.\n");
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 5f3ab76..38e1db7 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -423,6 +423,10 @@
device->RemoveMenuItemForAction(Device::ENTER_FASTBOOT);
}
+ if (!is_ro_debuggable()) {
+ device->RemoveMenuItemForAction(Device::ENTER_RESCUE);
+ }
+
ui->SetBackground(RecoveryUI::NONE);
if (show_text) ui->ShowText(true);
diff --git a/recovery_ui/device.cpp b/recovery_ui/device.cpp
index ddb0118..e7ae1a3 100644
--- a/recovery_ui/device.cpp
+++ b/recovery_ui/device.cpp
@@ -37,6 +37,7 @@
{ "View recovery logs", Device::VIEW_RECOVERY_LOGS },
{ "Run graphics test", Device::RUN_GRAPHICS_TEST },
{ "Run locale test", Device::RUN_LOCALE_TEST },
+ { "Enter rescue", Device::ENTER_RESCUE },
{ "Power off", Device::SHUTDOWN },
};
diff --git a/recovery_ui/include/recovery_ui/device.h b/recovery_ui/include/recovery_ui/device.h
index 3c44510..8f17639 100644
--- a/recovery_ui/include/recovery_ui/device.h
+++ b/recovery_ui/include/recovery_ui/device.h
@@ -50,6 +50,7 @@
KEY_INTERRUPTED = 13,
ENTER_FASTBOOT = 14,
ENTER_RECOVERY = 15,
+ ENTER_RESCUE = 16,
};
explicit Device(RecoveryUI* ui);