Merge up to AOSP marshmallow-release
In order to maintain compatibility with older trees, we now have minadbd.old and minui.old. I had to use a TARGET_GLOBAL_CFLAG to handle ifdef issues in minui/minui.d because healthd includes minui/minui.h and there was no other alternative to make minui.h compatible with older trees without having to modify healthd rules which is outside of TWRP. Note that the new minui does not currently have support for qcom overlay graphics. Support for this graphics mode will likely be added in a later patch set. If you are building in a 6.0 tree and have a device that needs qcom overlay graphics, be warned, as off mode charging may not work properly. A dead battery in this case could potentially brick your device if it is unable to charge as healthd handles charging duties. Update rules for building toolbox and add rules for making toybox Use permissive.sh in init.rc which will follow symlinks so we do not have to worry about what binary is supplying the setenforce functionality (toolbox, toybox, or busybox). Fix a few warnings in the main recovery binary source code. Fix a few includes that were missing that prevented compiling in 6.0 Change-Id: Ia67aa2107d260883da5e365475a19bea538e8b97
This commit is contained in:
@@ -41,40 +41,59 @@
|
||||
|
||||
#define UI_WAIT_KEY_TIMEOUT_SEC 120
|
||||
|
||||
// There's only (at most) one of these objects, and global callbacks
|
||||
// (for pthread_create, and the input event system) need to find it,
|
||||
// so use a global variable.
|
||||
static RecoveryUI* self = NULL;
|
||||
|
||||
RecoveryUI::RecoveryUI() :
|
||||
key_queue_len(0),
|
||||
key_last_down(-1),
|
||||
key_long_press(false),
|
||||
key_down_count(0),
|
||||
enable_reboot(true),
|
||||
consecutive_power_keys(0),
|
||||
consecutive_alternate_keys(0),
|
||||
last_key(-1) {
|
||||
pthread_mutex_init(&key_queue_mutex, NULL);
|
||||
pthread_cond_init(&key_queue_cond, NULL);
|
||||
self = this;
|
||||
RecoveryUI::RecoveryUI()
|
||||
: key_queue_len(0),
|
||||
key_last_down(-1),
|
||||
key_long_press(false),
|
||||
key_down_count(0),
|
||||
enable_reboot(true),
|
||||
consecutive_power_keys(0),
|
||||
last_key(-1),
|
||||
has_power_key(false),
|
||||
has_up_key(false),
|
||||
has_down_key(false) {
|
||||
pthread_mutex_init(&key_queue_mutex, nullptr);
|
||||
pthread_cond_init(&key_queue_cond, nullptr);
|
||||
memset(key_pressed, 0, sizeof(key_pressed));
|
||||
}
|
||||
|
||||
void RecoveryUI::Init() {
|
||||
ev_init(input_callback, NULL);
|
||||
pthread_create(&input_t, NULL, input_thread, NULL);
|
||||
void RecoveryUI::OnKeyDetected(int key_code) {
|
||||
if (key_code == KEY_POWER) {
|
||||
has_power_key = true;
|
||||
} else if (key_code == KEY_DOWN || key_code == KEY_VOLUMEDOWN) {
|
||||
has_down_key = true;
|
||||
} else if (key_code == KEY_UP || key_code == KEY_VOLUMEUP) {
|
||||
has_up_key = true;
|
||||
}
|
||||
}
|
||||
|
||||
int RecoveryUI::InputCallback(int fd, uint32_t epevents, void* data) {
|
||||
return reinterpret_cast<RecoveryUI*>(data)->OnInputEvent(fd, epevents);
|
||||
}
|
||||
|
||||
int RecoveryUI::input_callback(int fd, uint32_t epevents, void* data)
|
||||
{
|
||||
// Reads input events, handles special hot keys, and adds to the key queue.
|
||||
static void* InputThreadLoop(void*) {
|
||||
while (true) {
|
||||
if (!ev_wait(-1)) {
|
||||
ev_dispatch();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RecoveryUI::Init() {
|
||||
ev_init(InputCallback, this);
|
||||
|
||||
ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
|
||||
|
||||
pthread_create(&input_thread_, nullptr, InputThreadLoop, nullptr);
|
||||
}
|
||||
|
||||
int RecoveryUI::OnInputEvent(int fd, uint32_t epevents) {
|
||||
struct input_event ev;
|
||||
int ret;
|
||||
|
||||
ret = ev_get_input(fd, epevents, &ev);
|
||||
if (ret)
|
||||
if (ev_get_input(fd, epevents, &ev) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ev.type == EV_SYN) {
|
||||
return 0;
|
||||
@@ -84,23 +103,24 @@ int RecoveryUI::input_callback(int fd, uint32_t epevents, void* data)
|
||||
// the trackball. When it exceeds a threshold
|
||||
// (positive or negative), fake an up/down
|
||||
// key event.
|
||||
self->rel_sum += ev.value;
|
||||
if (self->rel_sum > 3) {
|
||||
self->process_key(KEY_DOWN, 1); // press down key
|
||||
self->process_key(KEY_DOWN, 0); // and release it
|
||||
self->rel_sum = 0;
|
||||
} else if (self->rel_sum < -3) {
|
||||
self->process_key(KEY_UP, 1); // press up key
|
||||
self->process_key(KEY_UP, 0); // and release it
|
||||
self->rel_sum = 0;
|
||||
rel_sum += ev.value;
|
||||
if (rel_sum > 3) {
|
||||
ProcessKey(KEY_DOWN, 1); // press down key
|
||||
ProcessKey(KEY_DOWN, 0); // and release it
|
||||
rel_sum = 0;
|
||||
} else if (rel_sum < -3) {
|
||||
ProcessKey(KEY_UP, 1); // press up key
|
||||
ProcessKey(KEY_UP, 0); // and release it
|
||||
rel_sum = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self->rel_sum = 0;
|
||||
rel_sum = 0;
|
||||
}
|
||||
|
||||
if (ev.type == EV_KEY && ev.code <= KEY_MAX)
|
||||
self->process_key(ev.code, ev.value);
|
||||
if (ev.type == EV_KEY && ev.code <= KEY_MAX) {
|
||||
ProcessKey(ev.code, ev.value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -117,7 +137,7 @@ int RecoveryUI::input_callback(int fd, uint32_t epevents, void* data)
|
||||
// a key is registered.
|
||||
//
|
||||
// updown == 1 for key down events; 0 for key up events
|
||||
void RecoveryUI::process_key(int key_code, int updown) {
|
||||
void RecoveryUI::ProcessKey(int key_code, int updown) {
|
||||
bool register_key = false;
|
||||
bool long_press = false;
|
||||
bool reboot_enabled;
|
||||
@@ -128,13 +148,13 @@ void RecoveryUI::process_key(int key_code, int updown) {
|
||||
++key_down_count;
|
||||
key_last_down = key_code;
|
||||
key_long_press = false;
|
||||
pthread_t th;
|
||||
key_timer_t* info = new key_timer_t;
|
||||
info->ui = this;
|
||||
info->key_code = key_code;
|
||||
info->count = key_down_count;
|
||||
pthread_create(&th, NULL, &RecoveryUI::time_key_helper, info);
|
||||
pthread_detach(th);
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, nullptr, &RecoveryUI::time_key_helper, info);
|
||||
pthread_detach(thread);
|
||||
} else {
|
||||
if (key_last_down == key_code) {
|
||||
long_press = key_long_press;
|
||||
@@ -146,8 +166,7 @@ void RecoveryUI::process_key(int key_code, int updown) {
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
|
||||
if (register_key) {
|
||||
NextCheckKeyIsLong(long_press);
|
||||
switch (CheckKey(key_code)) {
|
||||
switch (CheckKey(key_code, long_press)) {
|
||||
case RecoveryUI::IGNORE:
|
||||
break;
|
||||
|
||||
@@ -166,13 +185,6 @@ void RecoveryUI::process_key(int key_code, int updown) {
|
||||
case RecoveryUI::ENQUEUE:
|
||||
EnqueueKey(key_code);
|
||||
break;
|
||||
|
||||
case RecoveryUI::MOUNT_SYSTEM:
|
||||
#ifndef NO_RECOVERY_MOUNT
|
||||
ensure_path_mounted("/system");
|
||||
Print("Mounted /system.");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,7 +193,7 @@ void* RecoveryUI::time_key_helper(void* cookie) {
|
||||
key_timer_t* info = (key_timer_t*) cookie;
|
||||
info->ui->time_key(info->key_code, info->count);
|
||||
delete info;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RecoveryUI::time_key(int key_code, int count) {
|
||||
@@ -205,19 +217,7 @@ void RecoveryUI::EnqueueKey(int key_code) {
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
}
|
||||
|
||||
|
||||
// Reads input events, handles special hot keys, and adds to the key queue.
|
||||
void* RecoveryUI::input_thread(void *cookie)
|
||||
{
|
||||
for (;;) {
|
||||
if (!ev_wait(-1))
|
||||
ev_dispatch();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int RecoveryUI::WaitKey()
|
||||
{
|
||||
int RecoveryUI::WaitKey() {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
|
||||
// Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
|
||||
@@ -225,17 +225,16 @@ int RecoveryUI::WaitKey()
|
||||
do {
|
||||
struct timeval now;
|
||||
struct timespec timeout;
|
||||
gettimeofday(&now, NULL);
|
||||
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);
|
||||
rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout);
|
||||
}
|
||||
} while (usb_connected() && key_queue_len == 0);
|
||||
} while (IsUsbConnected() && key_queue_len == 0);
|
||||
|
||||
int key = -1;
|
||||
if (key_queue_len > 0) {
|
||||
@@ -246,8 +245,7 @@ int RecoveryUI::WaitKey()
|
||||
return key;
|
||||
}
|
||||
|
||||
// Return true if USB is connected.
|
||||
bool RecoveryUI::usb_connected() {
|
||||
bool RecoveryUI::IsUsbConnected() {
|
||||
int fd = open("/sys/class/android_usb/android0/state", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("failed to open /sys/class/android_usb/android0/state: %s\n",
|
||||
@@ -256,8 +254,8 @@ bool RecoveryUI::usb_connected() {
|
||||
}
|
||||
|
||||
char buf;
|
||||
/* USB is connected if android_usb state is CONNECTED or CONFIGURED */
|
||||
int connected = (read(fd, &buf, 1) == 1) && (buf == 'C');
|
||||
// USB is connected if android_usb state is CONNECTED or CONFIGURED.
|
||||
int connected = (TEMP_FAILURE_RETRY(read(fd, &buf, 1)) == 1) && (buf == 'C');
|
||||
if (close(fd) < 0) {
|
||||
printf("failed to close /sys/class/android_usb/android0/state: %s\n",
|
||||
strerror(errno));
|
||||
@@ -265,31 +263,55 @@ bool RecoveryUI::usb_connected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
bool RecoveryUI::IsKeyPressed(int key)
|
||||
{
|
||||
bool RecoveryUI::IsKeyPressed(int key) {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
int pressed = key_pressed[key];
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool RecoveryUI::IsLongPress() {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
bool result = key_long_press;
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool RecoveryUI::HasThreeButtons() {
|
||||
return has_power_key && has_up_key && has_down_key;
|
||||
}
|
||||
|
||||
void RecoveryUI::FlushKeys() {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
key_queue_len = 0;
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
}
|
||||
|
||||
// The default CheckKey implementation assumes the device has power,
|
||||
// volume up, and volume down keys.
|
||||
//
|
||||
// - Hold power and press vol-up to toggle display.
|
||||
// - Press power seven times in a row to reboot.
|
||||
// - Alternate vol-up and vol-down seven times to mount /system.
|
||||
RecoveryUI::KeyAction RecoveryUI::CheckKey(int key) {
|
||||
if ((IsKeyPressed(KEY_POWER) && key == KEY_VOLUMEUP) || key == KEY_HOME) {
|
||||
return TOGGLE;
|
||||
RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
key_long_press = false;
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
|
||||
// If we have power and volume up keys, that chord is the signal to toggle the text display.
|
||||
if (HasThreeButtons()) {
|
||||
if (key == KEY_VOLUMEUP && IsKeyPressed(KEY_POWER)) {
|
||||
return TOGGLE;
|
||||
}
|
||||
} else {
|
||||
// Otherwise long press of any button toggles to the text display,
|
||||
// and there's no way to toggle back (but that's pretty useless anyway).
|
||||
if (is_long_press && !IsTextVisible()) {
|
||||
return TOGGLE;
|
||||
}
|
||||
|
||||
// Also, for button-limited devices, a long press is translated to KEY_ENTER.
|
||||
if (is_long_press && IsTextVisible()) {
|
||||
EnqueueKey(KEY_ENTER);
|
||||
return IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
// Press power seven times in a row to reboot.
|
||||
if (key == KEY_POWER) {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
bool reboot_enabled = enable_reboot;
|
||||
@@ -305,27 +327,11 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key) {
|
||||
consecutive_power_keys = 0;
|
||||
}
|
||||
|
||||
if ((key == KEY_VOLUMEUP &&
|
||||
(last_key == KEY_VOLUMEDOWN || last_key == -1)) ||
|
||||
(key == KEY_VOLUMEDOWN &&
|
||||
(last_key == KEY_VOLUMEUP || last_key == -1))) {
|
||||
++consecutive_alternate_keys;
|
||||
if (consecutive_alternate_keys >= 7) {
|
||||
consecutive_alternate_keys = 0;
|
||||
return MOUNT_SYSTEM;
|
||||
}
|
||||
} else {
|
||||
consecutive_alternate_keys = 0;
|
||||
}
|
||||
last_key = key;
|
||||
|
||||
return ENQUEUE;
|
||||
return IsTextVisible() ? ENQUEUE : IGNORE;
|
||||
}
|
||||
|
||||
void RecoveryUI::NextCheckKeyIsLong(bool is_long_press) {
|
||||
}
|
||||
|
||||
void RecoveryUI::KeyLongPress(int key) {
|
||||
void RecoveryUI::KeyLongPress(int) {
|
||||
}
|
||||
|
||||
void RecoveryUI::SetEnableReboot(bool enabled) {
|
||||
|
||||
Reference in New Issue
Block a user