Merge "recovery: Add screensaver mode."

am: 389a29193c

Change-Id: Ia3a03dce52f6e6c0aa907643aa67ad725fea8005
This commit is contained in:
Tao Bao 2017-01-31 06:15:53 +00:00 committed by android-build-merger
commit 2684259c34
2 changed files with 121 additions and 25 deletions

131
ui.cpp
View file

@ -32,7 +32,11 @@
#include <string>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <cutils/android_reboot.h>
#include <minui/minui.h>
@ -40,11 +44,15 @@
#include "roots.h"
#include "device.h"
#define UI_WAIT_KEY_TIMEOUT_SEC 120
static constexpr int UI_WAIT_KEY_TIMEOUT_SEC = 120;
static constexpr const char* BRIGHTNESS_FILE = "/sys/class/leds/lcd-backlight/brightness";
static constexpr const char* MAX_BRIGHTNESS_FILE = "/sys/class/leds/lcd-backlight/max_brightness";
RecoveryUI::RecoveryUI()
: locale_(""),
rtl_locale_(false),
brightness_normal_(50),
brightness_dimmed_(25),
key_queue_len(0),
key_last_down(-1),
key_long_press(false),
@ -54,7 +62,8 @@ RecoveryUI::RecoveryUI()
last_key(-1),
has_power_key(false),
has_up_key(false),
has_down_key(false) {
has_down_key(false),
screensaver_state_(ScreensaverState::DISABLED) {
pthread_mutex_init(&key_queue_mutex, nullptr);
pthread_cond_init(&key_queue_cond, nullptr);
memset(key_pressed, 0, sizeof(key_pressed));
@ -80,6 +89,40 @@ static void* InputThreadLoop(void*) {
return nullptr;
}
bool RecoveryUI::InitScreensaver() {
// Disabled.
if (brightness_normal_ == 0 || brightness_dimmed_ > brightness_normal_) {
return false;
}
// Set the initial brightness level based on the max brightness. Note that reading the initial
// value from BRIGHTNESS_FILE doesn't give the actual brightness value (bullhead, sailfish), so
// we don't have a good way to query the default value.
std::string content;
if (!android::base::ReadFileToString(MAX_BRIGHTNESS_FILE, &content)) {
LOG(WARNING) << "Failed to read max brightness: " << content;
return false;
}
unsigned int max_value;
if (!android::base::ParseUint(android::base::Trim(content), &max_value)) {
LOG(WARNING) << "Failed to parse max brightness: " << content;
return false;
}
brightness_normal_value_ = max_value * brightness_normal_ / 100.0;
brightness_dimmed_value_ = max_value * brightness_dimmed_ / 100.0;
if (!android::base::WriteStringToFile(std::to_string(brightness_normal_value_),
BRIGHTNESS_FILE)) {
PLOG(WARNING) << "Failed to set brightness";
return false;
}
LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_ << "%)";
screensaver_state_ = ScreensaverState::NORMAL;
return true;
}
bool RecoveryUI::Init(const std::string& locale) {
// Set up the locale info.
SetLocale(locale);
@ -88,6 +131,10 @@ bool RecoveryUI::Init(const std::string& locale) {
ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
if (!InitScreensaver()) {
LOG(INFO) << "Screensaver disabled";
}
pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr);
return true;
}
@ -220,31 +267,65 @@ void RecoveryUI::EnqueueKey(int key_code) {
}
int RecoveryUI::WaitKey() {
pthread_mutex_lock(&key_queue_mutex);
pthread_mutex_lock(&key_queue_mutex);
// Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
// plugged in.
do {
struct timeval now;
struct timespec timeout;
gettimeofday(&now, nullptr);
timeout.tv_sec = now.tv_sec;
timeout.tv_nsec = now.tv_usec * 1000;
timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
// Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
// plugged in.
do {
struct timeval now;
struct timespec timeout;
gettimeofday(&now, nullptr);
timeout.tv_sec = now.tv_sec;
timeout.tv_nsec = now.tv_usec * 1000;
timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
int rc = 0;
while (key_queue_len == 0 && rc != ETIMEDOUT) {
rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout);
}
} while (IsUsbConnected() && key_queue_len == 0);
int key = -1;
if (key_queue_len > 0) {
key = key_queue[0];
memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
int rc = 0;
while (key_queue_len == 0 && rc != ETIMEDOUT) {
rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout);
}
pthread_mutex_unlock(&key_queue_mutex);
return key;
if (screensaver_state_ != ScreensaverState::DISABLED) {
if (rc == ETIMEDOUT) {
// Lower the brightness level: NORMAL -> DIMMED; DIMMED -> OFF.
if (screensaver_state_ == ScreensaverState::NORMAL) {
if (android::base::WriteStringToFile(std::to_string(brightness_dimmed_value_),
BRIGHTNESS_FILE)) {
LOG(INFO) << "Brightness: " << brightness_dimmed_value_ << " (" << brightness_dimmed_
<< "%)";
screensaver_state_ = ScreensaverState::DIMMED;
}
} else if (screensaver_state_ == ScreensaverState::DIMMED) {
if (android::base::WriteStringToFile("0", BRIGHTNESS_FILE)) {
LOG(INFO) << "Brightness: 0 (off)";
screensaver_state_ = ScreensaverState::OFF;
}
}
} else if (screensaver_state_ != ScreensaverState::NORMAL) {
// Drop the first key if it's changing from OFF to NORMAL.
if (screensaver_state_ == ScreensaverState::OFF) {
if (key_queue_len > 0) {
memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
}
}
// Reset the brightness to normal.
if (android::base::WriteStringToFile(std::to_string(brightness_normal_value_),
BRIGHTNESS_FILE)) {
screensaver_state_ = ScreensaverState::NORMAL;
LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_
<< "%)";
}
}
}
} while (IsUsbConnected() && key_queue_len == 0);
int key = -1;
if (key_queue_len > 0) {
key = key_queue[0];
memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
}
pthread_mutex_unlock(&key_queue_mutex);
return key;
}
bool RecoveryUI::IsUsbConnected() {
@ -330,7 +411,7 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) {
}
last_key = key;
return IsTextVisible() ? ENQUEUE : IGNORE;
return (IsTextVisible() || screensaver_state_ == ScreensaverState::OFF) ? ENQUEUE : IGNORE;
}
void RecoveryUI::KeyLongPress(int) {

15
ui.h
View file

@ -130,6 +130,13 @@ class RecoveryUI {
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 @@ class RecoveryUI {
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