diff options
-rw-r--r-- | Android.mk | 14 | ||||
-rw-r--r-- | default_recovery_ui.c | 61 | ||||
-rw-r--r-- | minui/graphics.c | 1 | ||||
-rw-r--r-- | minui/minui.h | 16 | ||||
-rw-r--r-- | recovery.c | 84 | ||||
-rw-r--r-- | recovery_ui.h | 68 | ||||
-rw-r--r-- | ui.c | 10 |
7 files changed, 186 insertions, 68 deletions
diff --git a/Android.mk b/Android.mk index 0367fef70..f04f7ddcc 100644 --- a/Android.mk +++ b/Android.mk @@ -1,11 +1,11 @@ +ifneq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_ARCH),arm) + LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) commands_recovery_local_path := $(LOCAL_PATH) -ifneq ($(TARGET_SIMULATOR),true) -ifeq ($(TARGET_ARCH),arm) - LOCAL_SRC_FILES := \ recovery.c \ bootloader.c \ @@ -32,7 +32,13 @@ LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION) LOCAL_MODULE_TAGS := eng -LOCAL_STATIC_LIBRARIES := libminzip libunz libamend libmtdutils libmincrypt +LOCAL_STATIC_LIBRARIES := +ifeq ($(TARGET_RECOVERY_UI_LIB),) + LOCAL_SRC_FILES += default_recovery_ui.c +else + LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB) +endif +LOCAL_STATIC_LIBRARIES += libminzip libunz libamend libmtdutils libmincrypt LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils LOCAL_STATIC_LIBRARIES += libstdc++ libc diff --git a/default_recovery_ui.c b/default_recovery_ui.c new file mode 100644 index 000000000..76fa43ea9 --- /dev/null +++ b/default_recovery_ui.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <linux/input.h> + +#include "recovery_ui.h" +#include "common.h" + +char* MENU_HEADERS[] = { "Android system recovery utility", + "", + NULL }; + +char* MENU_ITEMS[] = { "reboot system now", + "apply sdcard:update.zip", + "wipe data/factory reset", + "wipe cache partition", + NULL }; + +int device_toggle_display(char* key_pressed, int key_code) { + return key_code == KEY_HOME; +} + +int device_reboot_now(char* key_pressed, int key_code) { + return 0; +} + +int device_handle_key(int key_code, int visible) { + if (visible) { + switch (key_code) { + case KEY_DOWN: + case KEY_VOLUMEDOWN: + return HIGHLIGHT_DOWN; + + case KEY_UP: + case KEY_VOLUMEUP: + return HIGHLIGHT_UP; + + case KEY_ENTER: + return SELECT_ITEM; + } + } + + return NO_ACTION; +} + +int device_perform_action(int which) { + return which; +} diff --git a/minui/graphics.c b/minui/graphics.c index 06c5fdfcd..adbfc09da 100644 --- a/minui/graphics.c +++ b/minui/graphics.c @@ -115,6 +115,7 @@ static void set_active_framebuffer(unsigned n) if (n > 1) return; vi.yres_virtual = vi.yres * 2; vi.yoffset = n * vi.yres; + vi.bits_per_pixel = 16; if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { perror("active fb swap failed"); } diff --git a/minui/minui.h b/minui/minui.h index 80b47a47f..567d42157 100644 --- a/minui/minui.h +++ b/minui/minui.h @@ -41,22 +41,6 @@ unsigned int gr_get_height(gr_surface surface); // see http://www.mjmwired.net/kernel/Documentation/input/ for info. struct input_event; -// Dream-specific key codes -#define KEY_DREAM_HOME 102 // = KEY_HOME -#define KEY_DREAM_RED 107 // = KEY_END -#define KEY_DREAM_VOLUMEDOWN 114 // = KEY_VOLUMEDOWN -#define KEY_DREAM_VOLUMEUP 115 // = KEY_VOLUMEUP -#define KEY_DREAM_SYM 127 // = KEY_COMPOSE -#define KEY_DREAM_MENU 139 // = KEY_MENU -#define KEY_DREAM_BACK 158 // = KEY_BACK -#define KEY_DREAM_FOCUS 211 // = KEY_HP (light touch on camera) -#define KEY_DREAM_CAMERA 212 // = KEY_CAMERA -#define KEY_DREAM_AT 215 // = KEY_EMAIL -#define KEY_DREAM_GREEN 231 -#define KEY_DREAM_FATTOUCH 258 // = BTN_2 ??? -#define KEY_DREAM_BALL 272 // = BTN_MOUSE -#define KEY_DREAM_TOUCH 330 // = BTN_TOUCH - int ev_init(void); void ev_exit(void); int ev_get(struct input_event *ev, unsigned dont_wait); diff --git a/recovery.c b/recovery.c index 5ccd38f2c..8ad133948 100644 --- a/recovery.c +++ b/recovery.c @@ -37,6 +37,7 @@ #include "minui/minui.h" #include "minzip/DirUtil.h" #include "roots.h" +#include "recovery_ui.h" static const struct option OPTIONS[] = { { "send_intent", required_argument, NULL, 's' }, @@ -287,26 +288,25 @@ erase_root(const char *root) static void prompt_and_wait() { - char* headers[] = { "Android system recovery <" + char* title[] = { "Android system recovery <" EXPAND(RECOVERY_API_VERSION) ">", - "", - "Use trackball to highlight;", - "click to select.", - "", - NULL }; - - // these constants correspond to elements of the items[] list. -#define ITEM_REBOOT 0 -#define ITEM_APPLY_SDCARD 1 -#define ITEM_WIPE_DATA 2 -#define ITEM_WIPE_CACHE 3 - char* items[] = { "reboot system now [Home+Back]", - "apply sdcard:update.zip [Alt+S]", - "wipe data/factory reset [Alt+W]", - "wipe cache partition", + "", NULL }; - ui_start_menu(headers, items); + // count the number of lines in our title, plus the + // product-provided headers. + int count = 0; + char** p; + for (p = title; *p; ++p, ++count); + for (p = MENU_HEADERS; *p; ++p, ++count); + + char** headers = malloc((count+1) * sizeof(char*)); + char** h = headers; + for (p = title; *p; ++p, ++h) *h = *p; + for (p = MENU_HEADERS; *p; ++p, ++h) *h = *p; + *h = NULL; + + ui_start_menu(headers, MENU_ITEMS); int selected = 0; int chosen_item = -1; @@ -314,29 +314,28 @@ prompt_and_wait() ui_reset_progress(); for (;;) { int key = ui_wait_key(); - int alt = ui_key_pressed(KEY_LEFTALT) || ui_key_pressed(KEY_RIGHTALT); int visible = ui_text_visible(); - if (key == KEY_DREAM_BACK && ui_key_pressed(KEY_DREAM_HOME)) { - // Wait for the keys to be released, to avoid triggering - // special boot modes (like coming back into recovery!). - while (ui_key_pressed(KEY_DREAM_BACK) || - ui_key_pressed(KEY_DREAM_HOME)) { - usleep(1000); + int action = device_handle_key(key, visible); + + if (action < 0) { + switch (action) { + case HIGHLIGHT_UP: + --selected; + selected = ui_menu_select(selected); + break; + case HIGHLIGHT_DOWN: + ++selected; + selected = ui_menu_select(selected); + break; + case SELECT_ITEM: + chosen_item = selected; + break; + case NO_ACTION: + break; } - chosen_item = ITEM_REBOOT; - } else if (alt && key == KEY_W) { - chosen_item = ITEM_WIPE_DATA; - } else if (alt && key == KEY_S) { - chosen_item = ITEM_APPLY_SDCARD; - } else if ((key == KEY_DOWN || key == KEY_VOLUMEDOWN) && visible) { - ++selected; - selected = ui_menu_select(selected); - } else if ((key == KEY_UP || key == KEY_VOLUMEUP) && visible) { - --selected; - selected = ui_menu_select(selected); - } else if (key == BTN_MOUSE && visible) { - chosen_item = selected; + } else { + chosen_item = action; } if (chosen_item >= 0) { @@ -344,6 +343,11 @@ prompt_and_wait() // on the screen. ui_end_menu(); + // device-specific code may take some action here. It may + // return one of the core actions handled in the switch + // statement below. + chosen_item = device_perform_action(chosen_item); + switch (chosen_item) { case ITEM_REBOOT: return; @@ -373,8 +377,8 @@ prompt_and_wait() return; // reboot if logs aren't visible } else { if (firmware_update_pending()) { - ui_print("\nReboot via home+back or menu\n" - "to complete installation.\n"); + ui_print("\nReboot via menu to complete\n" + "installation.\n"); } else { ui_print("\nInstall from sdcard complete.\n"); } @@ -384,7 +388,7 @@ prompt_and_wait() // if we didn't return from this function to reboot, show // the menu again. - ui_start_menu(headers, items); + ui_start_menu(headers, MENU_ITEMS); selected = 0; chosen_item = -1; diff --git a/recovery_ui.h b/recovery_ui.h new file mode 100644 index 000000000..86f540b6e --- /dev/null +++ b/recovery_ui.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _RECOVERY_UI_H +#define _RECOVERY_UI_H + +// Called in the input thread when a new key (key_code) is pressed. +// *key_pressed is an array of KEY_MAX+1 bytes indicating which other +// keys are already pressed. Return true if the text display should +// be toggled. +extern int device_toggle_display(char* key_pressed, int key_code); + +// Called in the input thread when a new key (key_code) is pressed. +// *key_pressed is an array of KEY_MAX+1 bytes indicating which other +// keys are already pressed. Return true if the device should reboot +// immediately. +extern int device_reboot_now(char* key_pressed, int key_code); + +// Called from the main thread when recovery is waiting for input and +// a key is pressed. key is the code of the key pressed; visible is +// true if the recovery menu is being shown. Implementations can call +// ui_key_pressed() to discover if other keys are being held down. +// Return one of the defined constants below in order to: +// +// - move the menu highlight (HIGHLIGHT_*) +// - invoke the highlighted item (SELECT_ITEM) +// - do nothing (NO_ACTION) +// - invoke a specific action (a menu position: any non-negative number) +extern int device_handle_key(int key, int visible); + +// Perform a recovery action selected from the menu. 'which' will be +// the item number of the selected menu item, or a non-negative number +// returned from device_handle_key(). The menu will be hidden when +// this is called; implementations can call ui_print() to print +// information to the screen. +extern int device_perform_action(int which); + +#define NO_ACTION -1 + +#define HIGHLIGHT_UP -2 +#define HIGHLIGHT_DOWN -3 +#define SELECT_ITEM -4 + +#define ITEM_REBOOT 0 +#define ITEM_APPLY_SDCARD 1 +#define ITEM_WIPE_DATA 2 +#define ITEM_WIPE_CACHE 3 + +// Header text to display above the main menu. +extern char* MENU_HEADERS[]; + +// Text of menu items. +extern char* MENU_ITEMS[]; + +#endif @@ -307,20 +307,14 @@ static void *input_thread(void *cookie) } pthread_mutex_unlock(&key_queue_mutex); - // Alt+L or Home+End: toggle log display - int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT]; - if ((alt && ev.code == KEY_L && ev.value > 0) || - (key_pressed[KEY_HOME] && ev.code == KEY_END && ev.value > 0)) { + if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) { pthread_mutex_lock(&gUpdateMutex); show_text = !show_text; update_screen_locked(); pthread_mutex_unlock(&gUpdateMutex); } - // Green+Menu+Red: reboot immediately - if (ev.code == KEY_DREAM_RED && - key_pressed[KEY_DREAM_MENU] && - key_pressed[KEY_DREAM_GREEN]) { + if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) { reboot(RB_AUTOBOOT); } } |