summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2017-02-24 04:06:53 +0100
committerTao Bao <tbao@google.com>2017-03-08 00:35:12 +0100
commitfc5499f22bd9b30affca08e584411012f71b6e9c (patch)
tree80131d47bb390fe5d54587e7e2257ada9725d6e8
parentMerge "recovery: Add the missing #include." (diff)
downloadandroid_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.tar
android_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.tar.gz
android_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.tar.bz2
android_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.tar.lz
android_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.tar.xz
android_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.tar.zst
android_bootable_recovery-fc5499f22bd9b30affca08e584411012f71b6e9c.zip
-rw-r--r--device.cpp2
-rw-r--r--device.h152
-rw-r--r--recovery.cpp135
3 files changed, 142 insertions, 147 deletions
diff --git a/device.cpp b/device.cpp
index e717dddf7..61501869e 100644
--- a/device.cpp
+++ b/device.cpp
@@ -60,7 +60,7 @@ Device::BuiltinAction Device::InvokeMenuItem(int menu_position) {
return menu_position < 0 ? NO_ACTION : MENU_ACTIONS[menu_position];
}
-int Device::HandleMenuKey(int key, int visible) {
+int Device::HandleMenuKey(int key, bool visible) {
if (!visible) {
return kNoAction;
}
diff --git a/device.h b/device.h
index 08dfcdff4..639e2bf57 100644
--- a/device.h
+++ b/device.h
@@ -20,96 +20,90 @@
#include "ui.h"
class Device {
- public:
- explicit Device(RecoveryUI* ui) : ui_(ui) { }
- virtual ~Device() { }
+ public:
+ explicit Device(RecoveryUI* ui) : ui_(ui) {}
+ virtual ~Device() {}
- // Called to obtain the UI object that should be used to display
- // the recovery user interface for this device. You should not
- // have called Init() on the UI object already, the caller will do
- // that after this method returns.
- virtual RecoveryUI* GetUI() { return ui_; }
+ // Called to obtain the UI object that should be used to display the recovery user interface for
+ // this device. You should not have called Init() on the UI object already, the caller will do
+ // that after this method returns.
+ virtual RecoveryUI* GetUI() {
+ return ui_;
+ }
- // Called when recovery starts up (after the UI has been obtained
- // and initialized and after the arguments have been parsed, but
- // before anything else).
- virtual void StartRecovery() { };
+ // Called when recovery starts up (after the UI has been obtained and initialized and after the
+ // arguments have been parsed, but before anything else).
+ virtual void StartRecovery() {};
- // Called from the main thread when recovery is at the main menu
- // and waiting for input, and a key is pressed. (Note that "at"
- // the main menu does not necessarily mean the menu is visible;
- // recovery will be at the main menu with it invisible after an
- // unsuccessful operation [ie OTA package failure], or if recovery
- // is started with no command.)
- //
- // key is the code of the key just pressed. (You can call
- // IsKeyPressed() on the RecoveryUI object you returned from GetUI
- // if you want to find out if other keys are held down.)
- //
- // visible is true if the menu is visible.
- //
- // Return one of the defined constants below in order to:
- //
- // - move the menu highlight (kHighlight{Up,Down})
- // - invoke the highlighted item (kInvokeItem)
- // - do nothing (kNoAction)
- // - invoke a specific action (a menu position: any non-negative number)
- virtual int HandleMenuKey(int key, int visible);
+ // Called from the main thread when recovery is at the main menu and waiting for input, and a key
+ // is pressed. (Note that "at" the main menu does not necessarily mean the menu is visible;
+ // recovery will be at the main menu with it invisible after an unsuccessful operation [ie OTA
+ // package failure], or if recovery is started with no command.)
+ //
+ // 'key' is the code of the key just pressed. (You can call IsKeyPressed() on the RecoveryUI
+ // object you returned from GetUI if you want to find out if other keys are held down.)
+ //
+ // 'visible' is true if the menu is visible.
+ //
+ // Returns one of the defined constants below in order to:
+ //
+ // - move the menu highlight (kHighlight{Up,Down})
+ // - invoke the highlighted item (kInvokeItem)
+ // - do nothing (kNoAction)
+ // - invoke a specific action (a menu position: any non-negative number)
+ virtual int HandleMenuKey(int key, bool visible);
- enum BuiltinAction {
- NO_ACTION = 0,
- REBOOT = 1,
- APPLY_SDCARD = 2,
- // APPLY_CACHE was 3.
- APPLY_ADB_SIDELOAD = 4,
- WIPE_DATA = 5,
- WIPE_CACHE = 6,
- REBOOT_BOOTLOADER = 7,
- SHUTDOWN = 8,
- VIEW_RECOVERY_LOGS = 9,
- MOUNT_SYSTEM = 10,
- RUN_GRAPHICS_TEST = 11,
- };
+ enum BuiltinAction {
+ NO_ACTION = 0,
+ REBOOT = 1,
+ APPLY_SDCARD = 2,
+ // APPLY_CACHE was 3.
+ APPLY_ADB_SIDELOAD = 4,
+ WIPE_DATA = 5,
+ WIPE_CACHE = 6,
+ REBOOT_BOOTLOADER = 7,
+ SHUTDOWN = 8,
+ VIEW_RECOVERY_LOGS = 9,
+ MOUNT_SYSTEM = 10,
+ RUN_GRAPHICS_TEST = 11,
+ };
- // Return the list of menu items (an array of strings,
- // NULL-terminated). The menu_position passed to InvokeMenuItem
- // will correspond to the indexes into this array.
- virtual const char* const* GetMenuItems();
+ // Return the list of menu items (an array of strings, NULL-terminated). The menu_position passed
+ // to InvokeMenuItem will correspond to the indexes into this array.
+ virtual const char* const* GetMenuItems();
- // Perform a recovery action selected from the menu.
- // 'menu_position' will be the item number of the selected menu
- // item, or a non-negative number returned from
- // device_handle_key(). The menu will be hidden when this is
- // called; implementations can call ui_print() to print
- // information to the screen. If the menu position is one of the
- // builtin actions, you can just return the corresponding enum
- // value. If it is an action specific to your device, you
- // actually perform it here and return NO_ACTION.
- virtual BuiltinAction InvokeMenuItem(int menu_position);
+ // Perform a recovery action selected from the menu. 'menu_position' will be the item number of
+ // the selected menu item, or a non-negative number returned from HandleMenuKey(). The menu will
+ // be hidden when this is called; implementations can call ui_print() to print information to the
+ // screen. If the menu position is one of the builtin actions, you can just return the
+ // corresponding enum value. If it is an action specific to your device, you actually perform it
+ // here and return NO_ACTION.
+ virtual BuiltinAction InvokeMenuItem(int menu_position);
- static const int kNoAction = -1;
- static const int kHighlightUp = -2;
- static const int kHighlightDown = -3;
- static const int kInvokeItem = -4;
+ static const int kNoAction = -1;
+ static const int kHighlightUp = -2;
+ static const int kHighlightDown = -3;
+ static const int kInvokeItem = -4;
- // Called before and after we do a wipe data/factory reset operation,
- // either via a reboot from the main system with the --wipe_data flag,
- // or when the user boots into recovery image manually and selects the
- // option from the menu, to perform whatever device-specific wiping
- // actions are needed.
- // Return true on success; returning false from PreWipeData will prevent
- // the regular wipe, and returning false from PostWipeData will cause
- // the wipe to be considered a failure.
- virtual bool PreWipeData() { return true; }
- virtual bool PostWipeData() { return true; }
+ // Called before and after we do a wipe data/factory reset operation, either via a reboot from the
+ // main system with the --wipe_data flag, or when the user boots into recovery image manually and
+ // selects the option from the menu, to perform whatever device-specific wiping actions as needed.
+ // Returns true on success; returning false from PreWipeData will prevent the regular wipe, and
+ // returning false from PostWipeData will cause the wipe to be considered a failure.
+ virtual bool PreWipeData() {
+ return true;
+ }
- private:
- RecoveryUI* ui_;
+ virtual bool PostWipeData() {
+ return true;
+ }
+
+ private:
+ RecoveryUI* ui_;
};
-// The device-specific library must define this function (or the
-// default one will be used, if there is no device-specific library).
-// It returns the Device object that recovery should use.
+// The device-specific library must define this function (or the default one will be used, if there
+// is no device-specific library). It returns the Device object that recovery should use.
Device* make_device();
#endif // _DEVICE_H
diff --git a/recovery.cpp b/recovery.cpp
index 618a2e8c7..b5cd3484b 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -607,54 +607,55 @@ static bool erase_volume(const char* volume) {
return (result == 0);
}
-static int
-get_menu_selection(const char* const * headers, const char* const * items,
- int menu_only, int initial_selection, Device* device) {
- // throw away keys pressed previously, so user doesn't
- // accidentally trigger menu items.
- ui->FlushKeys();
-
- ui->StartMenu(headers, items, initial_selection);
- int selected = initial_selection;
- int chosen_item = -1;
-
- while (chosen_item < 0) {
- int key = ui->WaitKey();
- int visible = ui->IsTextVisible();
-
- if (key == -1) { // ui_wait_key() timed out
- if (ui->WasTextEverVisible()) {
- continue;
- } else {
- LOG(INFO) << "timed out waiting for key input; rebooting.";
- ui->EndMenu();
- return 0; // XXX fixme
- }
- }
+// Display a menu with the specified 'headers' and 'items'. Device specific HandleMenuKey() may
+// return a positive number beyond the given range. Caller sets 'menu_only' to true to ensure only
+// a menu item gets selected. 'initial_selection' controls the initial cursor location.
+static int get_menu_selection(const char* const* headers, const char* const* items, bool menu_only,
+ int initial_selection, Device* device) {
+ // Throw away keys pressed previously, so user doesn't accidentally trigger menu items.
+ ui->FlushKeys();
+
+ ui->StartMenu(headers, items, initial_selection);
+ int selected = initial_selection;
+ int chosen_item = -1;
+
+ while (chosen_item < 0) {
+ int key = ui->WaitKey();
+
+ if (key == -1) { // ui_wait_key() timed out
+ if (ui->WasTextEverVisible()) {
+ continue;
+ } else {
+ LOG(INFO) << "timed out waiting for key input; rebooting.";
+ ui->EndMenu();
+ return 0; // XXX fixme
+ }
+ }
- int action = device->HandleMenuKey(key, visible);
-
- if (action < 0) {
- switch (action) {
- case Device::kHighlightUp:
- selected = ui->SelectMenu(--selected);
- break;
- case Device::kHighlightDown:
- selected = ui->SelectMenu(++selected);
- break;
- case Device::kInvokeItem:
- chosen_item = selected;
- break;
- case Device::kNoAction:
- break;
- }
- } else if (!menu_only) {
- chosen_item = action;
- }
+ bool visible = ui->IsTextVisible();
+ int action = device->HandleMenuKey(key, visible);
+
+ if (action < 0) {
+ switch (action) {
+ case Device::kHighlightUp:
+ selected = ui->SelectMenu(--selected);
+ break;
+ case Device::kHighlightDown:
+ selected = ui->SelectMenu(++selected);
+ break;
+ case Device::kInvokeItem:
+ chosen_item = selected;
+ break;
+ case Device::kNoAction:
+ break;
+ }
+ } else if (!menu_only) {
+ chosen_item = action;
}
+ }
- ui->EndMenu();
- return chosen_item;
+ ui->EndMenu();
+ return chosen_item;
}
// Returns the selected filename, or an empty string.
@@ -699,7 +700,7 @@ static std::string browse_directory(const std::string& path, Device* device) {
int chosen_item = 0;
while (true) {
- chosen_item = get_menu_selection(headers, entries, 1, chosen_item, device);
+ chosen_item = get_menu_selection(headers, entries, true, chosen_item, device);
const std::string& item = zips[chosen_item];
if (chosen_item == 0) {
@@ -726,7 +727,7 @@ static bool yes_no(Device* device, const char* question1, const char* question2)
const char* headers[] = { question1, question2, NULL };
const char* items[] = { " No", " Yes", NULL };
- int chosen_item = get_menu_selection(headers, items, 1, 0, device);
+ int chosen_item = get_menu_selection(headers, items, true, 0, device);
return (chosen_item == 1);
}
@@ -749,25 +750,25 @@ static bool wipe_data(Device* device) {
}
static bool prompt_and_wipe_data(Device* device) {
- const char* const headers[] = {
- "Boot halted, user data is corrupt",
- "Wipe all user data to recover",
- NULL
- };
- const char* const items[] = {
- "Retry boot",
- "Wipe user data",
- NULL
- };
- for (;;) {
- int chosen_item = get_menu_selection(headers, items, 1, 0, device);
- if (chosen_item != 1) {
- return true; // Just reboot, no wipe; not a failure, user asked for it
- }
- if (ask_to_wipe_data(device)) {
- return wipe_data(device);
- }
+ const char* const headers[] = {
+ "Boot halted, user data is corrupt",
+ "Wipe all user data to recover",
+ NULL
+ };
+ const char* const items[] = {
+ "Retry boot",
+ "Wipe user data",
+ NULL
+ };
+ for (;;) {
+ int chosen_item = get_menu_selection(headers, items, true, 0, device);
+ if (chosen_item != 1) {
+ return true; // Just reboot, no wipe; not a failure, user asked for it
+ }
+ if (ask_to_wipe_data(device)) {
+ return wipe_data(device);
}
+ }
}
// Return true on success.
@@ -961,7 +962,7 @@ static void choose_recovery_file(Device* device) {
int chosen_item = 0;
while (true) {
- chosen_item = get_menu_selection(headers, menu_entries.data(), 1, chosen_item, device);
+ chosen_item = get_menu_selection(headers, menu_entries.data(), true, chosen_item, device);
if (entries[chosen_item] == "Back") break;
ui->ShowFile(entries[chosen_item].c_str());
@@ -1110,7 +1111,7 @@ prompt_and_wait(Device* device, int status) {
}
ui->SetProgressType(RecoveryUI::EMPTY);
- int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), 0, 0, device);
+ int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), false, 0, device);
// device-specific code may take some action here. It may
// return one of the core actions handled in the switch