diff options
author | Tao Bao | 2017-01-16 19:38:18 -0600 |
---|---|---|
committer | Tao Bao | 2017-01-30 18:12:30 -0600 |
commit | 6278bdf3490a2f6682f5a9c47350b3d9f92a9165 (patch) | |
tree | d6ea708f810fc06bc0c33d8386b3d01f035c25a5 /ui.cpp | |
parent | 56ff8061b1bc58cf646a14054485b617e916f423 (diff) | |
download | platform-bootable-recovery-6278bdf3490a2f6682f5a9c47350b3d9f92a9165.tar.gz platform-bootable-recovery-6278bdf3490a2f6682f5a9c47350b3d9f92a9165.tar.xz platform-bootable-recovery-6278bdf3490a2f6682f5a9c47350b3d9f92a9165.zip |
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
Diffstat (limited to 'ui.cpp')
-rw-r--r-- | ui.cpp | 129 |
1 files changed, 105 insertions, 24 deletions
@@ -32,7 +32,11 @@ | |||
32 | 32 | ||
33 | #include <string> | 33 | #include <string> |
34 | 34 | ||
35 | #include <android-base/file.h> | ||
36 | #include <android-base/logging.h> | ||
37 | #include <android-base/parseint.h> | ||
35 | #include <android-base/properties.h> | 38 | #include <android-base/properties.h> |
39 | #include <android-base/strings.h> | ||
36 | #include <cutils/android_reboot.h> | 40 | #include <cutils/android_reboot.h> |
37 | #include <minui/minui.h> | 41 | #include <minui/minui.h> |
38 | 42 | ||
@@ -40,11 +44,15 @@ | |||
40 | #include "roots.h" | 44 | #include "roots.h" |
41 | #include "device.h" | 45 | #include "device.h" |
42 | 46 | ||
43 | #define UI_WAIT_KEY_TIMEOUT_SEC 120 | 47 | static constexpr int UI_WAIT_KEY_TIMEOUT_SEC = 120; |
48 | static constexpr const char* BRIGHTNESS_FILE = "/sys/class/leds/lcd-backlight/brightness"; | ||
49 | static constexpr const char* MAX_BRIGHTNESS_FILE = "/sys/class/leds/lcd-backlight/max_brightness"; | ||
44 | 50 | ||
45 | RecoveryUI::RecoveryUI() | 51 | RecoveryUI::RecoveryUI() |
46 | : locale_(""), | 52 | : locale_(""), |
47 | rtl_locale_(false), | 53 | rtl_locale_(false), |
54 | brightness_normal_(50), | ||
55 | brightness_dimmed_(25), | ||
48 | key_queue_len(0), | 56 | key_queue_len(0), |
49 | key_last_down(-1), | 57 | key_last_down(-1), |
50 | key_long_press(false), | 58 | key_long_press(false), |
@@ -54,7 +62,8 @@ RecoveryUI::RecoveryUI() | |||
54 | last_key(-1), | 62 | last_key(-1), |
55 | has_power_key(false), | 63 | has_power_key(false), |
56 | has_up_key(false), | 64 | has_up_key(false), |
57 | has_down_key(false) { | 65 | has_down_key(false), |
66 | screensaver_state_(ScreensaverState::DISABLED) { | ||
58 | pthread_mutex_init(&key_queue_mutex, nullptr); | 67 | pthread_mutex_init(&key_queue_mutex, nullptr); |
59 | pthread_cond_init(&key_queue_cond, nullptr); | 68 | pthread_cond_init(&key_queue_cond, nullptr); |
60 | memset(key_pressed, 0, sizeof(key_pressed)); | 69 | memset(key_pressed, 0, sizeof(key_pressed)); |
@@ -80,6 +89,40 @@ static void* InputThreadLoop(void*) { | |||
80 | return nullptr; | 89 | return nullptr; |
81 | } | 90 | } |
82 | 91 | ||
92 | bool RecoveryUI::InitScreensaver() { | ||
93 | // Disabled. | ||
94 | if (brightness_normal_ == 0 || brightness_dimmed_ > brightness_normal_) { | ||
95 | return false; | ||
96 | } | ||
97 | |||
98 | // Set the initial brightness level based on the max brightness. Note that reading the initial | ||
99 | // value from BRIGHTNESS_FILE doesn't give the actual brightness value (bullhead, sailfish), so | ||
100 | // we don't have a good way to query the default value. | ||
101 | std::string content; | ||
102 | if (!android::base::ReadFileToString(MAX_BRIGHTNESS_FILE, &content)) { | ||
103 | LOG(WARNING) << "Failed to read max brightness: " << content; | ||
104 | return false; | ||
105 | } | ||
106 | |||
107 | unsigned int max_value; | ||
108 | if (!android::base::ParseUint(android::base::Trim(content), &max_value)) { | ||
109 | LOG(WARNING) << "Failed to parse max brightness: " << content; | ||
110 | return false; | ||
111 | } | ||
112 | |||
113 | brightness_normal_value_ = max_value * brightness_normal_ / 100.0; | ||
114 | brightness_dimmed_value_ = max_value * brightness_dimmed_ / 100.0; | ||
115 | if (!android::base::WriteStringToFile(std::to_string(brightness_normal_value_), | ||
116 | BRIGHTNESS_FILE)) { | ||
117 | PLOG(WARNING) << "Failed to set brightness"; | ||
118 | return false; | ||
119 | } | ||
120 | |||
121 | LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_ << "%)"; | ||
122 | screensaver_state_ = ScreensaverState::NORMAL; | ||
123 | return true; | ||
124 | } | ||
125 | |||
83 | bool RecoveryUI::Init(const std::string& locale) { | 126 | bool RecoveryUI::Init(const std::string& locale) { |
84 | // Set up the locale info. | 127 | // Set up the locale info. |
85 | SetLocale(locale); | 128 | SetLocale(locale); |
@@ -88,6 +131,10 @@ bool RecoveryUI::Init(const std::string& locale) { | |||
88 | 131 | ||
89 | ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1)); | 132 | ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1)); |
90 | 133 | ||
134 | if (!InitScreensaver()) { | ||
135 | LOG(INFO) << "Screensaver disabled"; | ||
136 | } | ||
137 | |||
91 | pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr); | 138 | pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr); |
92 | return true; | 139 | return true; |
93 | } | 140 | } |
@@ -220,31 +267,65 @@ void RecoveryUI::EnqueueKey(int key_code) { | |||
220 | } | 267 | } |
221 | 268 | ||
222 | int RecoveryUI::WaitKey() { | 269 | int RecoveryUI::WaitKey() { |
223 | pthread_mutex_lock(&key_queue_mutex); | 270 | pthread_mutex_lock(&key_queue_mutex); |
271 | |||
272 | // Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is | ||
273 | // plugged in. | ||
274 | do { | ||
275 | struct timeval now; | ||
276 | struct timespec timeout; | ||
277 | gettimeofday(&now, nullptr); | ||
278 | timeout.tv_sec = now.tv_sec; | ||
279 | timeout.tv_nsec = now.tv_usec * 1000; | ||
280 | timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC; | ||
281 | |||
282 | int rc = 0; | ||
283 | while (key_queue_len == 0 && rc != ETIMEDOUT) { | ||
284 | rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout); | ||
285 | } | ||
224 | 286 | ||
225 | // Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is | 287 | if (screensaver_state_ != ScreensaverState::DISABLED) { |
226 | // plugged in. | 288 | if (rc == ETIMEDOUT) { |
227 | do { | 289 | // Lower the brightness level: NORMAL -> DIMMED; DIMMED -> OFF. |
228 | struct timeval now; | 290 | if (screensaver_state_ == ScreensaverState::NORMAL) { |
229 | struct timespec timeout; | 291 | if (android::base::WriteStringToFile(std::to_string(brightness_dimmed_value_), |
230 | gettimeofday(&now, nullptr); | 292 | BRIGHTNESS_FILE)) { |
231 | timeout.tv_sec = now.tv_sec; | 293 | LOG(INFO) << "Brightness: " << brightness_dimmed_value_ << " (" << brightness_dimmed_ |
232 | timeout.tv_nsec = now.tv_usec * 1000; | 294 | << "%)"; |
233 | timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC; | 295 | screensaver_state_ = ScreensaverState::DIMMED; |
234 | 296 | } | |
235 | int rc = 0; | 297 | } else if (screensaver_state_ == ScreensaverState::DIMMED) { |
236 | while (key_queue_len == 0 && rc != ETIMEDOUT) { | 298 | if (android::base::WriteStringToFile("0", BRIGHTNESS_FILE)) { |
237 | rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout); | 299 | LOG(INFO) << "Brightness: 0 (off)"; |
300 | screensaver_state_ = ScreensaverState::OFF; | ||
301 | } | ||
302 | } | ||
303 | } else if (screensaver_state_ != ScreensaverState::NORMAL) { | ||
304 | // Drop the first key if it's changing from OFF to NORMAL. | ||
305 | if (screensaver_state_ == ScreensaverState::OFF) { | ||
306 | if (key_queue_len > 0) { | ||
307 | memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len); | ||
308 | } | ||
238 | } | 309 | } |
239 | } while (IsUsbConnected() && key_queue_len == 0); | ||
240 | 310 | ||
241 | int key = -1; | 311 | // Reset the brightness to normal. |
242 | if (key_queue_len > 0) { | 312 | if (android::base::WriteStringToFile(std::to_string(brightness_normal_value_), |
243 | key = key_queue[0]; | 313 | BRIGHTNESS_FILE)) { |
244 | memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len); | 314 | screensaver_state_ = ScreensaverState::NORMAL; |
315 | LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_ | ||
316 | << "%)"; | ||
317 | } | ||
318 | } | ||
245 | } | 319 | } |
246 | pthread_mutex_unlock(&key_queue_mutex); | 320 | } while (IsUsbConnected() && key_queue_len == 0); |
247 | return key; | 321 | |
322 | int key = -1; | ||
323 | if (key_queue_len > 0) { | ||
324 | key = key_queue[0]; | ||
325 | memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len); | ||
326 | } | ||
327 | pthread_mutex_unlock(&key_queue_mutex); | ||
328 | return key; | ||
248 | } | 329 | } |
249 | 330 | ||
250 | bool RecoveryUI::IsUsbConnected() { | 331 | bool RecoveryUI::IsUsbConnected() { |
@@ -330,7 +411,7 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) { | |||
330 | } | 411 | } |
331 | 412 | ||
332 | last_key = key; | 413 | last_key = key; |
333 | return IsTextVisible() ? ENQUEUE : IGNORE; | 414 | return (IsTextVisible() || screensaver_state_ == ScreensaverState::OFF) ? ENQUEUE : IGNORE; |
334 | } | 415 | } |
335 | 416 | ||
336 | void RecoveryUI::KeyLongPress(int) { | 417 | void RecoveryUI::KeyLongPress(int) { |