am 6e435abf: Merge "Move the menu header out of the menu."

* commit '6e435abfeb7256b5ea82ca37166acf36e3f98085':
  Move the menu header out of the menu.
diff --git a/Android.mk b/Android.mk
index a34c265..0484065 100644
--- a/Android.mk
+++ b/Android.mk
@@ -72,6 +72,7 @@
     libminui \
     libpng \
     libfs_mgr \
+    libbase \
     libcutils \
     liblog \
     libselinux \
diff --git a/device.cpp b/device.cpp
index 024fc34..fd1a987 100644
--- a/device.cpp
+++ b/device.cpp
@@ -16,20 +16,6 @@
 
 #include "device.h"
 
-static const char* REGULAR_HEADERS[] = {
-    "Volume up/down move highlight.",
-    "Power button activates.",
-    "",
-    NULL
-};
-
-static const char* LONG_PRESS_HEADERS[] = {
-    "Any button cycles highlight.",
-    "Long-press activates.",
-    "",
-    NULL
-};
-
 static const char* MENU_ITEMS[] = {
     "Reboot system now",
     "Reboot to bootloader",
@@ -43,10 +29,6 @@
     NULL
 };
 
-const char* const* Device::GetMenuHeaders() {
-  return ui_->HasThreeButtons() ? REGULAR_HEADERS : LONG_PRESS_HEADERS;
-}
-
 const char* const* Device::GetMenuItems() {
   return MENU_ITEMS;
 }
diff --git a/device.h b/device.h
index 1507183..dad8ccd 100644
--- a/device.h
+++ b/device.h
@@ -70,12 +70,6 @@
         MOUNT_SYSTEM = 10,
     };
 
-    // Return the headers (an array of strings, one per line,
-    // NULL-terminated) for the main menu.  Typically these tell users
-    // what to push to move the selection and invoke the selected
-    // item.
-    virtual const char* const* GetMenuHeaders();
-
     // 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.
diff --git a/minui/graphics.cpp b/minui/graphics.cpp
index d7d6e8d..f240f4b 100644
--- a/minui/graphics.cpp
+++ b/minui/graphics.cpp
@@ -103,7 +103,7 @@
     }
 }
 
-void gr_text(int x, int y, const char *s, int bold)
+void gr_text(int x, int y, const char *s, bool bold)
 {
     GRFont* font = gr_font;
 
diff --git a/minui/minui.h b/minui/minui.h
index eca3a50..936f7ee 100644
--- a/minui/minui.h
+++ b/minui/minui.h
@@ -48,7 +48,7 @@
 void gr_clear();  // clear entire surface to current color
 void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
 void gr_fill(int x1, int y1, int x2, int y2);
-void gr_text(int x, int y, const char *s, int bold);
+void gr_text(int x, int y, const char *s, bool bold);
 void gr_texticon(int x, int y, gr_surface icon);
 int gr_measure(const char *s);
 void gr_font_size(int *x, int *y);
diff --git a/recovery.cpp b/recovery.cpp
index f7ae5e7..4dd8279 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -629,7 +629,7 @@
     z_size += d_size;
     zips[z_size] = NULL;
 
-    const char* headers[] = { "Choose a package to install:", path, "", NULL };
+    const char* headers[] = { "Choose a package to install:", path, NULL };
 
     char* result;
     int chosen_item = 0;
@@ -668,7 +668,7 @@
 }
 
 static bool yes_no(Device* device, const char* question1, const char* question2) {
-    const char* headers[] = { question1, question2, "", NULL };
+    const char* headers[] = { question1, question2, NULL };
     const char* items[] = { " No", " Yes", NULL };
 
     int chosen_item = get_menu_selection(headers, items, 1, 0, device);
@@ -743,7 +743,7 @@
         entries[n++] = filename;
     }
 
-    const char* headers[] = { "Select file to view", "", NULL };
+    const char* headers[] = { "Select file to view", NULL };
 
     while (true) {
         int chosen_item = get_menu_selection(headers, entries, 1, 0, device);
@@ -791,8 +791,6 @@
 // on if the --shutdown_after flag was passed to recovery.
 static Device::BuiltinAction
 prompt_and_wait(Device* device, int status) {
-    const char* const* headers = device->GetMenuHeaders();
-
     for (;;) {
         finish_recovery(NULL);
         switch (status) {
@@ -808,7 +806,7 @@
         }
         ui->SetProgressType(RecoveryUI::EMPTY);
 
-        int chosen_item = get_menu_selection(headers, device->GetMenuItems(), 0, 0, device);
+        int chosen_item = get_menu_selection(nullptr, device->GetMenuItems(), 0, 0, device);
 
         // device-specific code may take some action here.  It may
         // return one of the core actions handled in the switch
@@ -1038,10 +1036,6 @@
     property_list(print_property, NULL);
     printf("\n");
 
-    char recovery_build[PROPERTY_VALUE_MAX];
-    property_get("ro.build.display.id", recovery_build, "");
-
-    ui->Print("%s\n", recovery_build);
     ui->Print("Supported API: %d\n", RECOVERY_API_VERSION);
 
     int status = INSTALL_SUCCESS;
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 7679335..52f22c2 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -30,6 +30,8 @@
 
 #include <vector>
 
+#include "base/strings.h"
+#include "cutils/properties.h"
 #include "common.h"
 #include "device.h"
 #include "minui/minui.h"
@@ -66,7 +68,6 @@
     show_text_ever(false),
     menu(nullptr),
     show_menu(false),
-    menu_top(0),
     menu_items(0),
     menu_sel(0),
     animation_fps(20),
@@ -174,6 +175,9 @@
 
 void ScreenRecoveryUI::SetColor(UIElement e) {
     switch (e) {
+        case INFO:
+            gr_color(249, 194, 0, 255);
+            break;
         case HEADER:
             gr_color(247, 0, 6, 255);
             break;
@@ -188,7 +192,7 @@
             gr_color(255, 255, 255, 255);
             break;
         case LOG:
-            gr_color(249, 194, 0, 255);
+            gr_color(196, 196, 196, 255);
             break;
         case TEXT_FILL:
             gr_color(0, 0, 0, 160);
@@ -203,9 +207,31 @@
     SetColor(MENU);
     *y += 4;
     gr_fill(0, *y, gr_fb_width(), *y + 2);
-    *y += 8;
+    *y += 4;
 }
 
+void ScreenRecoveryUI::DrawTextLine(int* y, const char* line, bool bold) {
+    gr_text(4, *y, line, bold);
+    *y += char_height + 4;
+}
+
+void ScreenRecoveryUI::DrawTextLines(int* y, const char* const* lines) {
+    for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) {
+        DrawTextLine(y, lines[i], false);
+    }
+}
+
+static const char* REGULAR_HELP[] = {
+    "Use volume up/down and power.",
+    NULL
+};
+
+static const char* LONG_PRESS_HELP[] = {
+    "Any button cycles highlight.",
+    "Long-press activates.",
+    NULL
+};
+
 // Redraw everything on the screen.  Does not flip pages.
 // Should only be called with updateMutex locked.
 void ScreenRecoveryUI::draw_screen_locked() {
@@ -218,39 +244,49 @@
 
         int y = 0;
         if (show_menu) {
+            char recovery_fingerprint[PROPERTY_VALUE_MAX];
+            property_get("ro.bootimage.build.fingerprint", recovery_fingerprint, "");
+
+            SetColor(INFO);
+            DrawTextLine(&y, "Android Recovery", true);
+            for (auto& chunk : android::base::Split(recovery_fingerprint, ":")) {
+                DrawTextLine(&y, chunk.c_str(), false);
+            }
+            DrawTextLines(&y, HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP);
+
             SetColor(HEADER);
+            DrawTextLines(&y, menu_headers);
 
-            for (int i = 0; i < menu_top + menu_items; ++i) {
-                if (i == menu_top) DrawHorizontalRule(&y);
-
-                if (i == menu_top + menu_sel) {
-                    // draw the highlight bar
+            SetColor(MENU);
+            DrawHorizontalRule(&y);
+            y += 4;
+            for (int i = 0; i < menu_items; ++i) {
+                if (i == menu_sel) {
+                    // Draw the highlight bar.
                     SetColor(IsLongPress() ? MENU_SEL_BG_ACTIVE : MENU_SEL_BG);
-                    gr_fill(0, y-2, gr_fb_width(), y+char_height+2);
-                    // white text of selected item
+                    gr_fill(0, y - 2, gr_fb_width(), y + char_height + 2);
+                    // Bold white text for the selected item.
                     SetColor(MENU_SEL_FG);
-                    if (menu[i][0]) gr_text(4, y, menu[i], 1);
+                    gr_text(4, y, menu[i], true);
                     SetColor(MENU);
                 } else {
-                    if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top);
+                    gr_text(4, y, menu[i], false);
                 }
-                y += char_height+4;
+                y += char_height + 4;
             }
-
             DrawHorizontalRule(&y);
         }
 
-        SetColor(LOG);
-
         // display from the bottom up, until we hit the top of the
         // screen, the bottom of the menu, or we've displayed the
         // entire text buffer.
+        SetColor(LOG);
         int row = (text_top+text_rows-1) % text_rows;
         size_t count = 0;
         for (int ty = gr_fb_height() - char_height;
              ty >= y && count < text_rows;
              ty -= char_height, ++count) {
-            gr_text(0, ty, text[row], 0);
+            gr_text(0, ty, text[row], false);
             --row;
             if (row < 0) row = text_rows-1;
         }
@@ -580,19 +616,13 @@
                                  int initial_selection) {
     pthread_mutex_lock(&updateMutex);
     if (text_rows > 0 && text_cols > 0) {
-        size_t i;
-        for (i = 0; i < text_rows; ++i) {
-            if (headers[i] == nullptr) break;
-            strncpy(menu[i], headers[i], text_cols-1);
+        menu_headers = headers;
+        size_t i = 0;
+        for (; i < text_rows && items[i] != nullptr; ++i) {
+            strncpy(menu[i], items[i], text_cols-1);
             menu[i][text_cols-1] = '\0';
         }
-        menu_top = i;
-        for (; i < text_rows; ++i) {
-            if (items[i-menu_top] == nullptr) break;
-            strncpy(menu[i], items[i-menu_top], text_cols-1);
-            menu[i][text_cols-1] = '\0';
-        }
-        menu_items = i - menu_top;
+        menu_items = i;
         show_menu = true;
         menu_sel = initial_selection;
         update_screen_locked();
diff --git a/screen_ui.h b/screen_ui.h
index 50a4564..d473b8e 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -61,7 +61,9 @@
 
     void Redraw();
 
-    enum UIElement { HEADER, MENU, MENU_SEL_BG, MENU_SEL_BG_ACTIVE, MENU_SEL_FG, LOG, TEXT_FILL };
+    enum UIElement {
+        HEADER, MENU, MENU_SEL_BG, MENU_SEL_BG_ACTIVE, MENU_SEL_FG, LOG, TEXT_FILL, INFO
+    };
     void SetColor(UIElement e);
 
   private:
@@ -95,8 +97,9 @@
     bool show_text_ever;   // has show_text ever been true?
 
     char** menu;
+    const char* const* menu_headers;
     bool show_menu;
-    int menu_top, menu_items, menu_sel;
+    int menu_items, menu_sel;
 
     pthread_t progress_thread_;
 
@@ -121,6 +124,8 @@
     void ClearText();
 
     void DrawHorizontalRule(int* y);
+    void DrawTextLine(int* y, const char* line, bool bold);
+    void DrawTextLines(int* y, const char* const* lines);
 
     void LoadBitmap(const char* filename, gr_surface* surface);
     void LoadBitmapArray(const char* filename, int* frames, gr_surface** surface);