Allow cancelation of adb sideload.

Change-Id: I1cc5a6719c3fe547afe944a94e134519c2c45fc6
This commit is contained in:
Koushik Dutta 2013-04-10 14:46:43 -07:00 committed by Koushik Dutta
parent d9ea07f6bb
commit fba8e1618c
4 changed files with 53 additions and 16 deletions

View File

@ -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);
pthread_t sideload_thread;
pthread_create(&sideload_thread, NULL, &adb_sideload_thread, &data);
static char* headers[] = { "ADB Sideload",
"",
NULL
};
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
ui_print("status %d\n", WEXITSTATUS(status));
}
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) {

View File

@ -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

View File

@ -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);

8
ui.c
View File

@ -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();