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
diff --git a/tests/unit/screen_ui_test.cpp b/tests/unit/screen_ui_test.cpp
index 4c0a868..7d97a00 100644
--- a/tests/unit/screen_ui_test.cpp
+++ b/tests/unit/screen_ui_test.cpp
@@ -264,6 +264,10 @@
 }
 
 int TestableScreenRecoveryUI::WaitKey() {
+  if (IsKeyInterrupted()) {
+    return static_cast<int>(RecoveryUI::KeyError::INTERRUPTED);
+  }
+
   CHECK_LT(key_buffer_index_, key_buffer_.size());
   return static_cast<int>(key_buffer_[key_buffer_index_++]);
 }
@@ -391,7 +395,8 @@
   ui_->SetKeyBuffer({
       KeyCode::TIMEOUT,
   });
-  ASSERT_EQ(static_cast<size_t>(-1), ui_->ShowMenu(HEADERS, ITEMS, 3, true, nullptr));
+  ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT),
+            ui_->ShowMenu(HEADERS, ITEMS, 3, true, nullptr));
 }
 
 TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut_TextWasEverVisible) {
@@ -412,6 +417,38 @@
                                         std::placeholders::_1, std::placeholders::_2)));
 }
 
+TEST_F(ScreenRecoveryUITest, ShowMenuWithInterrupt) {
+  RETURN_IF_NO_GRAPHICS;
+
+  ASSERT_TRUE(ui_->Init(kTestLocale));
+  ui_->SetKeyBuffer({
+      KeyCode::UP,
+      KeyCode::DOWN,
+      KeyCode::UP,
+      KeyCode::DOWN,
+      KeyCode::ENTER,
+  });
+
+  ui_->InterruptKey();
+  ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
+            ui_->ShowMenu(HEADERS, ITEMS, 3, true,
+                          std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
+                                    std::placeholders::_1, std::placeholders::_2)));
+
+  ui_->SetKeyBuffer({
+      KeyCode::UP,
+      KeyCode::UP,
+      KeyCode::NO_OP,
+      KeyCode::NO_OP,
+      KeyCode::UP,
+      KeyCode::ENTER,
+  });
+  ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
+            ui_->ShowMenu(HEADERS, ITEMS, 0, true,
+                          std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
+                                    std::placeholders::_1, std::placeholders::_2)));
+}
+
 TEST_F(ScreenRecoveryUITest, LoadAnimation) {
   RETURN_IF_NO_GRAPHICS;