Merge "recovery_ui:Add support for multiple connectors switch" am: 91688b36bb am: 5a3219c41f

Original change: https://android-review.googlesource.com/c/platform/bootable/recovery/+/2146827

Change-Id: Ifce779dbb0cd93d4cd52376eed8cea8d35dd3533
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/recovery_ui/include/recovery_ui/screen_ui.h b/recovery_ui/include/recovery_ui/screen_ui.h
index 92b3c25..99ad534 100644
--- a/recovery_ui/include/recovery_ui/screen_ui.h
+++ b/recovery_ui/include/recovery_ui/screen_ui.h
@@ -245,6 +245,9 @@
       const std::vector<std::string>& backup_headers, const std::vector<std::string>& backup_items,
       const std::function<int(int, bool)>& key_handler) override;
 
+  // For Lid switch handle
+  int SetSwCallback(int code, int value) override;
+
  protected:
   static constexpr int kMenuIndent = 4;
 
@@ -404,6 +407,9 @@
 
   std::mutex updateMutex;
 
+  // Switch the display to active one after graphics is ready
+  bool is_graphics_available;
+
  private:
   void SetLocale(const std::string&);
 
diff --git a/recovery_ui/include/recovery_ui/stub_ui.h b/recovery_ui/include/recovery_ui/stub_ui.h
index 511b131..49689ba 100644
--- a/recovery_ui/include/recovery_ui/stub_ui.h
+++ b/recovery_ui/include/recovery_ui/stub_ui.h
@@ -80,6 +80,10 @@
   }
 
   void SetTitle(const std::vector<std::string>& /* lines */) override {}
+
+  int SetSwCallback(int /* code */, int /* value */) override {
+    return 0;
+  }
 };
 
 #endif  // RECOVERY_STUB_UI_H
diff --git a/recovery_ui/include/recovery_ui/ui.h b/recovery_ui/include/recovery_ui/ui.h
index 512732f..c3e3ee2 100644
--- a/recovery_ui/include/recovery_ui/ui.h
+++ b/recovery_ui/include/recovery_ui/ui.h
@@ -231,6 +231,8 @@
   bool InitScreensaver();
   void SetScreensaverState(ScreensaverState state);
 
+  virtual int SetSwCallback(int code, int value) = 0;
+
   // Key event input queue
   std::mutex key_queue_mutex;
   std::condition_variable key_queue_cond;
diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp
index b2c828f..ee3cbb1 100644
--- a/recovery_ui/screen_ui.cpp
+++ b/recovery_ui/screen_ui.cpp
@@ -48,6 +48,11 @@
 #include "recovery_ui/device.h"
 #include "recovery_ui/ui.h"
 
+enum DirectRenderManager {
+    DRM_INNER,
+    DRM_OUTER,
+};
+
 // Return the current time as a double (including fractions of a second).
 static double now() {
   struct timeval tv;
@@ -334,7 +339,8 @@
       stage(-1),
       max_stage(-1),
       locale_(""),
-      rtl_locale_(false) {}
+      rtl_locale_(false),
+      is_graphics_available(false) {}
 
 ScreenRecoveryUI::~ScreenRecoveryUI() {
   progress_thread_stopped_ = true;
@@ -906,6 +912,7 @@
   if (!InitGraphics()) {
     return false;
   }
+  is_graphics_available = true;
 
   if (!InitTextParams()) {
     return false;
@@ -950,6 +957,9 @@
   // Keep the progress bar updated, even when the process is otherwise busy.
   progress_thread_ = std::thread(&ScreenRecoveryUI::ProgressThreadLoop, this);
 
+  // set the callback for hall sensor event
+  (void)ev_sync_sw_state([this](auto&& a, auto&& b) { return this->SetSwCallback(a, b);});
+
   return true;
 }
 
@@ -1367,3 +1377,45 @@
     }
   }
 }
+
+int ScreenRecoveryUI::SetSwCallback(int code, int value) {
+  if (!is_graphics_available) { return -1; }
+  if (code > SW_MAX) { return -1; }
+  if (code != SW_LID) { return 0; }
+
+  /* detect dual display */
+  if (!gr_has_multiple_connectors()) { return -1; }
+
+  /* turn off all screen */
+  gr_fb_blank(true, DirectRenderManager::DRM_INNER);
+  gr_fb_blank(true, DirectRenderManager::DRM_OUTER);
+  gr_color(0, 0, 0, 255);
+  gr_clear();
+
+  /* turn on the screen */
+  gr_fb_blank(false, value);
+  gr_flip();
+
+  /* set the retation */
+  std::string rotation_str;
+  if (value == DirectRenderManager::DRM_OUTER) {
+    rotation_str =
+      android::base::GetProperty("ro.minui.second_rotation", "ROTATION_NONE");
+  } else {
+    rotation_str =
+      android::base::GetProperty("ro.minui.default_rotation", "ROTATION_NONE");
+  }
+
+  if (rotation_str == "ROTATION_RIGHT") {
+    gr_rotate(GRRotation::RIGHT);
+  } else if (rotation_str == "ROTATION_DOWN") {
+    gr_rotate(GRRotation::DOWN);
+  } else if (rotation_str == "ROTATION_LEFT") {
+    gr_rotate(GRRotation::LEFT);
+  } else {  // "ROTATION_NONE" or unknown string
+    gr_rotate(GRRotation::NONE);
+  }
+  Redraw();
+
+  return 0;
+}
diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp
index 6e67b1d..eb87f52 100644
--- a/recovery_ui/ui.cpp
+++ b/recovery_ui/ui.cpp
@@ -341,6 +341,11 @@
     ProcessKey(ev.code, ev.value);
   }
 
+  // For Lid switch handle
+  if (ev.type == EV_SW) {
+    SetSwCallback(ev.code, ev.value);
+  }
+
   return 0;
 }