diff options
-rw-r--r-- | default_recovery_ui.c | 1 | ||||
-rw-r--r-- | minui/graphics.c | 39 | ||||
-rw-r--r-- | recovery.c | 40 | ||||
-rw-r--r-- | recovery_ui.h | 1 |
4 files changed, 70 insertions, 11 deletions
diff --git a/default_recovery_ui.c b/default_recovery_ui.c index 7c4017e7e..d56164e7e 100644 --- a/default_recovery_ui.c +++ b/default_recovery_ui.c @@ -27,6 +27,7 @@ char* MENU_ITEMS[] = { "reboot system now", "apply update from external storage", "wipe data/factory reset", "wipe cache partition", + "apply update from cache", NULL }; void device_ui_init(UIParameters* ui_parameters) { diff --git a/minui/graphics.c b/minui/graphics.c index 741d69f46..b79631a31 100644 --- a/minui/graphics.c +++ b/minui/graphics.c @@ -74,13 +74,48 @@ static int get_framebuffer(GGLSurface *fb) return -1; } - if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { + if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { perror("failed to get fb0 info"); close(fd); return -1; } - if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { + vi.bits_per_pixel = PIXEL_SIZE * 8; + if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_BGRA_8888) { + vi.red.offset = 8; + vi.red.length = 8; + vi.green.offset = 16; + vi.green.length = 8; + vi.blue.offset = 24; + vi.blue.length = 8; + vi.transp.offset = 0; + vi.transp.length = 8; + } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBX_8888) { + vi.red.offset = 24; + vi.red.length = 8; + vi.green.offset = 16; + vi.green.length = 8; + vi.blue.offset = 8; + vi.blue.length = 8; + vi.transp.offset = 0; + vi.transp.length = 8; + } else { /* RGB565*/ + vi.red.offset = 11; + vi.red.length = 5; + vi.green.offset = 5; + vi.green.length = 6; + vi.blue.offset = 0; + vi.blue.length = 5; + vi.transp.offset = 0; + vi.transp.length = 0; + } + if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) { + perror("failed to put fb0 info"); + close(fd); + return -1; + } + + if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { perror("failed to get fb0 info"); close(fd); return -1; diff --git a/recovery.c b/recovery.c index 3a412d5c5..1e3eb5afb 100644 --- a/recovery.c +++ b/recovery.c @@ -52,6 +52,7 @@ static const char *COMMAND_FILE = "/cache/recovery/command"; static const char *INTENT_FILE = "/cache/recovery/intent"; static const char *LOG_FILE = "/cache/recovery/log"; static const char *LAST_LOG_FILE = "/cache/recovery/last_log"; +static const char *CACHE_ROOT = "/cache"; static const char *SDCARD_ROOT = "/sdcard"; static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log"; static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload"; @@ -468,8 +469,8 @@ static int compare_string(const void* a, const void* b) { } static int -sdcard_directory(const char* path) { - ensure_path_mounted(SDCARD_ROOT); +update_directory(const char* path, const char* unmount_when_done) { + ensure_path_mounted(path); const char* MENU_HEADERS[] = { "Choose a package to install:", path, @@ -480,7 +481,9 @@ sdcard_directory(const char* path) { d = opendir(path); if (d == NULL) { LOGE("error opening %s: %s\n", path, strerror(errno)); - ensure_path_unmounted(SDCARD_ROOT); + if (unmount_when_done != NULL) { + ensure_path_unmounted(unmount_when_done); + } return 0; } @@ -545,7 +548,7 @@ sdcard_directory(const char* path) { char* item = zips[chosen_item]; int item_len = strlen(item); if (chosen_item == 0) { // item 0 is always "../" - // go up but continue browsing (if the caller is sdcard_directory) + // go up but continue browsing (if the caller is update_directory) result = -1; break; } else if (item[item_len-1] == '/') { @@ -555,7 +558,7 @@ sdcard_directory(const char* path) { strlcat(new_path, "/", PATH_MAX); strlcat(new_path, item, PATH_MAX); new_path[strlen(new_path)-1] = '\0'; // truncate the trailing '/' - result = sdcard_directory(new_path); + result = update_directory(new_path, unmount_when_done); if (result >= 0) break; } else { // selected a zip file: attempt to install it, and return @@ -568,7 +571,9 @@ sdcard_directory(const char* path) { ui_print("\n-- Install %s ...\n", path); set_sdcard_update_bootloader_message(); char* copy = copy_sideloaded_package(new_path); - ensure_path_unmounted(SDCARD_ROOT); + if (unmount_when_done != NULL) { + ensure_path_unmounted(unmount_when_done); + } if (copy) { result = install_package(copy); free(copy); @@ -584,7 +589,9 @@ sdcard_directory(const char* path) { free(zips); free(headers); - ensure_path_unmounted(SDCARD_ROOT); + if (unmount_when_done != NULL) { + ensure_path_unmounted(unmount_when_done); + } return result; } @@ -642,6 +649,7 @@ prompt_and_wait() { // statement below. chosen_item = device_perform_action(chosen_item); + int status; switch (chosen_item) { case ITEM_REBOOT: return; @@ -659,8 +667,7 @@ prompt_and_wait() { break; case ITEM_APPLY_SDCARD: - ; - int status = sdcard_directory(SDCARD_ROOT); + status = update_directory(SDCARD_ROOT, SDCARD_ROOT); if (status >= 0) { if (status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); @@ -672,6 +679,21 @@ prompt_and_wait() { } } break; + case ITEM_APPLY_CACHE: + // Don't unmount cache at the end of this. + status = update_directory(CACHE_ROOT, NULL); + if (status >= 0) { + if (status != INSTALL_SUCCESS) { + ui_set_background(BACKGROUND_ICON_ERROR); + ui_print("Installation aborted.\n"); + } else if (!ui_text_visible()) { + return; // reboot if logs aren't visible + } else { + ui_print("\nInstall from cache complete.\n"); + } + } + break; + } } } diff --git a/recovery_ui.h b/recovery_ui.h index e56a24b29..5f0177045 100644 --- a/recovery_ui.h +++ b/recovery_ui.h @@ -76,6 +76,7 @@ int device_wipe_data(); #define ITEM_APPLY_SDCARD 1 // historical synonym for ITEM_APPLY_EXT #define ITEM_WIPE_DATA 2 #define ITEM_WIPE_CACHE 3 +#define ITEM_APPLY_CACHE 4 // Header text to display above the main menu. extern char* MENU_HEADERS[]; |