recovery: Add screensaver mode.

While it's waiting for user input, dim or turn off the backlight to
avoid OLED burn-in. The backlight brightness will be reduced after the
first timeout (default 120s), and then turned off after the second.
Pressing any key will take it back to the normal brightness. While the
display is off, the first key input will only turn on the backlight.

The most common case that triggers the screensaver is under text mode,
such as waiting for menu selection or viewing recovery logs.

This CL doesn't change the brightness while it's installing updates or
performing wipes under UI mode.

When it encounters any install error under UI mode (user builds):
 - If it's NOT USB connected, it will reboot automatically after the
   first timeout (same as before);
 - If it's USB connected, it will dim and turn off the display per the
   change in this CL.

Bug: 34077703
Test: Boot a device with the new recovery image. Wait for timeout.

Change-Id: I0c14907e60340a7f037adb6e464942d099ada08b
diff --git a/ui.h b/ui.h
index 53ce060..823eb65 100644
--- a/ui.h
+++ b/ui.h
@@ -130,6 +130,13 @@
     std::string locale_;
     bool rtl_locale_;
 
+    // The normal and dimmed brightness percentages (default: 50 and 25, which means 50% and 25%
+    // of the max_brightness). Because the absolute values may vary across devices. These two
+    // values can be configured via subclassing. Setting brightness_normal_ to 0 to disable
+    // screensaver.
+    unsigned int brightness_normal_;
+    unsigned int brightness_dimmed_;
+
   private:
     // Key event input queue
     pthread_mutex_t key_queue_mutex;
@@ -167,6 +174,14 @@
     void time_key(int key_code, int count);
 
     void SetLocale(const std::string&);
+
+    enum class ScreensaverState { DISABLED, NORMAL, DIMMED, OFF };
+    ScreensaverState screensaver_state_;
+    // The following two contain the absolute values computed from brightness_normal_ and
+    // brightness_dimmed_ respectively.
+    unsigned int brightness_normal_value_;
+    unsigned int brightness_dimmed_value_;
+    bool InitScreensaver();
 };
 
 #endif  // RECOVERY_UI_H