aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoushik Dutta <koush@koushikdutta.com>2013-04-10 14:46:43 -0700
committerKoushik Dutta <koushd@gmail.com>2013-04-10 18:48:01 -0700
commitfba8e1618c86c2b6ae571c6ed1f19f776fde4ab7 (patch)
treef53a1055f79fd6395a30830cbdd3617ce0427e7b
parentd9ea07f6bbf4e8e795cd298724ffd334268ed9d8 (diff)
downloadbootable_recovery-fba8e1618c86c2b6ae571c6ed1f19f776fde4ab7.zip
bootable_recovery-fba8e1618c86c2b6ae571c6ed1f19f776fde4ab7.tar.gz
bootable_recovery-fba8e1618c86c2b6ae571c6ed1f19f776fde4ab7.tar.bz2
Allow cancelation of adb sideload.
Change-Id: I1cc5a6719c3fe547afe944a94e134519c2c45fc6
-rw-r--r--adb_install.c54
-rw-r--r--common.h1
-rw-r--r--recovery.c8
-rw-r--r--ui.c8
4 files changed, 54 insertions, 17 deletions
diff --git a/adb_install.c b/adb_install.c
index a87858c..00c3cc0 100644
--- a/adb_install.c
+++ b/adb_install.c
@@ -17,6 +17,7 @@
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -29,6 +30,7 @@
#include "cutils/properties.h"
#include "install.h"
#include "common.h"
+#include "recovery_ui.h"
#include "adb_install.h"
#include "minadbd/adb.h"
@@ -74,6 +76,27 @@ maybe_restart_adbd() {
}
}
+struct sideload_waiter_data {
+ pid_t child;
+};
+
+void *adb_sideload_thread(void* v) {
+ struct sideload_waiter_data* data = (struct sideload_waiter_data*)v;
+
+ int status;
+ waitpid(data->child, &status, 0);
+ LOGI("sideload process finished\n");
+
+ ui_cancel_wait_key();
+
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ ui_print("status %d\n", WEXITSTATUS(status));
+ }
+
+ LOGI("sideload thread finished\n");
+ return NULL;
+}
+
int
apply_from_adb() {
@@ -83,25 +106,32 @@ apply_from_adb() {
ui_print("\n\nSideload started ...\nNow send the package you want to apply\n"
"to the device with \"adb sideload <filename>\"...\n\n");
- pid_t child;
- if ((child = fork()) == 0) {
+ struct sideload_waiter_data data;
+ if ((data.child = fork()) == 0) {
execl("/sbin/recovery", "recovery", "adbd", NULL);
_exit(-1);
}
- int status;
- // TODO(dougz): there should be a way to cancel waiting for a
- // package (by pushing some button combo on the device). For now
- // you just have to 'adb sideload' a file that's not a valid
- // package, like "/dev/null".
- waitpid(child, &status, 0);
-
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- ui_print("status %d\n", WEXITSTATUS(status));
- }
+
+ pthread_t sideload_thread;
+ pthread_create(&sideload_thread, NULL, &adb_sideload_thread, &data);
+
+ static char* headers[] = { "ADB Sideload",
+ "",
+ NULL
+ };
+
+ static char* list[] = { "Cancel sideload", NULL };
+
+ get_menu_selection(headers, list, 0, 0);
set_usb_driver(0);
maybe_restart_adbd();
+ // kill the child
+ kill(data.child, SIGTERM);
+ pthread_join(&sideload_thread, NULL);
+ ui_clear_key_queue();
+
struct stat st;
if (stat(ADB_SIDELOAD_FILENAME, &st) != 0) {
if (errno == ENOENT) {
diff --git a/common.h b/common.h
index b203362..7580f32 100644
--- a/common.h
+++ b/common.h
@@ -23,6 +23,7 @@
void ui_init();
// Use KEY_* codes from <linux/input.h> or KEY_DREAM_* from "minui/minui.h".
+void ui_cancel_wait_key();
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
diff --git a/recovery.c b/recovery.c
index 9aa19ef..6e50541 100644
--- a/recovery.c
+++ b/recovery.c
@@ -441,11 +441,6 @@ get_menu_selection(char** headers, char** items, int menu_only,
int selected = initial_selection;
int chosen_item = -1;
- // Some users with dead enter keys need a way to turn on power to select.
- // Jiggering across the wrapping menu is one "secret" way to enable it.
- // We can't rely on /cache or /sdcard since they may not be available.
- int wrap_count = 0;
-
while (chosen_item < 0 && chosen_item != GO_BACK) {
int key = ui_wait_key();
int visible = ui_text_visible();
@@ -459,6 +454,9 @@ get_menu_selection(char** headers, char** items, int menu_only,
return ITEM_REBOOT;
}
}
+ else if (key == -2) {
+ return GO_BACK;
+ }
int action = ui_handle_key(key, visible);
diff --git a/ui.c b/ui.c
index b536c0c..785d70a 100644
--- a/ui.c
+++ b/ui.c
@@ -857,6 +857,14 @@ static int usb_connected() {
return connected;
}
+void ui_cancel_wait_key() {
+ pthread_mutex_lock(&key_queue_mutex);
+ key_queue[key_queue_len] = -2;
+ key_queue_len++;
+ pthread_cond_signal(&key_queue_cond);
+ pthread_mutex_unlock(&key_queue_mutex);
+}
+
int ui_wait_key()
{
if (boardEnableKeyRepeat) return ui_wait_key_with_repeat();