summaryrefslogtreecommitdiffstats
path: root/recovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'recovery.c')
-rw-r--r--recovery.c103
1 files changed, 61 insertions, 42 deletions
diff --git a/recovery.c b/recovery.c
index 0ff5d94d0..33cbc13d8 100644
--- a/recovery.c
+++ b/recovery.c
@@ -36,6 +36,7 @@
#include "minui/minui.h"
#include "minzip/DirUtil.h"
#include "roots.h"
+#include "recovery_ui.h"
static const struct option OPTIONS[] = {
{ "send_intent", required_argument, NULL, 's' },
@@ -206,6 +207,15 @@ get_args(int *argc, char ***argv) {
set_bootloader_message(&boot);
}
+static void
+set_sdcard_update_bootloader_message()
+{
+ struct bootloader_message boot;
+ memset(&boot, 0, sizeof(boot));
+ strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
+ strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
+ set_bootloader_message(&boot);
+}
// clear the recovery command and prepare to boot a (hopefully working) system,
// copy our log file to cache as well (for the system to read), and
@@ -272,26 +282,25 @@ erase_root(const char *root)
static void
prompt_and_wait()
{
- char* headers[] = { "Android system recovery <"
+ char* title[] = { "Android system recovery <"
EXPAND(RECOVERY_API_VERSION) "e>",
- "",
- "Use trackball to highlight;",
- "click to select.",
- "",
- NULL };
-
- // these constants correspond to elements of the items[] list.
-#define ITEM_REBOOT 0
-#define ITEM_APPLY_SDCARD 1
-#define ITEM_WIPE_DATA 2
-#define ITEM_WIPE_CACHE 3
- char* items[] = { "reboot system now [Home+Back]",
- "apply sdcard:update.zip [Alt+S]",
- "wipe data/factory reset [Alt+W]",
- "wipe cache partition",
+ "",
NULL };
- ui_start_menu(headers, items);
+ // count the number of lines in our title, plus the
+ // product-provided headers.
+ int count = 0;
+ char** p;
+ for (p = title; *p; ++p, ++count);
+ for (p = MENU_HEADERS; *p; ++p, ++count);
+
+ char** headers = malloc((count+1) * sizeof(char*));
+ char** h = headers;
+ for (p = title; *p; ++p, ++h) *h = *p;
+ for (p = MENU_HEADERS; *p; ++p, ++h) *h = *p;
+ *h = NULL;
+
+ ui_start_menu(headers, MENU_ITEMS);
int selected = 0;
int chosen_item = -1;
@@ -299,29 +308,28 @@ prompt_and_wait()
ui_reset_progress();
for (;;) {
int key = ui_wait_key();
- int alt = ui_key_pressed(KEY_LEFTALT) || ui_key_pressed(KEY_RIGHTALT);
int visible = ui_text_visible();
- if (key == KEY_DREAM_BACK && ui_key_pressed(KEY_DREAM_HOME)) {
- // Wait for the keys to be released, to avoid triggering
- // special boot modes (like coming back into recovery!).
- while (ui_key_pressed(KEY_DREAM_BACK) ||
- ui_key_pressed(KEY_DREAM_HOME)) {
- usleep(1000);
+ int action = device_handle_key(key, visible);
+
+ if (action < 0) {
+ switch (action) {
+ case HIGHLIGHT_UP:
+ --selected;
+ selected = ui_menu_select(selected);
+ break;
+ case HIGHLIGHT_DOWN:
+ ++selected;
+ selected = ui_menu_select(selected);
+ break;
+ case SELECT_ITEM:
+ chosen_item = selected;
+ break;
+ case NO_ACTION:
+ break;
}
- chosen_item = ITEM_REBOOT;
- } else if (alt && key == KEY_W) {
- chosen_item = ITEM_WIPE_DATA;
- } else if (alt && key == KEY_S) {
- chosen_item = ITEM_APPLY_SDCARD;
- } else if ((key == KEY_DOWN || key == KEY_VOLUMEDOWN) && visible) {
- ++selected;
- selected = ui_menu_select(selected);
- } else if ((key == KEY_UP || key == KEY_VOLUMEUP) && visible) {
- --selected;
- selected = ui_menu_select(selected);
- } else if (key == BTN_MOUSE && visible) {
- chosen_item = selected;
+ } else {
+ chosen_item = action;
}
if (chosen_item >= 0) {
@@ -329,12 +337,18 @@ prompt_and_wait()
// on the screen.
ui_end_menu();
+ // device-specific code may take some action here. It may
+ // return one of the core actions handled in the switch
+ // statement below.
+ chosen_item = device_perform_action(chosen_item);
+
switch (chosen_item) {
case ITEM_REBOOT:
return;
case ITEM_WIPE_DATA:
ui_print("\n-- Wiping data...\n");
+ device_wipe_data();
erase_root("DATA:");
erase_root("CACHE:");
ui_print("Data wipe complete.\n");
@@ -350,6 +364,7 @@ prompt_and_wait()
case ITEM_APPLY_SDCARD:
ui_print("\n-- Install from sdcard...\n");
+ set_sdcard_update_bootloader_message();
int status = install_package(SDCARD_PACKAGE_FILE);
if (status != INSTALL_SUCCESS) {
ui_set_background(BACKGROUND_ICON_ERROR);
@@ -358,8 +373,8 @@ prompt_and_wait()
return; // reboot if logs aren't visible
} else {
if (firmware_update_pending()) {
- ui_print("\nReboot via home+back or menu\n"
- "to complete installation.\n");
+ ui_print("\nReboot via menu to complete\n"
+ "installation.\n");
} else {
ui_print("\nInstall from sdcard complete.\n");
}
@@ -369,7 +384,7 @@ prompt_and_wait()
// if we didn't return from this function to reboot, show
// the menu again.
- ui_start_menu(headers, items);
+ ui_start_menu(headers, MENU_ITEMS);
selected = 0;
chosen_item = -1;
@@ -435,10 +450,14 @@ main(int argc, char **argv)
if (update_package != NULL) {
status = install_package(update_package);
if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
- } else if (wipe_data || wipe_cache) {
- if (wipe_data && erase_root("DATA:")) status = INSTALL_ERROR;
+ } else if (wipe_data) {
+ if (device_wipe_data()) status = INSTALL_ERROR;
+ if (erase_root("DATA:")) status = INSTALL_ERROR;
if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
+ } else if (wipe_cache) {
+ if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
+ if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
} else {
status = INSTALL_ERROR; // No command specified
}