confirm before wiping user data in recovery
When using the hidden menu to wipe data in recovery, confirm before starting the wipe. (This does not affect booting with the --wipe_data flag, or using Alt+W on dream with the menu hidden -- those still wipe data immediately.)
This commit is contained in:
170
recovery.c
170
recovery.c
@@ -276,34 +276,40 @@ erase_root(const char *root)
|
|||||||
return format_root_device(root);
|
return format_root_device(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static char**
|
||||||
prompt_and_wait()
|
prepend_title(char** headers) {
|
||||||
{
|
|
||||||
char* title[] = { "Android system recovery <"
|
char* title[] = { "Android system recovery <"
|
||||||
EXPAND(RECOVERY_API_VERSION) "e>",
|
EXPAND(RECOVERY_API_VERSION) "e>",
|
||||||
"",
|
"",
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
// count the number of lines in our title, plus the
|
// count the number of lines in our title, plus the
|
||||||
// product-provided headers.
|
// caller-provided headers.
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char** p;
|
char** p;
|
||||||
for (p = title; *p; ++p, ++count);
|
for (p = title; *p; ++p, ++count);
|
||||||
for (p = MENU_HEADERS; *p; ++p, ++count);
|
for (p = headers; *p; ++p, ++count);
|
||||||
|
|
||||||
char** headers = malloc((count+1) * sizeof(char*));
|
char** new_headers = malloc((count+1) * sizeof(char*));
|
||||||
char** h = headers;
|
char** h = new_headers;
|
||||||
for (p = title; *p; ++p, ++h) *h = *p;
|
for (p = title; *p; ++p, ++h) *h = *p;
|
||||||
for (p = MENU_HEADERS; *p; ++p, ++h) *h = *p;
|
for (p = headers; *p; ++p, ++h) *h = *p;
|
||||||
*h = NULL;
|
*h = NULL;
|
||||||
|
|
||||||
ui_start_menu(headers, MENU_ITEMS);
|
return new_headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_menu_selection(char** headers, char** items, int menu_only) {
|
||||||
|
// throw away keys pressed previously, so user doesn't
|
||||||
|
// accidentally trigger menu items.
|
||||||
|
ui_clear_key_queue();
|
||||||
|
|
||||||
|
ui_start_menu(headers, items);
|
||||||
int selected = 0;
|
int selected = 0;
|
||||||
int chosen_item = -1;
|
int chosen_item = -1;
|
||||||
|
|
||||||
finish_recovery(NULL);
|
while (chosen_item < 0) {
|
||||||
ui_reset_progress();
|
|
||||||
for (;;) {
|
|
||||||
int key = ui_wait_key();
|
int key = ui_wait_key();
|
||||||
int visible = ui_text_visible();
|
int visible = ui_text_visible();
|
||||||
|
|
||||||
@@ -325,72 +331,104 @@ prompt_and_wait()
|
|||||||
case NO_ACTION:
|
case NO_ACTION:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!menu_only) {
|
||||||
chosen_item = action;
|
chosen_item = action;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (chosen_item >= 0) {
|
ui_end_menu();
|
||||||
// turn off the menu, letting ui_print() to scroll output
|
return chosen_item;
|
||||||
// on the screen.
|
}
|
||||||
ui_end_menu();
|
|
||||||
|
|
||||||
// device-specific code may take some action here. It may
|
static void
|
||||||
// return one of the core actions handled in the switch
|
wipe_data(int confirm) {
|
||||||
// statement below.
|
if (confirm) {
|
||||||
chosen_item = device_perform_action(chosen_item);
|
static char** title_headers = NULL;
|
||||||
|
|
||||||
switch (chosen_item) {
|
if (title_headers == NULL) {
|
||||||
case ITEM_REBOOT:
|
char* headers[] = { "Confirm wipe of all user data?",
|
||||||
return;
|
" THIS CAN NOT BE UNDONE.",
|
||||||
|
"",
|
||||||
|
NULL };
|
||||||
|
title_headers = prepend_title(headers);
|
||||||
|
}
|
||||||
|
|
||||||
case ITEM_WIPE_DATA:
|
char* items[] = { " No",
|
||||||
ui_print("\n-- Wiping data...\n");
|
" No",
|
||||||
device_wipe_data();
|
" No",
|
||||||
erase_root("DATA:");
|
" No",
|
||||||
erase_root("CACHE:");
|
" No",
|
||||||
ui_print("Data wipe complete.\n");
|
" No",
|
||||||
if (!ui_text_visible()) return;
|
" No",
|
||||||
break;
|
" Yes -- delete all user data", // [7]
|
||||||
|
" No",
|
||||||
|
" No",
|
||||||
|
" No",
|
||||||
|
NULL };
|
||||||
|
|
||||||
case ITEM_WIPE_CACHE:
|
int chosen_item = get_menu_selection(title_headers, items, 1);
|
||||||
ui_print("\n-- Wiping cache...\n");
|
if (chosen_item != 7) {
|
||||||
erase_root("CACHE:");
|
return;
|
||||||
ui_print("Cache wipe complete.\n");
|
}
|
||||||
if (!ui_text_visible()) return;
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case ITEM_APPLY_SDCARD:
|
ui_print("\n-- Wiping data...\n");
|
||||||
ui_print("\n-- Install from sdcard...\n");
|
device_wipe_data();
|
||||||
set_sdcard_update_bootloader_message();
|
erase_root("DATA:");
|
||||||
int status = install_package(SDCARD_PACKAGE_FILE);
|
erase_root("CACHE:");
|
||||||
if (status != INSTALL_SUCCESS) {
|
ui_print("Data wipe complete.\n");
|
||||||
ui_set_background(BACKGROUND_ICON_ERROR);
|
}
|
||||||
ui_print("Installation aborted.\n");
|
|
||||||
} else if (!ui_text_visible()) {
|
static void
|
||||||
return; // reboot if logs aren't visible
|
prompt_and_wait()
|
||||||
} else {
|
{
|
||||||
if (firmware_update_pending()) {
|
char** headers = prepend_title(MENU_HEADERS);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
finish_recovery(NULL);
|
||||||
|
ui_reset_progress();
|
||||||
|
|
||||||
|
int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0);
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
wipe_data(ui_text_visible());
|
||||||
|
if (!ui_text_visible()) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ITEM_WIPE_CACHE:
|
||||||
|
ui_print("\n-- Wiping cache...\n");
|
||||||
|
erase_root("CACHE:");
|
||||||
|
ui_print("Cache wipe complete.\n");
|
||||||
|
if (!ui_text_visible()) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
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);
|
||||||
|
ui_print("Installation aborted.\n");
|
||||||
|
} else if (!ui_text_visible()) {
|
||||||
|
return; // reboot if logs aren't visible
|
||||||
|
} else {
|
||||||
|
if (firmware_update_pending()) {
|
||||||
ui_print("\nReboot via menu to complete\n"
|
ui_print("\nReboot via menu to complete\n"
|
||||||
"installation.\n");
|
"installation.\n");
|
||||||
} else {
|
} else {
|
||||||
ui_print("\nInstall from sdcard complete.\n");
|
ui_print("\nInstall from sdcard complete.\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
// if we didn't return from this function to reboot, show
|
|
||||||
// the menu again.
|
|
||||||
ui_start_menu(headers, MENU_ITEMS);
|
|
||||||
selected = 0;
|
|
||||||
chosen_item = -1;
|
|
||||||
|
|
||||||
finish_recovery(NULL);
|
|
||||||
ui_reset_progress();
|
|
||||||
|
|
||||||
// throw away keys pressed while the command was running,
|
|
||||||
// so user doesn't accidentally trigger menu items.
|
|
||||||
ui_clear_key_queue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user