From 50dd532934e8da9a4929d8dfae85265e5310a336 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Tue, 7 Mar 2017 14:57:04 -0800 Subject: 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 --- recovery.cpp | 193 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 94 insertions(+), 99 deletions(-) diff --git a/recovery.cpp b/recovery.cpp index b5cd3484b..91c511a6a 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -609,26 +609,26 @@ static bool erase_volume(const char* volume) { // 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 @@ static int apply_from_sdcard(Device* device, bool* wipe_cache) { 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); + 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); + 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); + // 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; + 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::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::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::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); - } + case Device::WIPE_CACHE: + wipe_cache(ui->IsTextVisible(), device); + if (!ui->IsTextVisible()) return Device::NO_ACTION; + break; - if (status == INSTALL_SUCCESS && should_wipe_cache) { - if (!wipe_cache(false, device)) { - status = INSTALL_ERROR; - } - } + 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) { - 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; + if (status == INSTALL_SUCCESS && should_wipe_cache) { + if (!wipe_cache(false, device)) { + status = INSTALL_ERROR; + } + } - case Device::VIEW_RECOVERY_LOGS: - choose_recovery_file(device); - break; + 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::RUN_GRAPHICS_TEST: - run_graphics_test(); - break; + case Device::VIEW_RECOVERY_LOGS: + choose_recovery_file(device); + 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"); - } - } + case Device::RUN_GRAPHICS_TEST: + run_graphics_test(); + break; - 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 -- cgit v1.2.3