aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Bao2017-03-07 16:57:04 -0600
committerTao Bao2017-03-07 17:35:17 -0600
commit50dd532934e8da9a4929d8dfae85265e5310a336 (patch)
treefe8cd039e428522cee3b9731b17ccdc3bd8f6971 /recovery.cpp
parentfc5499f22bd9b30affca08e584411012f71b6e9c (diff)
downloadplatform-bootable-recovery-50dd532934e8da9a4929d8dfae85265e5310a336.tar.gz
platform-bootable-recovery-50dd532934e8da9a4929d8dfae85265e5310a336.tar.xz
platform-bootable-recovery-50dd532934e8da9a4929d8dfae85265e5310a336.zip
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
Diffstat (limited to 'recovery.cpp')
-rw-r--r--recovery.cpp193
1 files changed, 94 insertions, 99 deletions
diff --git a/recovery.cpp b/recovery.cpp
index b5cd3484..91c511a6 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -609,26 +609,26 @@ static bool erase_volume(const char* volume) {
609 609
610// Display a menu with the specified 'headers' and 'items'. Device specific HandleMenuKey() may 610// Display a menu with the specified 'headers' and 'items'. Device specific HandleMenuKey() may
611// return a positive number beyond the given range. Caller sets 'menu_only' to true to ensure only 611// return a positive number beyond the given range. Caller sets 'menu_only' to true to ensure only
612// a menu item gets selected. 'initial_selection' controls the initial cursor location. 612// a menu item gets selected. 'initial_selection' controls the initial cursor location. Returns the
613// (non-negative) chosen item number, or -1 if timed out waiting for input.
613static int get_menu_selection(const char* const* headers, const char* const* items, bool menu_only, 614static int get_menu_selection(const char* const* headers, const char* const* items, bool menu_only,
614 int initial_selection, Device* device) { 615 int initial_selection, Device* device) {
615 // Throw away keys pressed previously, so user doesn't accidentally trigger menu items. 616 // Throw away keys pressed previously, so user doesn't accidentally trigger menu items.
616 ui->FlushKeys(); 617 ui->FlushKeys();
617 618
618 ui->StartMenu(headers, items, initial_selection); 619 ui->StartMenu(headers, items, initial_selection);
620
619 int selected = initial_selection; 621 int selected = initial_selection;
620 int chosen_item = -1; 622 int chosen_item = -1;
621
622 while (chosen_item < 0) { 623 while (chosen_item < 0) {
623 int key = ui->WaitKey(); 624 int key = ui->WaitKey();
624 625 if (key == -1) { // WaitKey() timed out.
625 if (key == -1) { // ui_wait_key() timed out
626 if (ui->WasTextEverVisible()) { 626 if (ui->WasTextEverVisible()) {
627 continue; 627 continue;
628 } else { 628 } else {
629 LOG(INFO) << "timed out waiting for key input; rebooting."; 629 LOG(INFO) << "Timed out waiting for key input; rebooting.";
630 ui->EndMenu(); 630 ui->EndMenu();
631 return 0; // XXX fixme 631 return -1;
632 } 632 }
633 } 633 }
634 634
@@ -1091,114 +1091,109 @@ static int apply_from_sdcard(Device* device, bool* wipe_cache) {
1091 return result; 1091 return result;
1092} 1092}
1093 1093
1094// Return REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER. Returning NO_ACTION 1094// Returns REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER. Returning NO_ACTION means to take the default,
1095// means to take the default, which is to reboot or shutdown depending 1095// which is to reboot or shutdown depending on if the --shutdown_after flag was passed to recovery.
1096// on if the --shutdown_after flag was passed to recovery. 1096static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
1097static Device::BuiltinAction 1097 for (;;) {
1098prompt_and_wait(Device* device, int status) { 1098 finish_recovery();
1099 for (;;) { 1099 switch (status) {
1100 finish_recovery(); 1100 case INSTALL_SUCCESS:
1101 switch (status) { 1101 case INSTALL_NONE:
1102 case INSTALL_SUCCESS: 1102 ui->SetBackground(RecoveryUI::NO_COMMAND);
1103 case INSTALL_NONE: 1103 break;
1104 ui->SetBackground(RecoveryUI::NO_COMMAND);
1105 break;
1106 1104
1107 case INSTALL_ERROR: 1105 case INSTALL_ERROR:
1108 case INSTALL_CORRUPT: 1106 case INSTALL_CORRUPT:
1109 ui->SetBackground(RecoveryUI::ERROR); 1107 ui->SetBackground(RecoveryUI::ERROR);
1110 break; 1108 break;
1111 } 1109 }
1112 ui->SetProgressType(RecoveryUI::EMPTY); 1110 ui->SetProgressType(RecoveryUI::EMPTY);
1113 1111
1114 int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), false, 0, device); 1112 int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), false, 0, device);
1115 1113
1116 // device-specific code may take some action here. It may 1114 // Device-specific code may take some action here. It may return one of the core actions
1117 // return one of the core actions handled in the switch 1115 // handled in the switch statement below.
1118 // statement below. 1116 Device::BuiltinAction chosen_action =
1119 Device::BuiltinAction chosen_action = device->InvokeMenuItem(chosen_item); 1117 (chosen_item == -1) ? Device::REBOOT : device->InvokeMenuItem(chosen_item);
1120 1118
1121 bool should_wipe_cache = false; 1119 bool should_wipe_cache = false;
1122 switch (chosen_action) { 1120 switch (chosen_action) {
1123 case Device::NO_ACTION: 1121 case Device::NO_ACTION:
1124 break; 1122 break;
1125 1123
1126 case Device::REBOOT: 1124 case Device::REBOOT:
1127 case Device::SHUTDOWN: 1125 case Device::SHUTDOWN:
1128 case Device::REBOOT_BOOTLOADER: 1126 case Device::REBOOT_BOOTLOADER:
1129 return chosen_action; 1127 return chosen_action;
1130 1128
1131 case Device::WIPE_DATA: 1129 case Device::WIPE_DATA:
1132 if (ui->IsTextVisible()) { 1130 if (ui->IsTextVisible()) {
1133 if (ask_to_wipe_data(device)) { 1131 if (ask_to_wipe_data(device)) {
1134 wipe_data(device); 1132 wipe_data(device);
1135 } 1133 }
1136 } else { 1134 } else {
1137 wipe_data(device); 1135 wipe_data(device);
1138 return Device::NO_ACTION; 1136 return Device::NO_ACTION;
1139 } 1137 }
1140 break; 1138 break;
1141
1142 case Device::WIPE_CACHE:
1143 wipe_cache(ui->IsTextVisible(), device);
1144 if (!ui->IsTextVisible()) return Device::NO_ACTION;
1145 break;
1146 1139
1147 case Device::APPLY_ADB_SIDELOAD: 1140 case Device::WIPE_CACHE:
1148 case Device::APPLY_SDCARD: 1141 wipe_cache(ui->IsTextVisible(), device);
1149 { 1142 if (!ui->IsTextVisible()) return Device::NO_ACTION;
1150 bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD); 1143 break;
1151 if (adb) {
1152 status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
1153 } else {
1154 status = apply_from_sdcard(device, &should_wipe_cache);
1155 }
1156 1144
1157 if (status == INSTALL_SUCCESS && should_wipe_cache) { 1145 case Device::APPLY_ADB_SIDELOAD:
1158 if (!wipe_cache(false, device)) { 1146 case Device::APPLY_SDCARD:
1159 status = INSTALL_ERROR; 1147 {
1160 } 1148 bool adb = (chosen_action == Device::APPLY_ADB_SIDELOAD);
1161 } 1149 if (adb) {
1150 status = apply_from_adb(ui, &should_wipe_cache, TEMPORARY_INSTALL_FILE);
1151 } else {
1152 status = apply_from_sdcard(device, &should_wipe_cache);
1153 }
1162 1154
1163 if (status != INSTALL_SUCCESS) { 1155 if (status == INSTALL_SUCCESS && should_wipe_cache) {
1164 ui->SetBackground(RecoveryUI::ERROR); 1156 if (!wipe_cache(false, device)) {
1165 ui->Print("Installation aborted.\n"); 1157 status = INSTALL_ERROR;
1166 copy_logs(); 1158 }
1167 } else if (!ui->IsTextVisible()) { 1159 }
1168 return Device::NO_ACTION; // reboot if logs aren't visible
1169 } else {
1170 ui->Print("\nInstall from %s complete.\n", adb ? "ADB" : "SD card");
1171 }
1172 }
1173 break;
1174 1160
1175 case Device::VIEW_RECOVERY_LOGS: 1161 if (status != INSTALL_SUCCESS) {
1176 choose_recovery_file(device); 1162 ui->SetBackground(RecoveryUI::ERROR);
1177 break; 1163 ui->Print("Installation aborted.\n");
1164 copy_logs();
1165 } else if (!ui->IsTextVisible()) {
1166 return Device::NO_ACTION; // reboot if logs aren't visible
1167 } else {
1168 ui->Print("\nInstall from %s complete.\n", adb ? "ADB" : "SD card");
1169 }
1170 }
1171 break;
1178 1172
1179 case Device::RUN_GRAPHICS_TEST: 1173 case Device::VIEW_RECOVERY_LOGS:
1180 run_graphics_test(); 1174 choose_recovery_file(device);
1181 break; 1175 break;
1182 1176
1183 case Device::MOUNT_SYSTEM: 1177 case Device::RUN_GRAPHICS_TEST:
1184 // For a system image built with the root directory (i.e. 1178 run_graphics_test();
1185 // system_root_image == "true"), we mount it to /system_root, and symlink /system 1179 break;
1186 // to /system_root/system to make adb shell work (the symlink is created through
1187 // the build system).
1188 // Bug: 22855115
1189 if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
1190 if (ensure_path_mounted_at("/", "/system_root") != -1) {
1191 ui->Print("Mounted /system.\n");
1192 }
1193 } else {
1194 if (ensure_path_mounted("/system") != -1) {
1195 ui->Print("Mounted /system.\n");
1196 }
1197 }
1198 1180
1199 break; 1181 case Device::MOUNT_SYSTEM:
1182 // For a system image built with the root directory (i.e. system_root_image == "true"), we
1183 // mount it to /system_root, and symlink /system to /system_root/system to make adb shell
1184 // work (the symlink is created through the build system). (Bug: 22855115)
1185 if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
1186 if (ensure_path_mounted_at("/", "/system_root") != -1) {
1187 ui->Print("Mounted /system.\n");
1188 }
1189 } else {
1190 if (ensure_path_mounted("/system") != -1) {
1191 ui->Print("Mounted /system.\n");
1192 }
1200 } 1193 }
1194 break;
1201 } 1195 }
1196 }
1202} 1197}
1203 1198
1204static void 1199static void