recovery: Provide sideload cancellation

We can't use InterruptWaitKey() as it hangs recovery
when called from the minadbd listener thread, so provide
our own 'CancelWaitKey' implementation.
[forkbomb: rework for Q]

Squashed:
  recovery: Move sideload (non)cancellation to its own key

   * We use KEY_REFRESH for actually refreshing menus, which is
     useful when handling hotpluggable storage.
     We don't want that to interact with the sideload menu.

  Change-Id: Id7f5c06385e613648b3f727fc5e91eb3206406cf

Change-Id: I13f0c9ae5444652a2141442ef24258679a78d320
diff --git a/install/adb_install.cpp b/install/adb_install.cpp
index b12e529..cf2fe60 100644
--- a/install/adb_install.cpp
+++ b/install/adb_install.cpp
@@ -111,6 +111,7 @@
         break;
       }
     }
+    ui->CancelWaitKey();
 
     auto package =
         Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME,
@@ -277,7 +278,7 @@
 //                               b11. exit the listening loop
 //
 static void CreateMinadbdServiceAndExecuteCommands(
-    RecoveryUI* ui, const std::map<MinadbdCommand, CommandFunction>& command_map,
+    Device* device, const std::map<MinadbdCommand, CommandFunction>& command_map,
     bool rescue_mode) {
   signal(SIGPIPE, SIG_IGN);
 
@@ -317,8 +318,23 @@
     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<std::string> headers{ rescue_mode ? "Rescue mode" : "ADB Sideload" };
+    std::vector<std::string> 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 @@
     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.