From b76af93ab56bc3296e01e65a6fe64a0622ab5b91 Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Tue, 22 May 2018 12:08:35 -0700 Subject: recovery: Add ability to interrupt UI Normally calling a UI method will block indefinitely until the UI is actually used. This creates a method to interrupt the UI, causing waitKey to return -2. This in turn, will cause ShowMenu to return -2. This allows switching between recovery and fastbootd via usb commands. Test: adb shell /data/nativetest64/recovery_unit_test/recovery_unit_test Bug: 78793464 Change-Id: I4c6c9aa18d79070877841a5c9818acf723fa6096 --- recovery.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'recovery.cpp') diff --git a/recovery.cpp b/recovery.cpp index 3284440da..3828e29b3 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -326,6 +326,11 @@ static std::string browse_directory(const std::string& path, Device* device) { headers, entries, chosen_item, true, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); + // Return if WaitKey() was interrupted. + if (chosen_item == static_cast(RecoveryUI::KeyError::INTERRUPTED)) { + return ""; + } + const std::string& item = entries[chosen_item]; if (chosen_item == 0) { // Go up but continue browsing (if the caller is browse_directory). @@ -401,6 +406,11 @@ static bool prompt_and_wipe_data(Device* device) { size_t chosen_item = ui->ShowMenu( headers, items, 0, true, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); + + // If ShowMenu() returned RecoveryUI::KeyError::INTERRUPTED, WaitKey() was interrupted. + if (chosen_item == static_cast(RecoveryUI::KeyError::INTERRUPTED)) { + return false; + } if (chosen_item != 1) { return true; // Just reboot, no wipe; not a failure, user asked for it } @@ -597,6 +607,11 @@ static void choose_recovery_file(Device* device) { chosen_item = ui->ShowMenu( headers, entries, chosen_item, true, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); + + // Handle WaitKey() interrupt. + if (chosen_item == static_cast(RecoveryUI::KeyError::INTERRUPTED)) { + break; + } if (entries[chosen_item] == "Back") break; ui->ShowFile(entries[chosen_item]); @@ -745,12 +760,16 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { size_t chosen_item = ui->ShowMenu( {}, device->GetMenuItems(), 0, false, std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2)); - + // Handle Interrupt key + if (chosen_item == static_cast(RecoveryUI::KeyError::INTERRUPTED)) { + return Device::KEY_INTERRUPTED; + } // Device-specific code may take some action here. It may return one of the core actions // handled in the switch statement below. - Device::BuiltinAction chosen_action = (chosen_item == static_cast(-1)) - ? Device::REBOOT - : device->InvokeMenuItem(chosen_item); + Device::BuiltinAction chosen_action = + (chosen_item == static_cast(RecoveryUI::KeyError::TIMED_OUT)) + ? Device::REBOOT + : device->InvokeMenuItem(chosen_item); bool should_wipe_cache = false; switch (chosen_action) { @@ -831,6 +850,9 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { } } break; + + case Device::KEY_INTERRUPTED: + return Device::KEY_INTERRUPTED; } } } @@ -1072,6 +1094,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorSetTitle(title_lines); + ui->ResetKeyInterruptStatus(); device->StartRecovery(); printf("Command:"); -- cgit v1.2.3