recovery: support selecting back arrow via volume buttons

Change-Id: I2180ab7b9f36c180595278ef30215239fa4d9786
diff --git a/recovery_ui/include/recovery_ui/screen_ui.h b/recovery_ui/include/recovery_ui/screen_ui.h
index b6b0b49..f11e635 100644
--- a/recovery_ui/include/recovery_ui/screen_ui.h
+++ b/recovery_ui/include/recovery_ui/screen_ui.h
@@ -92,7 +92,7 @@
  public:
   virtual ~Menu() = default;
   // Returns the current menu selection.
-  size_t selection() const;
+  int selection() const;
   // Sets the current selection to |sel|. Handle the overflow cases depending on if the menu is
   // scrollable.
   virtual int Select(int sel) = 0;
@@ -112,7 +112,7 @@
  protected:
   Menu(size_t initial_selection, const DrawInterface& draw_func);
   // Current menu selection.
-  size_t selection_;
+  int selection_;
   // Reference to the class that implements all the draw functions.
   const DrawInterface& draw_funcs_;
 };
@@ -444,6 +444,7 @@
 
   std::unique_ptr<GRSurface> lineage_logo_;
   std::unique_ptr<GRSurface> back_icon_;
+  std::unique_ptr<GRSurface> back_icon_sel_;
   std::unique_ptr<GRSurface> fastbootd_logo_;
 
   // current_icon_ points to one of the frames in intro_frames_ or loop_frames_, indexed by
diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp
index c3273db..470e22e 100644
--- a/recovery_ui/screen_ui.cpp
+++ b/recovery_ui/screen_ui.cpp
@@ -57,7 +57,7 @@
 Menu::Menu(size_t initial_selection, const DrawInterface& draw_func)
     : selection_(initial_selection), draw_funcs_(draw_func) {}
 
-size_t Menu::selection() const {
+int Menu::selection() const {
   return selection_;
 }
 
@@ -110,7 +110,7 @@
   }
 
   *cur_selection_str =
-      android::base::StringPrintf("Current item: %zu/%zu", selection_ + 1, ItemsCount());
+      android::base::StringPrintf("Current item: %d/%zu", selection_ + 1, ItemsCount());
   return true;
 }
 
@@ -119,12 +119,14 @@
   CHECK_LE(ItemsCount(), static_cast<size_t>(std::numeric_limits<int>::max()));
   int count = ItemsCount();
 
+  int min = IsMain() ? 0 : -1; // -1 is back arrow
+
   // Wraps the selection at boundary if the menu is not scrollable.
   if (!scrollable_) {
-    if (sel < 0) {
+    if (sel < min) {
       selection_ = count - 1;
     } else if (sel >= count) {
-      selection_ = 0;
+      selection_ = min;
     } else {
       selection_ = sel;
     }
@@ -132,15 +134,17 @@
     return selection_;
   }
 
-  if (sel < 0) {
-    selection_ = 0;
+  if (sel < min) {
+    selection_ = min;
   } else if (sel >= count) {
     selection_ = count - 1;
   } else {
-    if (static_cast<size_t>(sel) < menu_start_) {
-      menu_start_--;
-    } else if (static_cast<size_t>(sel) >= MenuEnd()) {
-      menu_start_++;
+    if (sel >= 0) {
+      if (static_cast<size_t>(sel) < menu_start_) {
+        menu_start_--;
+      } else if (static_cast<size_t>(sel) >= MenuEnd()) {
+        menu_start_++;
+      }
     }
     selection_ = sel;
   }
@@ -825,7 +829,8 @@
         auto icon_h = gr_get_height(back_icon_.get());
         auto icon_x = centered_x / 2 - icon_w / 2;
         auto icon_y = y - logo_height / 2 - icon_h / 2;
-        gr_blit(back_icon_.get(), 0, 0, icon_w, icon_h, icon_x, icon_y);
+        gr_blit(back_icon_sel_ && menu_->selection() == -1 ? back_icon_sel_.get() : back_icon_.get(),
+                0, 0, icon_w, icon_h, icon_x, icon_y);
       }
     } else {
       for (size_t i = 0; i < title_lines_.size(); i++) {
@@ -1022,6 +1027,7 @@
 
   lineage_logo_ = LoadBitmap("logo_image");
   back_icon_ = LoadBitmap("ic_back");
+  back_icon_sel_ = LoadBitmap("ic_back_sel");
   if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) ||
       android::base::GetBoolProperty("ro.fastbootd.available", false)) {
     fastbootd_logo_ = LoadBitmap("fastbootd");
@@ -1423,7 +1429,11 @@
           selected = ScrollMenu(1);
           break;
         case Device::kInvokeItem:
-          chosen_item = selected;
+          if (selected < 0) {
+            chosen_item = Device::kGoBack;
+          } else {
+            chosen_item = selected;
+          }
           break;
         case Device::kNoAction:
           break;
diff --git a/res-hdpi/images/ic_back_sel.png b/res-hdpi/images/ic_back_sel.png
new file mode 100644
index 0000000..2b154d1
--- /dev/null
+++ b/res-hdpi/images/ic_back_sel.png
Binary files differ
diff --git a/res-mdpi/images/ic_back_sel.png b/res-mdpi/images/ic_back_sel.png
new file mode 100644
index 0000000..4e8152c
--- /dev/null
+++ b/res-mdpi/images/ic_back_sel.png
Binary files differ
diff --git a/res-xhdpi/images/ic_back_sel.png b/res-xhdpi/images/ic_back_sel.png
new file mode 100644
index 0000000..20e5451
--- /dev/null
+++ b/res-xhdpi/images/ic_back_sel.png
Binary files differ
diff --git a/res-xxhdpi/images/ic_back_sel.png b/res-xxhdpi/images/ic_back_sel.png
new file mode 100644
index 0000000..50dc557
--- /dev/null
+++ b/res-xxhdpi/images/ic_back_sel.png
Binary files differ
diff --git a/res-xxxhdpi/images/ic_back_sel.png b/res-xxxhdpi/images/ic_back_sel.png
new file mode 100644
index 0000000..b7f604c
--- /dev/null
+++ b/res-xxxhdpi/images/ic_back_sel.png
Binary files differ