aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Zongker <dougz@android.com>2011-01-25 13:15:30 -0800
committerDoug Zongker <dougz@android.com>2011-01-25 13:50:16 -0800
commit5cae445e43c5928daba0a76745b0dd2657274eda (patch)
tree2afc1e07d1dbd6e677af74419b31c321641b33aa
parent8f132ed870b4b83727d59f8019b8fabe49fe8ed4 (diff)
downloadbootable_recovery-5cae445e43c5928daba0a76745b0dd2657274eda.zip
bootable_recovery-5cae445e43c5928daba0a76745b0dd2657274eda.tar.gz
bootable_recovery-5cae445e43c5928daba0a76745b0dd2657274eda.tar.bz2
make recovery reboot after 2 minutes of no activity
If recovery sits for 2 minutes in prompt_and_wait(), and you've never turned the screen on via the magic keypress, go ahead and reboot. (We used to assume that the user could pull the battery to get out of this state, but on devices with nonremovable batteries...) If you've ever enabled display of the log/menu since recovery started, we assume you know what you're doing and will stay in recovery until you choose to reboot. Bug: 3387873 Bug: 3387274 Change-Id: I041621e5db132df9a925e6808845a7c45e1b427a
-rw-r--r--common.h1
-rw-r--r--recovery.c10
-rw-r--r--ui.c35
3 files changed, 42 insertions, 4 deletions
diff --git a/common.h b/common.h
index 97e87ee..d99daaf 100644
--- a/common.h
+++ b/common.h
@@ -26,6 +26,7 @@ void ui_init();
int ui_wait_key(); // waits for a key/button press, returns the code
int ui_key_pressed(int key); // returns >0 if the code is currently pressed
int ui_text_visible(); // returns >0 if text log is currently visible
+int ui_text_ever_visible(); // returns >0 if text log was ever visible
void ui_show_text(int visible);
void ui_clear_key_queue();
diff --git a/recovery.c b/recovery.c
index 9ad075d..c81a13c 100644
--- a/recovery.c
+++ b/recovery.c
@@ -446,6 +446,16 @@ get_menu_selection(char** headers, char** items, int menu_only,
int key = ui_wait_key();
int visible = ui_text_visible();
+ if (key == -1) { // ui_wait_key() timed out
+ if (ui_text_ever_visible()) {
+ continue;
+ } else {
+ LOGI("timed out waiting for key input; rebooting.\n");
+ ui_end_menu();
+ return ITEM_REBOOT;
+ }
+ }
+
int action = device_handle_key(key, visible);
if (action < 0) {
diff --git a/ui.c b/ui.c
index 84a9b85..82004f0 100644
--- a/ui.c
+++ b/ui.c
@@ -24,6 +24,7 @@
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
+#include <errno.h>
#include "common.h"
#include "minui/minui.h"
@@ -38,6 +39,8 @@
#define PROGRESSBAR_INDETERMINATE_STATES 6
#define PROGRESSBAR_INDETERMINATE_FPS 15
+#define UI_WAIT_KEY_TIMEOUT_SEC 120
+
static pthread_mutex_t gUpdateMutex = PTHREAD_MUTEX_INITIALIZER;
static gr_surface gBackgroundIcon[NUM_BACKGROUND_ICONS];
static gr_surface gProgressBarIndeterminate[PROGRESSBAR_INDETERMINATE_STATES];
@@ -78,6 +81,7 @@ static char text[MAX_ROWS][MAX_COLS];
static int text_cols = 0, text_rows = 0;
static int text_col = 0, text_row = 0, text_top = 0;
static int show_text = 0;
+static int show_text_ever = 0; // has show_text ever been 1?
static char menu[MAX_ROWS][MAX_COLS];
static int show_menu = 0;
@@ -295,6 +299,7 @@ static void *input_thread(void *cookie)
if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) {
pthread_mutex_lock(&gUpdateMutex);
show_text = !show_text;
+ if (show_text) show_text_ever = 1;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
@@ -481,10 +486,19 @@ int ui_text_visible()
return visible;
}
+int ui_text_ever_visible()
+{
+ pthread_mutex_lock(&gUpdateMutex);
+ int ever_visible = show_text_ever;
+ pthread_mutex_unlock(&gUpdateMutex);
+ return ever_visible;
+}
+
void ui_show_text(int visible)
{
pthread_mutex_lock(&gUpdateMutex);
show_text = visible;
+ if (show_text) show_text_ever = 1;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
@@ -492,12 +506,25 @@ void ui_show_text(int visible)
int ui_wait_key()
{
pthread_mutex_lock(&key_queue_mutex);
- while (key_queue_len == 0) {
- pthread_cond_wait(&key_queue_cond, &key_queue_mutex);
+
+ struct timeval now;
+ struct timespec timeout;
+ gettimeofday(&now, NULL);
+ 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);
}
- int key = key_queue[0];
- memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
+ 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;
}