From c6dc325e88a25201aa3856e6532c3ed14203a376 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Tue, 16 Apr 2019 14:22:25 -0700 Subject: [PATCH] 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 --- install/adb_install.cpp | 31 +++++++++++++++++------- install/include/install/adb_install.h | 2 +- minadbd/minadbd.cpp | 12 +++++++-- minadbd/minadbd_services.cpp | 6 +++++ minadbd/minadbd_services.h | 2 ++ recovery.cpp | 18 ++++++++++---- recovery_main.cpp | 4 +++ recovery_ui/device.cpp | 1 + recovery_ui/include/recovery_ui/device.h | 1 + 9 files changed, 60 insertions(+), 17 deletions(-) diff --git a/install/adb_install.cpp b/install/adb_install.cpp index 548b6e5b..f430920a 100644 --- a/install/adb_install.cpp +++ b/install/adb_install.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -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; @@ -228,7 +230,7 @@ static void ListenAndExecuteMinadbdCommands( // b11. exit the listening loop // static void CreateMinadbdServiceAndExecuteCommands( - const std::map& command_map) { + const std::map& command_map, bool rescue_mode) { signal(SIGPIPE, SIG_IGN); android::base::unique_fd recovery_socket; @@ -245,9 +247,16 @@ static void CreateMinadbdServiceAndExecuteCommands( } if (child == 0) { recovery_socket.reset(); - execl("/system/bin/minadbd", "minadbd", "--socket_fd", - std::to_string(minadbd_socket.release()).c_str(), nullptr); - + std::vector 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 @@ static void CreateMinadbdServiceAndExecuteCommands( 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 @@ int apply_from_adb(RecoveryUI* ui) { return INSTALL_ERROR; } - ui->Print( - "\n\nNow send the package you want to apply\n" - "to the device with \"adb sideload \"...\n"); + if (!rescue_mode) { + ui->Print( + "\n\nNow send the package you want to apply\n" + "to the device with \"adb sideload \"...\n"); + } else { + ui->Print("\n\nWaiting for rescue commands...\n"); + } int install_result = INSTALL_ERROR; std::map 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 f7b065b6..208d0c78 100644 --- a/install/include/install/adb_install.h +++ b/install/include/install/adb_install.h @@ -18,4 +18,4 @@ #include -int apply_from_adb(RecoveryUI* ui); +int ApplyFromAdb(RecoveryUI* ui, bool rescue_mode); diff --git a/minadbd/minadbd.cpp b/minadbd/minadbd.cpp index 57158ad5..c80d5490 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 @@ int main(int argc, char** argv) { } 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 f2b65c09..eaf88ecc 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 6835bd77..20e3410c 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 0e6e4976..ce29cb27 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -538,12 +538,20 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { 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 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorShowText(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 5f3ab76d..38e1db73 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -423,6 +423,10 @@ int main(int argc, char** argv) { 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 ddb0118d..e7ae1a3e 100644 --- a/recovery_ui/device.cpp +++ b/recovery_ui/device.cpp @@ -37,6 +37,7 @@ static std::vector> g_menu_actions { "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 3c44510c..8f17639d 100644 --- a/recovery_ui/include/recovery_ui/device.h +++ b/recovery_ui/include/recovery_ui/device.h @@ -50,6 +50,7 @@ class Device { KEY_INTERRUPTED = 13, ENTER_FASTBOOT = 14, ENTER_RECOVERY = 15, + ENTER_RESCUE = 16, }; explicit Device(RecoveryUI* ui);