recovery: Fix the FIXME in get_menu_selection().

It used to return a REBOOT action on timeout, until the CL in commit
daefc1d442fb421606680feb9aeb59c133f4c427 that redefined the return value
of get_menu_selection() (changing from action to a menu index).

Prior to this CL, it was returning 0 (i.e. the value of Device::REBOOT)
to trigger the reboot. This CL specifies a return value of -1 to
indicate the timeout.

Test: Boot into a user build recovery; it reboots automatically on
      timeout (120 sec).
Change-Id: I4aedb7a4628bf258017078fe73eb8b48a21d0ea8
diff --git a/recovery.cpp b/recovery.cpp
index b5cd348..91c511a 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -609,26 +609,26 @@
 
 // Display a menu with the specified 'headers' and 'items'. Device specific HandleMenuKey() may
 // return a positive number beyond the given range. Caller sets 'menu_only' to true to ensure only
-// a menu item gets selected. 'initial_selection' controls the initial cursor location.
+// a menu item gets selected. 'initial_selection' controls the initial cursor location. Returns the
+// (non-negative) chosen item number, or -1 if timed out waiting for input.
 static int get_menu_selection(const char* const* headers, const char* const* items, bool menu_only,
                               int initial_selection, Device* device) {
   // Throw away keys pressed previously, so user doesn't accidentally trigger menu items.
   ui->FlushKeys();
 
   ui->StartMenu(headers, items, initial_selection);
+
   int selected = initial_selection;
   int chosen_item = -1;
-
   while (chosen_item < 0) {
     int key = ui->WaitKey();
-
-    if (key == -1) {  // ui_wait_key() timed out
+    if (key == -1) {  // WaitKey() timed out.
       if (ui->WasTextEverVisible()) {
         continue;
       } else {
-        LOG(INFO) << "timed out waiting for key input; rebooting.";
+        LOG(INFO) << "Timed out waiting for key input; rebooting.";
         ui->EndMenu();
-        return 0;  // XXX fixme
+        return -1;
       }
     }
 
@@ -1091,114 +1091,109 @@
     return result;
 }
 
-// Return REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER.  Returning NO_ACTION
-// means to take the default, which is to reboot or shutdown depending
-// on if the --shutdown_after flag was passed to recovery.
-static Device::BuiltinAction
-prompt_and_wait(Device* device, int status) {
-    for (;;) {
-        finish_recovery();
-        switch (status) {
-            case INSTALL_SUCCESS:
-            case INSTALL_NONE:
-                ui->SetBackground(RecoveryUI::NO_COMMAND);
-                break;
+// Returns REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER. Returning NO_ACTION means to take the default,
+// which is to reboot or shutdown depending on if the --shutdown_after flag was passed to recovery.
+static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
+  for (;;) {
+    finish_recovery();
+    switch (status) {
+      case INSTALL_SUCCESS:
+      case INSTALL_NONE:
+        ui->SetBackground(RecoveryUI::NO_COMMAND);
+        break;
 
-            case INSTALL_ERROR:
-            case INSTALL_CORRUPT:
-                ui->SetBackground(RecoveryUI::ERROR);
-                break;
-        }
-        ui->SetProgressType(RecoveryUI::EMPTY);
-
-        int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), false, 0, device);
-
-        // 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 = device->InvokeMenuItem(chosen_item);
-
-        bool should_wipe_cache = false;
-        switch (chosen_action) {
-            case Device::NO_ACTION:
-                break;
-
-            case Device::REBOOT:
-            case Device::SHUTDOWN:
-            case Device::REBOOT_BOOTLOADER:
-                return chosen_action;
-
-            case Device::WIPE_DATA:
-                if (ui->IsTextVisible()) {
-                    if (ask_to_wipe_data(device)) {
-                        wipe_data(device);
-                    }
-                } else {
-                    wipe_data(device);
-                    return Device::NO_ACTION;
-                }
-                break;
-
-            case Device::WIPE_CACHE:
-                wipe_cache(ui->IsTextVisible(), device);
-                if (!ui->IsTextVisible()) return Device::NO_ACTION;
-                break;
-
-            case Device::APPLY_ADB_SIDELOAD:
-            case Device::APPLY_SDCARD:
-                {
-                    bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
-                    if (adb) {
-                        status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
-                    } else {
-                        status = apply_from_sdcard(device, &should_wipe_cache);
-                    }
-
-                    if (status == INSTALL_SUCCESS && should_wipe_cache) {
-                        if (!wipe_cache(false, device)) {
-                            status = INSTALL_ERROR;
-                        }
-                    }
-
-                    if (status != INSTALL_SUCCESS) {
-                        ui->SetBackground(RecoveryUI::ERROR);
-                        ui->Print("Installation aborted.\n");
-                        copy_logs();
-                    } else if (!ui->IsTextVisible()) {
-                        return Device::NO_ACTION;  // reboot if logs aren't visible
-                    } else {
-                        ui->Print("\nInstall from %s complete.\n", adb ? "ADB" : "SD card");
-                    }
-                }
-                break;
-
-            case Device::VIEW_RECOVERY_LOGS:
-                choose_recovery_file(device);
-                break;
-
-            case Device::RUN_GRAPHICS_TEST:
-                run_graphics_test();
-                break;
-
-            case Device::MOUNT_SYSTEM:
-                // For a system image built with the root directory (i.e.
-                // system_root_image == "true"), we mount it to /system_root, and symlink /system
-                // to /system_root/system to make adb shell work (the symlink is created through
-                // the build system).
-                // Bug: 22855115
-                if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
-                    if (ensure_path_mounted_at("/", "/system_root") != -1) {
-                        ui->Print("Mounted /system.\n");
-                    }
-                } else {
-                    if (ensure_path_mounted("/system") != -1) {
-                        ui->Print("Mounted /system.\n");
-                    }
-                }
-
-                break;
-        }
+      case INSTALL_ERROR:
+      case INSTALL_CORRUPT:
+        ui->SetBackground(RecoveryUI::ERROR);
+        break;
     }
+    ui->SetProgressType(RecoveryUI::EMPTY);
+
+    int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), false, 0, device);
+
+    // 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 == -1) ? Device::REBOOT : device->InvokeMenuItem(chosen_item);
+
+    bool should_wipe_cache = false;
+    switch (chosen_action) {
+      case Device::NO_ACTION:
+        break;
+
+      case Device::REBOOT:
+      case Device::SHUTDOWN:
+      case Device::REBOOT_BOOTLOADER:
+        return chosen_action;
+
+      case Device::WIPE_DATA:
+        if (ui->IsTextVisible()) {
+          if (ask_to_wipe_data(device)) {
+            wipe_data(device);
+          }
+        } else {
+          wipe_data(device);
+          return Device::NO_ACTION;
+        }
+        break;
+
+      case Device::WIPE_CACHE:
+        wipe_cache(ui->IsTextVisible(), device);
+        if (!ui->IsTextVisible()) return Device::NO_ACTION;
+        break;
+
+      case Device::APPLY_ADB_SIDELOAD:
+      case Device::APPLY_SDCARD:
+        {
+          bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
+          if (adb) {
+            status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
+          } else {
+            status = apply_from_sdcard(device, &should_wipe_cache);
+          }
+
+          if (status == INSTALL_SUCCESS && should_wipe_cache) {
+            if (!wipe_cache(false, device)) {
+              status = INSTALL_ERROR;
+            }
+          }
+
+          if (status != INSTALL_SUCCESS) {
+            ui->SetBackground(RecoveryUI::ERROR);
+            ui->Print("Installation aborted.\n");
+            copy_logs();
+          } else if (!ui->IsTextVisible()) {
+            return Device::NO_ACTION;  // reboot if logs aren't visible
+          } else {
+            ui->Print("\nInstall from %s complete.\n", adb ? "ADB" : "SD card");
+          }
+        }
+        break;
+
+      case Device::VIEW_RECOVERY_LOGS:
+        choose_recovery_file(device);
+        break;
+
+      case Device::RUN_GRAPHICS_TEST:
+        run_graphics_test();
+        break;
+
+      case Device::MOUNT_SYSTEM:
+        // For a system image built with the root directory (i.e. system_root_image == "true"), we
+        // mount it to /system_root, and symlink /system to /system_root/system to make adb shell
+        // work (the symlink is created through the build system). (Bug: 22855115)
+        if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
+          if (ensure_path_mounted_at("/", "/system_root") != -1) {
+            ui->Print("Mounted /system.\n");
+          }
+        } else {
+          if (ensure_path_mounted("/system") != -1) {
+            ui->Print("Mounted /system.\n");
+          }
+        }
+        break;
+    }
+  }
 }
 
 static void