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.
This commit is contained in:
Doug Zongker 2009-06-09 12:22:33 -07:00
parent d9d9d1785a
commit ddd6a2865d
6 changed files with 171 additions and 72 deletions

View File

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

61
default_recovery_ui.c Normal file
View File

@ -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;
}
void device_perform_action(int which) {
// none defined
}

View File

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

View File

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

68
recovery_ui.h Normal file
View File

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

10
ui.c
View File

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