aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--default_device.cpp4
-rw-r--r--device.h3
-rw-r--r--recovery.cpp55
3 files changed, 44 insertions, 18 deletions
diff --git a/default_device.cpp b/default_device.cpp
index 1f181318..a25f05f8 100644
--- a/default_device.cpp
+++ b/default_device.cpp
@@ -29,6 +29,8 @@ static const char* ITEMS[] = {"reboot system now",
29 "apply update from ADB", 29 "apply update from ADB",
30 "wipe data/factory reset", 30 "wipe data/factory reset",
31 "wipe cache partition", 31 "wipe cache partition",
32 "reboot to bootloader",
33 "power down",
32 NULL }; 34 NULL };
33 35
34class DefaultDevice : public Device { 36class DefaultDevice : public Device {
@@ -65,6 +67,8 @@ class DefaultDevice : public Device {
65 case 1: return APPLY_ADB_SIDELOAD; 67 case 1: return APPLY_ADB_SIDELOAD;
66 case 2: return WIPE_DATA; 68 case 2: return WIPE_DATA;
67 case 3: return WIPE_CACHE; 69 case 3: return WIPE_CACHE;
70 case 4: return REBOOT_BOOTLOADER;
71 case 5: return SHUTDOWN;
68 default: return NO_ACTION; 72 default: return NO_ACTION;
69 } 73 }
70 } 74 }
diff --git a/device.h b/device.h
index 583de75e..df71377c 100644
--- a/device.h
+++ b/device.h
@@ -66,7 +66,8 @@ class Device {
66 virtual int HandleMenuKey(int key, int visible) = 0; 66 virtual int HandleMenuKey(int key, int visible) = 0;
67 67
68 enum BuiltinAction { NO_ACTION, REBOOT, APPLY_EXT, APPLY_CACHE, 68 enum BuiltinAction { NO_ACTION, REBOOT, APPLY_EXT, APPLY_CACHE,
69 APPLY_ADB_SIDELOAD, WIPE_DATA, WIPE_CACHE }; 69 APPLY_ADB_SIDELOAD, WIPE_DATA, WIPE_CACHE,
70 REBOOT_BOOTLOADER, SHUTDOWN };
70 71
71 // Perform a recovery action selected from the menu. 72 // Perform a recovery action selected from the menu.
72 // 'menu_position' will be the item number of the selected menu 73 // 'menu_position' will be the item number of the selected menu
diff --git a/recovery.cpp b/recovery.cpp
index 8d373154..09af5f8b 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -771,7 +771,10 @@ wipe_data(int confirm, Device* device) {
771 ui->Print("Data wipe complete.\n"); 771 ui->Print("Data wipe complete.\n");
772} 772}
773 773
774static void 774// Return REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER. Returning NO_ACTION
775// means to take the default, which is to reboot or shutdown depending
776// on if the --shutdown_after flag was passed to recovery.
777static Device::BuiltinAction
775prompt_and_wait(Device* device, int status) { 778prompt_and_wait(Device* device, int status) {
776 const char* const* headers = prepend_title(device->GetMenuHeaders()); 779 const char* const* headers = prepend_title(device->GetMenuHeaders());
777 780
@@ -795,23 +798,28 @@ prompt_and_wait(Device* device, int status) {
795 // device-specific code may take some action here. It may 798 // device-specific code may take some action here. It may
796 // return one of the core actions handled in the switch 799 // return one of the core actions handled in the switch
797 // statement below. 800 // statement below.
798 chosen_item = device->InvokeMenuItem(chosen_item); 801 Device::BuiltinAction chosen_action = device->InvokeMenuItem(chosen_item);
799 802
800 int wipe_cache; 803 int wipe_cache;
801 switch (chosen_item) { 804 switch (chosen_action) {
805 case Device::NO_ACTION:
806 break;
807
802 case Device::REBOOT: 808 case Device::REBOOT:
803 return; 809 case Device::SHUTDOWN:
810 case Device::REBOOT_BOOTLOADER:
811 return chosen_action;
804 812
805 case Device::WIPE_DATA: 813 case Device::WIPE_DATA:
806 wipe_data(ui->IsTextVisible(), device); 814 wipe_data(ui->IsTextVisible(), device);
807 if (!ui->IsTextVisible()) return; 815 if (!ui->IsTextVisible()) return Device::NO_ACTION;
808 break; 816 break;
809 817
810 case Device::WIPE_CACHE: 818 case Device::WIPE_CACHE:
811 ui->Print("\n-- Wiping cache...\n"); 819 ui->Print("\n-- Wiping cache...\n");
812 erase_volume("/cache"); 820 erase_volume("/cache");
813 ui->Print("Cache wipe complete.\n"); 821 ui->Print("Cache wipe complete.\n");
814 if (!ui->IsTextVisible()) return; 822 if (!ui->IsTextVisible()) return Device::NO_ACTION;
815 break; 823 break;
816 824
817 case Device::APPLY_EXT: 825 case Device::APPLY_EXT:
@@ -829,7 +837,7 @@ prompt_and_wait(Device* device, int status) {
829 ui->SetBackground(RecoveryUI::ERROR); 837 ui->SetBackground(RecoveryUI::ERROR);
830 ui->Print("Installation aborted.\n"); 838 ui->Print("Installation aborted.\n");
831 } else if (!ui->IsTextVisible()) { 839 } else if (!ui->IsTextVisible()) {
832 return; // reboot if logs aren't visible 840 return Device::NO_ACTION; // reboot if logs aren't visible
833 } else { 841 } else {
834 ui->Print("\nInstall from sdcard complete.\n"); 842 ui->Print("\nInstall from sdcard complete.\n");
835 } 843 }
@@ -852,7 +860,7 @@ prompt_and_wait(Device* device, int status) {
852 ui->SetBackground(RecoveryUI::ERROR); 860 ui->SetBackground(RecoveryUI::ERROR);
853 ui->Print("Installation aborted.\n"); 861 ui->Print("Installation aborted.\n");
854 } else if (!ui->IsTextVisible()) { 862 } else if (!ui->IsTextVisible()) {
855 return; // reboot if logs aren't visible 863 return Device::NO_ACTION; // reboot if logs aren't visible
856 } else { 864 } else {
857 ui->Print("\nInstall from cache complete.\n"); 865 ui->Print("\nInstall from cache complete.\n");
858 } 866 }
@@ -867,7 +875,7 @@ prompt_and_wait(Device* device, int status) {
867 ui->Print("Installation aborted.\n"); 875 ui->Print("Installation aborted.\n");
868 copy_logs(); 876 copy_logs();
869 } else if (!ui->IsTextVisible()) { 877 } else if (!ui->IsTextVisible()) {
870 return; // reboot if logs aren't visible 878 return Device::NO_ACTION; // reboot if logs aren't visible
871 } else { 879 } else {
872 ui->Print("\nInstall from ADB complete.\n"); 880 ui->Print("\nInstall from ADB complete.\n");
873 } 881 }
@@ -1074,18 +1082,31 @@ main(int argc, char **argv) {
1074 copy_logs(); 1082 copy_logs();
1075 ui->SetBackground(RecoveryUI::ERROR); 1083 ui->SetBackground(RecoveryUI::ERROR);
1076 } 1084 }
1085 Device::BuiltinAction after = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
1077 if (status != INSTALL_SUCCESS || ui->IsTextVisible()) { 1086 if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
1078 prompt_and_wait(device, status); 1087 Device::BuiltinAction temp = prompt_and_wait(device, status);
1088 if (temp != Device::NO_ACTION) after = temp;
1079 } 1089 }
1080 1090
1081 // Otherwise, get ready to boot the main system... 1091 // Save logs and clean up before rebooting or shutting down.
1082 finish_recovery(send_intent); 1092 finish_recovery(send_intent);
1083 if (shutdown_after) { 1093
1084 ui->Print("Shutting down...\n"); 1094 switch (after) {
1085 property_set(ANDROID_RB_PROPERTY, "shutdown,"); 1095 case Device::SHUTDOWN:
1086 } else { 1096 ui->Print("Shutting down...\n");
1087 ui->Print("Rebooting...\n"); 1097 property_set(ANDROID_RB_PROPERTY, "shutdown,");
1088 property_set(ANDROID_RB_PROPERTY, "reboot,"); 1098 break;
1099
1100 case Device::REBOOT_BOOTLOADER:
1101 ui->Print("Rebooting to bootloader...\n");
1102 property_set(ANDROID_RB_PROPERTY, "reboot,bootloader");
1103 break;
1104
1105 default:
1106 ui->Print("Rebooting...\n");
1107 property_set(ANDROID_RB_PROPERTY, "reboot,");
1108 break;
1089 } 1109 }
1110 sleep(5); // should reboot before this finishes
1090 return EXIT_SUCCESS; 1111 return EXIT_SUCCESS;
1091} 1112}