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
diff --git a/recovery.cpp b/recovery.cpp
index c5a589c..38366b6 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -75,6 +75,7 @@
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 @@
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 @@
printf("\n");
property_list(print_property, NULL);
+ property_get("ro.build.display.id", recovery_version, "");
printf("\n");
int status = INSTALL_SUCCESS;
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 93e2609..6a63858 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -196,9 +196,29 @@
}
}
-#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 @@
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 @@
update_screen_locked();
pthread_mutex_unlock(&updateMutex);
}
+
+void ScreenRecoveryUI::Redraw()
+{
+ pthread_mutex_lock(&updateMutex);
+ update_screen_locked();
+ pthread_mutex_unlock(&updateMutex);
+}
diff --git a/screen_ui.h b/screen_ui.h
index fe0de46..0bd220f 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -53,6 +53,11 @@
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;
diff --git a/ui.cpp b/ui.cpp
index 65f4028..cece02d 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -46,7 +46,8 @@
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 @@
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::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 @@
void RecoveryUI::NextCheckKeyIsLong(bool is_long_press) {
}
+
+void RecoveryUI::KeyLongPress(int key) {
+}
diff --git a/ui.h b/ui.h
index aca7b7b..6c8987a 100644
--- a/ui.h
+++ b/ui.h
@@ -80,8 +80,17 @@
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 @@
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