From ddd6a2865db5c73a4bb9d486f71a8c2f1f96ec69 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Tue, 9 Jun 2009 12:22:33 -0700 Subject: [PATCH] split out device-specific recovery UI code into vendor directories Take some device-specific details of the recovery UI (eg, what keys to press to bring up the interface and perform actions, exact text of the menu, etc.) and split them out into separate C functions. Arrange to take implementations of those functions from the appropriate vendor directory at build time. Provide a default implementation in case no vendor-specific one is available. --- Android.mk | 17 +++++++---- default_recovery_ui.c | 61 +++++++++++++++++++++++++++++++++++++ minui/minui.h | 16 ---------- recovery.c | 71 ++++++++++++++++++------------------------- recovery_ui.h | 68 +++++++++++++++++++++++++++++++++++++++++ ui.c | 10 ++---- 6 files changed, 171 insertions(+), 72 deletions(-) create mode 100644 default_recovery_ui.c create mode 100644 recovery_ui.h diff --git a/Android.mk b/Android.mk index 8c1de73..ba82017 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 \ @@ -29,17 +29,22 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true 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 include $(BUILD_EXECUTABLE) -include $(commands_recovery_local_path)/minui/Android.mk - endif # TARGET_ARCH == arm endif # !TARGET_SIMULATOR +include $(commands_recovery_local_path)/minui/Android.mk include $(commands_recovery_local_path)/amend/Android.mk include $(commands_recovery_local_path)/minzip/Android.mk include $(commands_recovery_local_path)/mtdutils/Android.mk diff --git a/default_recovery_ui.c b/default_recovery_ui.c new file mode 100644 index 0000000..7bc5f2c --- /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 + +#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; +} + +void device_perform_action(int which) { + // none defined +} diff --git a/minui/minui.h b/minui/minui.h index 80b47a4..567d421 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 188d4de..6c13b9f 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,25 +288,7 @@ erase_root(const char *root) static void prompt_and_wait() { - char* headers[] = { "Android system recovery utility", - "", - "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); + ui_start_menu(MENU_HEADERS, MENU_ITEMS); int selected = 0; int chosen_item = -1; @@ -313,29 +296,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) { @@ -343,6 +325,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; @@ -372,8 +359,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"); } @@ -383,7 +370,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(MENU_HEADERS, MENU_ITEMS); selected = 0; chosen_item = -1; diff --git a/recovery_ui.h b/recovery_ui.h new file mode 100644 index 0000000..86f540b --- /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 diff --git a/ui.c b/ui.c index b84f172..039d682 100644 --- a/ui.c +++ b/ui.c @@ -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); } }