Introduce VR recovery ui

A version of screen ui with specific adjustments for vr device
compatibility.

Bug: 37779982
Test: "adb reboot recovery" to view
Change-Id: If6b0f26c1b587f8d0176060685b5efb6c67593b1
diff --git a/Android.mk b/Android.mk
index e619db0..5348e36 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,6 +76,7 @@
     rotate_logs.cpp \
     screen_ui.cpp \
     ui.cpp \
+    vr_ui.cpp \
     wear_ui.cpp \
     wear_touch.cpp \
 
@@ -182,6 +183,17 @@
 LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
 
+# vr headset default device
+# ===============================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := vr_device.cpp
+
+# should match TARGET_RECOVERY_UI_LIB set in BoardConfig.mk
+LOCAL_MODULE := librecovery_ui_vr
+
+include $(BUILD_STATIC_LIBRARY)
+
 include \
     $(LOCAL_PATH)/applypatch/Android.mk \
     $(LOCAL_PATH)/boot_control/Android.mk \
diff --git a/screen_ui.cpp b/screen_ui.cpp
index bb2772d..61ef591 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -256,6 +256,10 @@
     *y += 4;
 }
 
+void ScreenRecoveryUI::DrawHighlightBar(int x, int y, int width, int height) const {
+    gr_fill(x, y, x + width, y + height);
+}
+
 void ScreenRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) const {
     gr_text(gr_sys_font(), x, *y, line, bold);
     *y += char_height_ + 4;
@@ -310,15 +314,14 @@
                 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);
+                    DrawHighlightBar(0, y - 2, gr_fb_width(), char_height_ + 4);
                     // Bold white text for the selected item.
                     SetColor(MENU_SEL_FG);
-                    gr_text(gr_sys_font(), 4, y, menu_[i], true);
+                    DrawTextLine(TEXT_INDENT, &y, menu_[i], true);
                     SetColor(MENU);
                 } else {
-                    gr_text(gr_sys_font(), 4, y, menu_[i], false);
+                    DrawTextLine(TEXT_INDENT, &y, menu_[i], false);
                 }
-                y += char_height_ + 4;
             }
             DrawHorizontalRule(&y);
         }
@@ -329,10 +332,11 @@
         SetColor(LOG);
         int row = (text_top_ + text_rows_ - 1) % text_rows_;
         size_t count = 0;
-        for (int ty = gr_fb_height() - char_height_;
+        for (int ty = gr_fb_height() - char_height_ - log_bottom_offset_;
              ty >= y && count < text_rows_;
              ty -= char_height_, ++count) {
-            gr_text(gr_sys_font(), 0, ty, text_[row], false);
+            int temp_y = ty;
+            DrawTextLine(0, &temp_y, text_[row], false);
             --row;
             if (row < 0) row = text_rows_ - 1;
         }
@@ -453,6 +457,7 @@
     gr_font_size(gr_sys_font(), &char_width_, &char_height_);
     text_rows_ = gr_fb_height() / char_height_;
     text_cols_ = gr_fb_width() / char_width_;
+    log_bottom_offset_ = 0;
     return true;
 }
 
diff --git a/screen_ui.h b/screen_ui.h
index a2322c3..bd99254 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -107,6 +107,7 @@
     // Log text overlay, displayed when a magic key is pressed.
     char** text_;
     size_t text_col_, text_row_, text_top_;
+    int log_bottom_offset_;
 
     bool show_text;
     bool show_text_ever;   // has show_text ever been true?
@@ -165,8 +166,9 @@
     virtual int GetProgressBaseline();
     virtual int GetTextBaseline();
 
-    void DrawHorizontalRule(int* y);
-    void DrawTextLine(int x, int* y, const char* line, bool bold) const;
+    virtual void DrawHorizontalRule(int* y);
+    virtual void DrawHighlightBar(int x, int y, int width, int height) const;
+    virtual void DrawTextLine(int x, int* y, const char* line, bool bold) const;
     void DrawTextLines(int x, int* y, const char* const* lines) const;
 };
 
diff --git a/vr_device.cpp b/vr_device.cpp
new file mode 100644
index 0000000..61e15cb
--- /dev/null
+++ b/vr_device.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "device.h"
+#include "vr_ui.h"
+
+Device* make_device() {
+    return new Device(new VrRecoveryUI);
+}
+
diff --git a/vr_ui.cpp b/vr_ui.cpp
new file mode 100644
index 0000000..b2c65e3
--- /dev/null
+++ b/vr_ui.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "vr_ui.h"
+
+#include <minui/minui.h>
+
+VrRecoveryUI::VrRecoveryUI() :
+  x_offset(400),
+  y_offset(400),
+  stereo_offset(100) {
+}
+
+bool VrRecoveryUI::InitTextParams() {
+  if (gr_init() < 0) {
+    return false;
+  }
+
+  gr_font_size(gr_sys_font(), &char_width_, &char_height_);
+  int mid_divide = gr_fb_width() / 2;
+  text_rows_ = (gr_fb_height() - 2 * y_offset) / char_height_;
+  text_cols_ = (mid_divide - x_offset - stereo_offset) / char_width_;
+  log_bottom_offset_ = gr_fb_height() - 2 * y_offset;
+  return true;
+}
+
+void VrRecoveryUI::DrawHorizontalRule(int* y) {
+  SetColor(MENU);
+  *y += 4;
+  gr_fill(0, *y + y_offset, gr_fb_width(), *y + y_offset + 2);
+  *y += 4;
+}
+
+void VrRecoveryUI::DrawHighlightBar(int x, int y, int width, int height) const {
+  gr_fill(x, y + y_offset, x + width, y + y_offset + height);
+}
+
+void VrRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) const {
+  int mid_divide = gr_fb_width() / 2;
+  gr_text(gr_sys_font(), x + x_offset + stereo_offset, *y + y_offset, line, bold);
+  gr_text(gr_sys_font(), x + x_offset - stereo_offset + mid_divide, *y + y_offset, line, bold);
+  *y += char_height_ + 4;
+}
diff --git a/vr_ui.h b/vr_ui.h
new file mode 100644
index 0000000..85c5708
--- /dev/null
+++ b/vr_ui.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RECOVERY_VR_UI_H
+#define RECOVERY_VR_UI_H
+
+#include "screen_ui.h"
+
+class VrRecoveryUI : public ScreenRecoveryUI {
+  public:
+    VrRecoveryUI();
+
+  protected:
+    // Pixel offsets to move drawing functions to visible range.
+    // Can vary per device depending on screen size and lens distortion.
+    int x_offset, y_offset, stereo_offset;
+
+    bool InitTextParams() override;
+
+    void DrawHorizontalRule(int* y) override;
+    void DrawHighlightBar(int x, int y, int width, int height) const override;
+    void DrawTextLine(int x, int* y, const char* line, bool bold) const override;
+};
+
+#endif  // RECOVERY_VR_UI_H