recovery: split in submenus

Co-authored-by: aleasto <ales.astone@gmail.com>
Change-Id: I4426689634ca477955b67d2264999f450f02067f
diff --git a/recovery_ui/device.cpp b/recovery_ui/device.cpp
index d205f77..0952952 100644
--- a/recovery_ui/device.cpp
+++ b/recovery_ui/device.cpp
@@ -26,16 +26,21 @@
 
 #include "recovery_ui/ui.h"
 
-static std::vector<std::pair<std::string, Device::BuiltinAction>> g_menu_actions{
+typedef std::pair<std::string, Device::BuiltinAction> menu_action_t;
+
+static std::vector<std::string> g_main_header{};
+static std::vector<menu_action_t> g_main_actions{
   { "Reboot system now", Device::REBOOT },
+  { "Apply update", Device::MENU_UPDATE },
+  { "Factory reset", Device::MENU_WIPE },
+  { "Advanced", Device::MENU_ADVANCED },
+};
+
+static std::vector<std::string> g_advanced_header{ "Advanced options" };
+static std::vector<menu_action_t> g_advanced_actions{
+  { "Enter fastboot", Device::ENTER_FASTBOOT },
   { "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
   { "Reboot to recovery", Device::REBOOT_RECOVERY },
-  { "Enter fastboot", Device::ENTER_FASTBOOT },
-  { "Apply update from ADB", Device::APPLY_ADB_SIDELOAD },
-  { "Apply update from SD card", Device::APPLY_SDCARD },
-  { "Wipe data/factory reset", Device::WIPE_DATA },
-  { "Wipe cache partition", Device::WIPE_CACHE },
-  { "Wipe system partition", Device::WIPE_SYSTEM },
   { "Mount /system", Device::MOUNT_SYSTEM },
   { "View recovery logs", Device::VIEW_RECOVERY_LOGS },
   { "Run graphics test", Device::RUN_GRAPHICS_TEST },
@@ -44,11 +49,25 @@
   { "Power off", Device::SHUTDOWN },
 };
 
+static std::vector<std::string> g_wipe_header{ "Factory reset" };
+static std::vector<menu_action_t> g_wipe_actions{
+  { "Wipe data/factory reset", Device::WIPE_DATA },
+  { "Wipe cache partition", Device::WIPE_CACHE },
+  { "Wipe system partition", Device::WIPE_SYSTEM },
+};
+
+static std::vector<std::string> g_update_header{ "Apply update" };
+static std::vector<menu_action_t> g_update_actions{
+  { "Apply from ADB", Device::APPLY_ADB_SIDELOAD },
+  { "Choose from internal storage", Device::APPLY_SDCARD },
+};
+
+static std::vector<menu_action_t>* current_menu_ = &g_main_actions;
 static std::vector<std::string> g_menu_items;
 
 static void PopulateMenuItems() {
   g_menu_items.clear();
-  std::transform(g_menu_actions.cbegin(), g_menu_actions.cend(), std::back_inserter(g_menu_items),
+  std::transform(current_menu_->cbegin(), current_menu_->cend(), std::back_inserter(g_menu_items),
                  [](const auto& entry) { return entry.first; });
 }
 
@@ -56,22 +75,59 @@
   PopulateMenuItems();
 }
 
-void Device::RemoveMenuItemForAction(Device::BuiltinAction action) {
-  g_menu_actions.erase(
-      std::remove_if(g_menu_actions.begin(), g_menu_actions.end(),
-                     [action](const auto& entry) { return entry.second == action; }));
-  CHECK(!g_menu_actions.empty());
-
-  // Re-populate the menu items.
+void Device::GoHome() {
+  current_menu_ = &g_main_actions;
   PopulateMenuItems();
 }
 
+static void RemoveMenuItemForAction(std::vector<menu_action_t>& menu, Device::BuiltinAction action) {
+  menu.erase(
+      std::remove_if(menu.begin(), menu.end(),
+                     [action](const auto& entry) { return entry.second == action; }), menu.end());
+  CHECK(!menu.empty());
+}
+
+void Device::RemoveMenuItemForAction(Device::BuiltinAction action) {
+  ::RemoveMenuItemForAction(g_update_actions, action);
+  ::RemoveMenuItemForAction(g_wipe_actions, action);
+  ::RemoveMenuItemForAction(g_advanced_actions, action);
+}
+
 const std::vector<std::string>& Device::GetMenuItems() {
   return g_menu_items;
 }
 
+const std::vector<std::string>& Device::GetMenuHeaders() {
+  if (current_menu_ == &g_update_actions)
+      return g_update_header;
+  else if (current_menu_ == &g_wipe_actions)
+      return g_wipe_header;
+  else if (current_menu_ == &g_advanced_actions)
+      return g_advanced_header;
+  return g_main_header;
+}
+
 Device::BuiltinAction Device::InvokeMenuItem(size_t menu_position) {
-  return g_menu_actions[menu_position].second;
+  Device::BuiltinAction action = (*current_menu_)[menu_position].second;
+
+  if (action > MENU_BASE) {
+    switch (action) {
+      case Device::BuiltinAction::MENU_UPDATE:
+        current_menu_ = &g_update_actions;
+        break;
+      case Device::BuiltinAction::MENU_WIPE:
+        current_menu_ = &g_wipe_actions;
+        break;
+      case Device::BuiltinAction::MENU_ADVANCED:
+        current_menu_ = &g_advanced_actions;
+        break;
+      default:
+        break;
+    }
+    action = Device::BuiltinAction::NO_ACTION;
+    PopulateMenuItems();
+  }
+  return action;
 }
 
 int Device::HandleMenuKey(int key, bool visible) {