notify about pending long press
Recovery changes: - add a method to the UI class that is called when a key is held down long enough to be a "long press" (but before it is released). Device-specific subclasses can override this to indicate a long press. - do color selection for ScreenRecoveryUI's menu-and-log drawing function. Subclasses can override this to customize the colors they use for various elements. - Include the value of ro.build.display.id in the menu headers, so you can see on the screen what version of recovery you are running. Change-Id: I426a6daf892b9011638e2035aebfa2831d4f596d
This commit is contained in:
+6
-8
@@ -75,6 +75,7 @@ static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload";
|
||||
|
||||
RecoveryUI* ui = NULL;
|
||||
char* locale = NULL;
|
||||
char recovery_version[PROPERTY_VALUE_MAX+1];
|
||||
|
||||
/*
|
||||
* The recovery tool communicates with the main system through /cache files.
|
||||
@@ -526,21 +527,17 @@ copy_sideloaded_package(const char* original_path) {
|
||||
|
||||
static const char**
|
||||
prepend_title(const char* const* headers) {
|
||||
const char* title[] = { "Android system recovery <"
|
||||
EXPAND(RECOVERY_API_VERSION) "e>",
|
||||
"",
|
||||
NULL };
|
||||
|
||||
// count the number of lines in our title, plus the
|
||||
// caller-provided headers.
|
||||
int count = 0;
|
||||
int count = 3; // our title has 3 lines
|
||||
const char* const* p;
|
||||
for (p = title; *p; ++p, ++count);
|
||||
for (p = headers; *p; ++p, ++count);
|
||||
|
||||
const char** new_headers = (const char**)malloc((count+1) * sizeof(char*));
|
||||
const char** h = new_headers;
|
||||
for (p = title; *p; ++p, ++h) *h = *p;
|
||||
*(h++) = "Android system recovery <" EXPAND(RECOVERY_API_VERSION) "e>";
|
||||
*(h++) = recovery_version;
|
||||
*(h++) = "";
|
||||
for (p = headers; *p; ++p, ++h) *h = *p;
|
||||
*h = NULL;
|
||||
|
||||
@@ -1022,6 +1019,7 @@ main(int argc, char **argv) {
|
||||
printf("\n");
|
||||
|
||||
property_list(print_property, NULL);
|
||||
property_get("ro.build.display.id", recovery_version, "");
|
||||
printf("\n");
|
||||
|
||||
int status = INSTALL_SUCCESS;
|
||||
|
||||
+38
-10
@@ -196,9 +196,29 @@ void ScreenRecoveryUI::draw_progress_locked()
|
||||
}
|
||||
}
|
||||
|
||||
#define C_HEADER 247,0,6
|
||||
#define C_MENU 0,106,157
|
||||
#define C_LOG 249,194,0
|
||||
void ScreenRecoveryUI::SetColor(UIElement e) {
|
||||
switch (e) {
|
||||
case HEADER:
|
||||
gr_color(247, 0, 6, 255);
|
||||
break;
|
||||
case MENU:
|
||||
case MENU_SEL_BG:
|
||||
gr_color(0, 106, 157, 255);
|
||||
break;
|
||||
case MENU_SEL_FG:
|
||||
gr_color(255, 255, 255, 255);
|
||||
break;
|
||||
case LOG:
|
||||
gr_color(249, 194, 0, 255);
|
||||
break;
|
||||
case TEXT_FILL:
|
||||
gr_color(0, 0, 0, 160);
|
||||
break;
|
||||
default:
|
||||
gr_color(255, 255, 255, 255);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Redraw everything on the screen. Does not flip pages.
|
||||
// Should only be called with updateMutex locked.
|
||||
@@ -208,37 +228,38 @@ void ScreenRecoveryUI::draw_screen_locked()
|
||||
draw_progress_locked();
|
||||
|
||||
if (show_text) {
|
||||
gr_color(0, 0, 0, 160);
|
||||
SetColor(TEXT_FILL);
|
||||
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
|
||||
|
||||
int y = 0;
|
||||
int i = 0;
|
||||
if (show_menu) {
|
||||
gr_color(C_HEADER, 255);
|
||||
SetColor(HEADER);
|
||||
|
||||
for (; i < menu_top + menu_items; ++i) {
|
||||
if (i == menu_top) gr_color(C_MENU, 255);
|
||||
if (i == menu_top) SetColor(MENU);
|
||||
|
||||
if (i == menu_top + menu_sel) {
|
||||
// draw the highlight bar
|
||||
SetColor(MENU_SEL_BG);
|
||||
gr_fill(0, y-2, gr_fb_width(), y+char_height+2);
|
||||
// white text of selected item
|
||||
gr_color(255, 255, 255, 255);
|
||||
SetColor(MENU_SEL_FG);
|
||||
if (menu[i][0]) gr_text(4, y, menu[i], 1);
|
||||
gr_color(C_MENU, 255);
|
||||
SetColor(MENU);
|
||||
} else {
|
||||
if (menu[i][0]) gr_text(4, y, menu[i], i < menu_top);
|
||||
}
|
||||
y += char_height+4;
|
||||
}
|
||||
gr_color(C_MENU, 255);
|
||||
SetColor(MENU);
|
||||
y += 4;
|
||||
gr_fill(0, y, gr_fb_width(), y+2);
|
||||
y += 4;
|
||||
++i;
|
||||
}
|
||||
|
||||
gr_color(C_LOG, 255);
|
||||
SetColor(LOG);
|
||||
|
||||
// display from the bottom up, until we hit the top of the
|
||||
// screen, the bottom of the menu, or we've displayed the
|
||||
@@ -585,3 +606,10 @@ void ScreenRecoveryUI::ShowText(bool visible)
|
||||
update_screen_locked();
|
||||
pthread_mutex_unlock(&updateMutex);
|
||||
}
|
||||
|
||||
void ScreenRecoveryUI::Redraw()
|
||||
{
|
||||
pthread_mutex_lock(&updateMutex);
|
||||
update_screen_locked();
|
||||
pthread_mutex_unlock(&updateMutex);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,11 @@ class ScreenRecoveryUI : public RecoveryUI {
|
||||
int SelectMenu(int sel);
|
||||
void EndMenu();
|
||||
|
||||
void Redraw();
|
||||
|
||||
enum UIElement { HEADER, MENU, MENU_SEL_BG, MENU_SEL_FG, LOG, TEXT_FILL };
|
||||
virtual void SetColor(UIElement e);
|
||||
|
||||
private:
|
||||
Icon currentIcon;
|
||||
int installingFrame;
|
||||
|
||||
@@ -46,7 +46,8 @@ static RecoveryUI* self = NULL;
|
||||
RecoveryUI::RecoveryUI() :
|
||||
key_queue_len(0),
|
||||
key_last_down(-1),
|
||||
key_down_time(0) {
|
||||
key_long_press(false),
|
||||
key_down_count(0) {
|
||||
pthread_mutex_init(&key_queue_mutex, NULL);
|
||||
pthread_cond_init(&key_queue_cond, NULL);
|
||||
self = this;
|
||||
@@ -112,19 +113,22 @@ void RecoveryUI::process_key(int key_code, int updown) {
|
||||
bool register_key = false;
|
||||
bool long_press = false;
|
||||
|
||||
const long long_threshold = CLOCKS_PER_SEC * 750 / 1000;
|
||||
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
key_pressed[key_code] = updown;
|
||||
if (updown) {
|
||||
++key_down_count;
|
||||
key_last_down = key_code;
|
||||
key_down_time = clock();
|
||||
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);
|
||||
} else {
|
||||
if (key_last_down == key_code) {
|
||||
long duration = clock() - key_down_time;
|
||||
if (duration > long_threshold) {
|
||||
long_press = true;
|
||||
}
|
||||
long_press = key_long_press;
|
||||
register_key = true;
|
||||
}
|
||||
key_last_down = -1;
|
||||
@@ -152,6 +156,24 @@ void RecoveryUI::process_key(int key_code, int updown) {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void RecoveryUI::time_key(int key_code, int count) {
|
||||
usleep(750000); // 750 ms == "long"
|
||||
bool long_press = false;
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
if (key_last_down == key_code && key_down_count == count) {
|
||||
long_press = key_long_press = true;
|
||||
}
|
||||
pthread_mutex_unlock(&key_queue_mutex);
|
||||
if (long_press) KeyLongPress(key_code);
|
||||
}
|
||||
|
||||
void RecoveryUI::EnqueueKey(int key_code) {
|
||||
pthread_mutex_lock(&key_queue_mutex);
|
||||
const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]);
|
||||
@@ -242,3 +264,6 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key) {
|
||||
|
||||
void RecoveryUI::NextCheckKeyIsLong(bool is_long_press) {
|
||||
}
|
||||
|
||||
void RecoveryUI::KeyLongPress(int key) {
|
||||
}
|
||||
|
||||
@@ -80,8 +80,17 @@ class RecoveryUI {
|
||||
enum KeyAction { ENQUEUE, TOGGLE, REBOOT, IGNORE };
|
||||
virtual KeyAction CheckKey(int key);
|
||||
|
||||
// Called immediately before each call to CheckKey(), tell you if
|
||||
// the key was long-pressed.
|
||||
virtual void NextCheckKeyIsLong(bool is_long_press);
|
||||
|
||||
// Called when a key is held down long enough to have been a
|
||||
// long-press (but before the key is released). This means that
|
||||
// if the key is eventually registered (released without any other
|
||||
// keys being pressed in the meantime), NextCheckKeyIsLong() will
|
||||
// be called with "true".
|
||||
virtual void KeyLongPress(int key);
|
||||
|
||||
// --- menu display ---
|
||||
|
||||
// Display some header text followed by a menu of items, which appears
|
||||
@@ -108,15 +117,25 @@ private:
|
||||
int key_queue[256], key_queue_len;
|
||||
char key_pressed[KEY_MAX + 1]; // under key_queue_mutex
|
||||
int key_last_down; // under key_queue_mutex
|
||||
clock_t key_down_time; // under key_queue_mutex
|
||||
bool key_long_press; // under key_queue_mutex
|
||||
int key_down_count; // under key_queue_mutex
|
||||
int rel_sum;
|
||||
|
||||
typedef struct {
|
||||
RecoveryUI* ui;
|
||||
int key_code;
|
||||
int count;
|
||||
} key_timer_t;
|
||||
|
||||
pthread_t input_t;
|
||||
|
||||
static void* input_thread(void* cookie);
|
||||
static int input_callback(int fd, short revents, void* data);
|
||||
void process_key(int key_code, int updown);
|
||||
bool usb_connected();
|
||||
|
||||
static void* time_key_helper(void* cookie);
|
||||
void time_key(int key_code, int count);
|
||||
};
|
||||
|
||||
#endif // RECOVERY_UI_H
|
||||
|
||||
Reference in New Issue
Block a user