diff --git a/install/adb_install.cpp b/install/adb_install.cpp index 5948e795..9101e40c 100644 --- a/install/adb_install.cpp +++ b/install/adb_install.cpp @@ -111,6 +111,7 @@ static auto AdbInstallPackageHandler(Device* device, InstallResult* result) { break; } } + ui->CancelWaitKey(); auto package = Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME, @@ -277,7 +278,7 @@ static void ListenAndExecuteMinadbdCommands( // b11. exit the listening loop // static void CreateMinadbdServiceAndExecuteCommands( - RecoveryUI* ui, const std::map& command_map, + Device* device, const std::map& command_map, bool rescue_mode) { signal(SIGPIPE, SIG_IGN); @@ -317,8 +318,23 @@ static void CreateMinadbdServiceAndExecuteCommands( return; } + RecoveryUI* ui = device->GetUI(); std::thread listener_thread(ListenAndExecuteMinadbdCommands, ui, child, std::move(recovery_socket), std::ref(command_map)); + + if (ui->IsTextVisible()) { + std::vector headers{ rescue_mode ? "Rescue mode" : "ADB Sideload" }; + std::vector entries{ "Cancel" }; + size_t chosen_item = ui->ShowMenu( + headers, entries, 0, true, + std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); + + if (chosen_item != Device::kDoSideload) { + // Kill minadbd if 'cancel' was selected, to abort sideload. + kill(child, SIGKILL); + } + } + if (listener_thread.joinable()) { listener_thread.join(); } @@ -377,7 +393,7 @@ InstallResult ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinActi ui->Print("\n\nWaiting for rescue commands...\n"); } - CreateMinadbdServiceAndExecuteCommands(ui, command_map, rescue_mode); + CreateMinadbdServiceAndExecuteCommands(device, 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/recovery_ui/device.cpp b/recovery_ui/device.cpp index 1c335d15..ec5433d5 100644 --- a/recovery_ui/device.cpp +++ b/recovery_ui/device.cpp @@ -92,6 +92,9 @@ int Device::HandleMenuKey(int key, bool visible) { case KEY_POWER: return kInvokeItem; + case KEY_AGAIN: + return kDoSideload; + default: // If you have all of the above buttons, any other buttons // are ignored. Otherwise, any button cycles the highlight. diff --git a/recovery_ui/include/recovery_ui/device.h b/recovery_ui/include/recovery_ui/device.h index 76166f09..81563471 100644 --- a/recovery_ui/include/recovery_ui/device.h +++ b/recovery_ui/include/recovery_ui/device.h @@ -35,6 +35,7 @@ class Device { static constexpr const int kHighlightUp = -2; static constexpr const int kHighlightDown = -3; static constexpr const int kInvokeItem = -4; + static constexpr const int kDoSideload = -5; // ENTER vs REBOOT: The latter will trigger a reboot that goes through bootloader, which allows // using a new bootloader / recovery image if applicable. For example, REBOOT_RESCUE goes from diff --git a/recovery_ui/include/recovery_ui/ui.h b/recovery_ui/include/recovery_ui/ui.h index 20ea9807..9bb1b600 100644 --- a/recovery_ui/include/recovery_ui/ui.h +++ b/recovery_ui/include/recovery_ui/ui.h @@ -166,6 +166,7 @@ class RecoveryUI { // KeyError::INTERRUPTED on a key interrupt. virtual int WaitKey(); + virtual void CancelWaitKey(); // Wakes up the UI if it is waiting on key input, causing WaitKey to return KeyError::INTERRUPTED. virtual void InterruptKey(); diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp index ee3cbb13..992a6142 100644 --- a/recovery_ui/screen_ui.cpp +++ b/recovery_ui/screen_ui.cpp @@ -1277,10 +1277,16 @@ size_t ScreenRecoveryUI::ShowMenu(std::unique_ptr&& menu, bool menu_only, break; case Device::kNoAction: break; + case Device::kDoSideload: + chosen_item = Device::kDoSideload; + break; } } else if (!menu_only) { chosen_item = action; } + if (chosen_item == Device::kDoSideload) { + break; + } } menu_.reset(); diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp index 18f1d019..92c3901c 100644 --- a/recovery_ui/ui.cpp +++ b/recovery_ui/ui.cpp @@ -533,6 +533,10 @@ int RecoveryUI::WaitKey() { return key; } +void RecoveryUI::CancelWaitKey() { + EnqueueKey(KEY_AGAIN); +} + void RecoveryUI::InterruptKey() { { std::lock_guard lg(key_queue_mutex);