diff options
Diffstat (limited to 'device.cpp')
-rw-r--r-- | device.cpp | 153 |
1 files changed, 134 insertions, 19 deletions
@@ -16,36 +16,133 @@ #include "device.h" -static const char* MENU_ITEMS[] = { - "Reboot system now", - "Reboot to bootloader", - "Apply update from ADB", - "Apply update from SD card", - "Wipe data/factory reset", +enum menu_action_type { + ACTION_NONE, + ACTION_SUBMENU, + ACTION_INVOKE +}; + +struct menu_entry; +struct menu { + const char** names; + const menu_entry* entries; +}; + +union menu_action { + const menu* submenu; + Device::BuiltinAction action; +}; + +struct menu_entry { + menu_action_type action_type; + const menu_action action; +}; + +static const char* WIPE_MENU_NAMES[] = { +#ifndef RELEASE_BUILD + "System reset (keep media)", +#endif + "Full factory reset", "Wipe cache partition", + nullptr +}; +static const menu_entry WIPE_MENU_ENTRIES[] = { +#ifndef RELEASE_BUILD + { ACTION_INVOKE, { .action = Device::WIPE_DATA } }, +#endif + { ACTION_INVOKE, { .action = Device::WIPE_FULL } }, + { ACTION_INVOKE, { .action = Device::WIPE_CACHE } }, + { ACTION_NONE, { .action = Device::NO_ACTION } } +}; +static const menu WIPE_MENU = { + WIPE_MENU_NAMES, + WIPE_MENU_ENTRIES +}; + +static const char* ADVANCED_MENU_NAMES[] = { + "Reboot recovery", +#ifdef DOWNLOAD_MODE + "Reboot to download mode", +#else + "Reboot to bootloader", +#endif +#ifndef RELEASE_BUILD "Mount /system", +#endif "View recovery logs", "Power off", - NULL + nullptr +}; +static const menu_entry ADVANCED_MENU_ENTRIES[] = { + { ACTION_INVOKE, { .action = Device::REBOOT_RECOVERY } }, +#ifdef DOWNLOAD_MODE + { ACTION_INVOKE, { .action = Device::REBOOT_BOOTLOADER } }, +#else + { ACTION_INVOKE, { .action = Device::REBOOT_BOOTLOADER } }, +#endif +#ifndef RELEASE_BUILD + { ACTION_INVOKE, { .action = Device::MOUNT_SYSTEM } }, +#endif + { ACTION_INVOKE, { .action = Device::VIEW_RECOVERY_LOGS } }, + { ACTION_INVOKE, { .action = Device::SHUTDOWN } }, + { ACTION_NONE, { .action = Device::NO_ACTION } } }; +static const menu ADVANCED_MENU = { + ADVANCED_MENU_NAMES, + ADVANCED_MENU_ENTRIES +}; + +static const char* MAIN_MENU_NAMES[] = { + "Reboot system now", + "Apply update", + "Factory reset", + "Advanced", + nullptr +}; +static const menu_entry MAIN_MENU_ENTRIES[] = { + { ACTION_INVOKE, { .action = Device::REBOOT } }, + { ACTION_INVOKE, { .action = Device::APPLY_UPDATE } }, + { ACTION_SUBMENU, { .submenu = &WIPE_MENU } }, + { ACTION_SUBMENU, { .submenu = &ADVANCED_MENU } }, + { ACTION_NONE, { .action = Device::NO_ACTION } } +}; +static const menu MAIN_MENU = { + MAIN_MENU_NAMES, + MAIN_MENU_ENTRIES +}; + +Device::Device(RecoveryUI* ui) : + ui_(ui) { + menu_stack.push(&MAIN_MENU); +} const char* const* Device::GetMenuItems() { - return MENU_ITEMS; + const menu* m = menu_stack.top(); + return m->names; } Device::BuiltinAction Device::InvokeMenuItem(int menu_position) { - switch (menu_position) { - case 0: return REBOOT; - case 1: return REBOOT_BOOTLOADER; - case 2: return APPLY_ADB_SIDELOAD; - case 3: return APPLY_SDCARD; - case 4: return WIPE_DATA; - case 5: return WIPE_CACHE; - case 6: return MOUNT_SYSTEM; - case 7: return VIEW_RECOVERY_LOGS; - case 8: return SHUTDOWN; - default: return NO_ACTION; + if (menu_position < 0) { + if (menu_position == Device::kGoBack) { + if (menu_stack.size() > 1) { + menu_stack.pop(); + } + } + return NO_ACTION; } + const menu* m = menu_stack.top(); + const menu_entry* entry = m->entries + menu_position; + if (entry->action_type == ACTION_SUBMENU) { + menu_stack.push(entry->action.submenu); + return NO_ACTION; + } + return entry->action.action; +} + +void Device::GoHome() { + while (menu_stack.size() > 1) { + menu_stack.pop(); + } } int Device::HandleMenuKey(int key, int visible) { @@ -53,19 +150,37 @@ int Device::HandleMenuKey(int key, int visible) { return kNoAction; } + if (key & KEY_FLAG_ABS) { + return key; + } + switch (key) { + case KEY_RIGHTSHIFT: case KEY_DOWN: case KEY_VOLUMEDOWN: + case KEY_MENU: return kHighlightDown; + case KEY_LEFTSHIFT: case KEY_UP: case KEY_VOLUMEUP: + case KEY_SEARCH: return kHighlightUp; case KEY_ENTER: case KEY_POWER: + case BTN_MOUSE: + case KEY_SEND: return kInvokeItem; + case KEY_BACKSPACE: + case KEY_BACK: + return kGoBack; + + case KEY_HOME: + case KEY_HOMEPAGE: + return kGoHome; + default: // If you have all of the above buttons, any other buttons // are ignored. Otherwise, any button cycles the highlight. |