Merge "recovery: Add screensaver mode."
am: 389a29193c
Change-Id: Ia3a03dce52f6e6c0aa907643aa67ad725fea8005
This commit is contained in:
commit
2684259c34
2 changed files with 121 additions and 25 deletions
131
ui.cpp
131
ui.cpp
|
@ -32,7 +32,11 @@
|
||||||
|
|
||||||
#include <string>
|
#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/properties.h>
|
||||||
|
#include <android-base/strings.h>
|
||||||
#include <cutils/android_reboot.h>
|
#include <cutils/android_reboot.h>
|
||||||
#include <minui/minui.h>
|
#include <minui/minui.h>
|
||||||
|
|
||||||
|
@ -40,11 +44,15 @@
|
||||||
#include "roots.h"
|
#include "roots.h"
|
||||||
#include "device.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()
|
RecoveryUI::RecoveryUI()
|
||||||
: locale_(""),
|
: locale_(""),
|
||||||
rtl_locale_(false),
|
rtl_locale_(false),
|
||||||
|
brightness_normal_(50),
|
||||||
|
brightness_dimmed_(25),
|
||||||
key_queue_len(0),
|
key_queue_len(0),
|
||||||
key_last_down(-1),
|
key_last_down(-1),
|
||||||
key_long_press(false),
|
key_long_press(false),
|
||||||
|
@ -54,7 +62,8 @@ RecoveryUI::RecoveryUI()
|
||||||
last_key(-1),
|
last_key(-1),
|
||||||
has_power_key(false),
|
has_power_key(false),
|
||||||
has_up_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_mutex_init(&key_queue_mutex, nullptr);
|
||||||
pthread_cond_init(&key_queue_cond, nullptr);
|
pthread_cond_init(&key_queue_cond, nullptr);
|
||||||
memset(key_pressed, 0, sizeof(key_pressed));
|
memset(key_pressed, 0, sizeof(key_pressed));
|
||||||
|
@ -80,6 +89,40 @@ static void* InputThreadLoop(void*) {
|
||||||
return nullptr;
|
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) {
|
bool RecoveryUI::Init(const std::string& locale) {
|
||||||
// Set up the locale info.
|
// Set up the locale info.
|
||||||
SetLocale(locale);
|
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));
|
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);
|
pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -220,31 +267,65 @@ void RecoveryUI::EnqueueKey(int key_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int RecoveryUI::WaitKey() {
|
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
|
// Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
|
||||||
// plugged in.
|
// plugged in.
|
||||||
do {
|
do {
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
gettimeofday(&now, nullptr);
|
gettimeofday(&now, nullptr);
|
||||||
timeout.tv_sec = now.tv_sec;
|
timeout.tv_sec = now.tv_sec;
|
||||||
timeout.tv_nsec = now.tv_usec * 1000;
|
timeout.tv_nsec = now.tv_usec * 1000;
|
||||||
timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
|
timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
|
||||||
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
while (key_queue_len == 0 && rc != ETIMEDOUT) {
|
while (key_queue_len == 0 && rc != ETIMEDOUT) {
|
||||||
rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout);
|
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);
|
|
||||||
}
|
}
|
||||||
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() {
|
bool RecoveryUI::IsUsbConnected() {
|
||||||
|
@ -330,7 +411,7 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) {
|
||||||
}
|
}
|
||||||
|
|
||||||
last_key = key;
|
last_key = key;
|
||||||
return IsTextVisible() ? ENQUEUE : IGNORE;
|
return (IsTextVisible() || screensaver_state_ == ScreensaverState::OFF) ? ENQUEUE : IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecoveryUI::KeyLongPress(int) {
|
void RecoveryUI::KeyLongPress(int) {
|
||||||
|
|
15
ui.h
15
ui.h
|
@ -130,6 +130,13 @@ class RecoveryUI {
|
||||||
std::string locale_;
|
std::string locale_;
|
||||||
bool rtl_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:
|
private:
|
||||||
// Key event input queue
|
// Key event input queue
|
||||||
pthread_mutex_t key_queue_mutex;
|
pthread_mutex_t key_queue_mutex;
|
||||||
|
@ -167,6 +174,14 @@ class RecoveryUI {
|
||||||
void time_key(int key_code, int count);
|
void time_key(int key_code, int count);
|
||||||
|
|
||||||
void SetLocale(const std::string&);
|
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
|
#endif // RECOVERY_UI_H
|
||||||
|
|
Loading…
Reference in a new issue