diff options
39 files changed, 165 insertions, 124 deletions
diff --git a/Android.mk b/Android.mk index 816d143cc..8c1de7366 100644 --- a/Android.mk +++ b/Android.mk @@ -30,24 +30,11 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_TAGS := eng LOCAL_STATIC_LIBRARIES := libminzip libunz libamend libmtdutils libmincrypt -LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libcutils +LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils LOCAL_STATIC_LIBRARIES += libstdc++ libc -# Specify a C-includable file containing the OTA public keys. -# This is built in config/Makefile. -# *** THIS IS A TOTAL HACK; EXECUTABLES MUST NOT CHANGE BETWEEN DIFFERENT -# PRODUCTS/BUILD TYPES. *** -# TODO: make recovery read the keys from an external file. -RECOVERY_INSTALL_OTA_KEYS_INC := \ - $(call intermediates-dir-for,PACKAGING,ota_keys_inc)/keys.inc -# Let install.c say #include "keys.inc" -LOCAL_C_INCLUDES += $(dir $(RECOVERY_INSTALL_OTA_KEYS_INC)) - include $(BUILD_EXECUTABLE) -# Depend on the generated keys.inc containing the OTA public keys. -$(intermediates)/install.o: $(RECOVERY_INSTALL_OTA_KEYS_INC) - include $(commands_recovery_local_path)/minui/Android.mk endif # TARGET_ARCH == arm @@ -47,7 +47,6 @@ void ui_end_menu(); // Set the icon (normally the only thing visible besides the progress bar). enum { BACKGROUND_ICON_NONE, - BACKGROUND_ICON_UNPACKING, BACKGROUND_ICON_INSTALLING, BACKGROUND_ICON_ERROR, BACKGROUND_ICON_FIRMWARE_INSTALLING, @@ -31,12 +31,8 @@ #include "roots.h" #include "verifier.h" -/* List of public keys */ -static const RSAPublicKey keys[] = { -#include "keys.inc" -}; - #define ASSUMED_UPDATE_SCRIPT_NAME "META-INF/com/google/android/update-script" +#define PUBLIC_KEYS_FILE "/res/keys" static const ZipEntry * find_update_script(ZipArchive *zip) @@ -114,7 +110,8 @@ handle_update_script(ZipArchive *zip, const ZipEntry *update_script_entry) } static int -handle_update_package(const char *path, ZipArchive *zip) +handle_update_package(const char *path, ZipArchive *zip, + const RSAPublicKey *keys, int numKeys) { // Give verification half the progress bar... ui_print("Verifying update package...\n"); @@ -122,7 +119,7 @@ handle_update_package(const char *path, ZipArchive *zip) VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); - if (!verify_jar_signature(zip, keys, sizeof(keys) / sizeof(keys[0]))) { + if (!verify_jar_signature(zip, keys, numKeys)) { LOGE("Verification failed\n"); return INSTALL_CORRUPT; } @@ -147,6 +144,80 @@ handle_update_package(const char *path, ZipArchive *zip) return ret; } +// Reads a file containing one or more public keys as produced by +// DumpPublicKey: this is an RSAPublicKey struct as it would appear +// as a C source literal, eg: +// +// "{64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}" +// +// (Note that the braces and commas in this example are actual +// characters the parser expects to find in the file; the ellipses +// indicate more numbers omitted from this example.) +// +// The file may contain multiple keys in this format, separated by +// commas. The last key must not be followed by a comma. +// +// Returns NULL if the file failed to parse, or if it contain zero keys. +static RSAPublicKey* +load_keys(const char* filename, int* numKeys) { + RSAPublicKey* out = NULL; + *numKeys = 0; + + FILE* f = fopen(filename, "r"); + if (f == NULL) { + LOGE("opening %s: %s\n", filename, strerror(errno)); + goto exit; + } + + int i; + bool done = false; + while (!done) { + ++*numKeys; + out = realloc(out, *numKeys * sizeof(RSAPublicKey)); + RSAPublicKey* key = out + (*numKeys - 1); + if (fscanf(f, " { %i , %i , { %i", + &(key->len), &(key->n0inv), &(key->n[0])) != 3) { + goto exit; + } + if (key->len != RSANUMWORDS) { + LOGE("key length (%d) does not match expected size\n", key->len); + goto exit; + } + for (i = 1; i < key->len; ++i) { + if (fscanf(f, " , %i", &(key->n[i])) != 1) goto exit; + } + if (fscanf(f, " } , { %i", &(key->rr[0])) != 1) goto exit; + for (i = 1; i < key->len; ++i) { + if (fscanf(f, " , %i", &(key->rr[i])) != 1) goto exit; + } + fscanf(f, " } } "); + + // if the line ends in a comma, this file has more keys. + switch (fgetc(f)) { + case ',': + // more keys to come. + break; + + case EOF: + done = true; + break; + + default: + LOGE("unexpected character between keys\n"); + goto exit; + } + } + + fclose(f); + return out; + +exit: + if (f) fclose(f); + free(out); + *numKeys = 0; + return NULL; +} + int install_package(const char *root_path) { @@ -169,6 +240,14 @@ install_package(const char *root_path) ui_print("Opening update package...\n"); LOGI("Update file path: %s\n", path); + int numKeys; + RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); + if (loadedKeys == NULL) { + LOGE("Failed to load keys\n"); + return INSTALL_CORRUPT; + } + LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); + /* Try to open the package. */ ZipArchive zip; @@ -180,7 +259,8 @@ install_package(const char *root_path) /* Verify and install the contents of the package. */ - int status = handle_update_package(path, &zip); + int status = handle_update_package(path, &zip, loadedKeys, numKeys); mzCloseZipArchive(&zip); + free(loadedKeys); return status; } diff --git a/minui/resources.c b/minui/resources.c index 5beb6a6d9..7ecfeefce 100644 --- a/minui/resources.c +++ b/minui/resources.c @@ -29,97 +29,84 @@ #include <pixelflinger/pixelflinger.h> +#include <png.h> + #include "minui.h" -// File signature for BMP files. -// The letters 'BM' as a little-endian unsigned short. - -#define BMP_SIGNATURE 0x4d42 - -typedef struct { - // constant, value should equal BMP_SIGNATURE - unsigned short bfType; - // size of the file in bytes. - unsigned long bfSize; - // must always be set to zero. - unsigned short bfReserved1; - // must always be set to zero. - unsigned short bfReserved2; - // offset from the beginning of the file to the bitmap data. - unsigned long bfOffBits; - - // The BITMAPINFOHEADER: - // size of the BITMAPINFOHEADER structure, in bytes. - unsigned long biSize; - // width of the image, in pixels. - unsigned long biWidth; - // height of the image, in pixels. - unsigned long biHeight; - // number of planes of the target device, must be set to 1. - unsigned short biPlanes; - // number of bits per pixel. - unsigned short biBitCount; - // type of compression, zero means no compression. - unsigned long biCompression; - // size of the image data, in bytes. If there is no compression, - // it is valid to set this member to zero. - unsigned long biSizeImage; - // horizontal pixels per meter on the designated targer device, - // usually set to zero. - unsigned long biXPelsPerMeter; - // vertical pixels per meter on the designated targer device, - // usually set to zero. - unsigned long biYPelsPerMeter; - // number of colors used in the bitmap, if set to zero the - // number of colors is calculated using the biBitCount member. - unsigned long biClrUsed; - // number of color that are 'important' for the bitmap, - // if set to zero, all colors are important. - unsigned long biClrImportant; -} __attribute__((packed)) BitMapFileHeader; +// libpng gives "undefined reference to 'pow'" errors, and I have no +// idea how to convince the build system to link with -lm. We don't +// need this functionality (it's used for gamma adjustment) so provide +// a dummy implementation to satisfy the linker. +double pow(double x, double y) { + return x; +} int res_create_surface(const char* name, gr_surface* pSurface) { char resPath[256]; - BitMapFileHeader header; GGLSurface* surface = NULL; int result = 0; - - snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.bmp", name); + unsigned char header[8]; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + + snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name); resPath[sizeof(resPath)-1] = '\0'; - int fd = open(resPath, O_RDONLY); - if (fd == -1) { + FILE* fp = fopen(resPath, "rb"); + if (fp == NULL) { result = -1; goto exit; } - size_t bytesRead = read(fd, &header, sizeof(header)); + + size_t bytesRead = fread(header, 1, sizeof(header), fp); if (bytesRead != sizeof(header)) { result = -2; goto exit; } - if (header.bfType != BMP_SIGNATURE) { - result = -3; // Not a legal header + + if (png_sig_cmp(header, 0, sizeof(header))) { + result = -3; goto exit; } - if (header.biPlanes != 1) { + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { result = -4; goto exit; } - if (!(header.biBitCount == 24 || header.biBitCount == 32)) { + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { result = -5; goto exit; } - if (header.biCompression != 0) { + + if (setjmp(png_jmpbuf(png_ptr))) { result = -6; goto exit; } - size_t width = header.biWidth; - size_t height = header.biHeight; + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, sizeof(header)); + png_read_info(png_ptr, info_ptr); + + size_t width = info_ptr->width; + size_t height = info_ptr->height; size_t stride = 4 * width; size_t pixelSize = stride * height; - + + int color_type = info_ptr->color_type; + int bit_depth = info_ptr->bit_depth; + int channels = info_ptr->channels; + if (bit_depth != 8 || (channels != 3 && channels != 4) || + (color_type != PNG_COLOR_TYPE_RGB && + color_type != PNG_COLOR_TYPE_RGBA)) { + return -7; + goto exit; + } + surface = malloc(sizeof(GGLSurface) + pixelSize); if (surface == NULL) { - result = -7; + result = -8; goto exit; } unsigned char* pData = (unsigned char*) (surface + 1); @@ -128,63 +115,43 @@ int res_create_surface(const char* name, gr_surface* pSurface) { surface->height = height; surface->stride = width; /* Yes, pixels, not bytes */ surface->data = pData; - surface->format = (header.biBitCount == 24) ? + surface->format = (channels == 3) ? GGL_PIXEL_FORMAT_RGBX_8888 : GGL_PIXEL_FORMAT_RGBA_8888; - // Source pixel bytes are stored B G R {A} - - lseek(fd, header.bfOffBits, SEEK_SET); - size_t y; - if (header.biBitCount == 24) { // RGB - size_t inputStride = (((3 * width + 3) >> 2) << 2); - for (y = 0; y < height; y++) { - unsigned char* pRow = pData + (height - (y + 1)) * stride; - bytesRead = read(fd, pRow, inputStride); - if (bytesRead != inputStride) { - result = -8; - goto exit; - } + int y; + if (channels == 3) { + for (y = 0; y < height; ++y) { + unsigned char* pRow = pData + y * stride; + png_read_row(png_ptr, pRow, NULL); + int x; for(x = width - 1; x >= 0; x--) { int sx = x * 3; int dx = x * 4; - unsigned char b = pRow[sx]; + unsigned char r = pRow[sx]; unsigned char g = pRow[sx + 1]; - unsigned char r = pRow[sx + 2]; + unsigned char b = pRow[sx + 2]; unsigned char a = 0xff; pRow[dx ] = r; // r pRow[dx + 1] = g; // g - pRow[dx + 2] = b; // b; + pRow[dx + 2] = b; // b pRow[dx + 3] = a; } } - } else { // RGBA - for (y = 0; y < height; y++) { - unsigned char* pRow = pData + (height - (y + 1)) * stride; - bytesRead = read(fd, pRow, stride); - if (bytesRead != stride) { - result = -9; - goto exit; - } - size_t x; - for(x = 0; x < width; x++) { - size_t xx = x * 4; - unsigned char b = pRow[xx]; - unsigned char g = pRow[xx + 1]; - unsigned char r = pRow[xx + 2]; - unsigned char a = pRow[xx + 3]; - pRow[xx ] = r; - pRow[xx + 1] = g; - pRow[xx + 2] = b; - pRow[xx + 3] = a; - } + } else { + for (y = 0; y < height; ++y) { + unsigned char* pRow = pData + y * stride; + png_read_row(png_ptr, pRow, NULL); } } + *pSurface = (gr_surface) surface; exit: - if (fd >= 0) { - close(fd); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + if (fp != NULL) { + fclose(fp); } if (result < 0) { if (surface) { diff --git a/recovery.c b/recovery.c index 221ee2975..a0bae97ca 100644 --- a/recovery.c +++ b/recovery.c @@ -302,9 +302,11 @@ prompt_and_wait() #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); @@ -357,6 +359,13 @@ prompt_and_wait() if (!ui_text_visible()) return; break; + case ITEM_WIPE_CACHE: + ui_print("\n-- Wiping cache...\n"); + erase_root("CACHE:"); + ui_print("Cache wipe complete.\n"); + if (!ui_text_visible()) return; + break; + case ITEM_APPLY_SDCARD: ui_print("\n-- Install from sdcard...\n"); int status = install_package(SDCARD_PACKAGE_FILE); diff --git a/res/images/icon_error.bmp b/res/images/icon_error.bmp Binary files differdeleted file mode 100644 index 7eb2bbc77..000000000 --- a/res/images/icon_error.bmp +++ /dev/null diff --git a/res/images/icon_error.png b/res/images/icon_error.png Binary files differnew file mode 100644 index 000000000..7064c2e23 --- /dev/null +++ b/res/images/icon_error.png diff --git a/res/images/icon_firmware_error.bmp b/res/images/icon_firmware_error.bmp Binary files differdeleted file mode 100644 index 5b8649f17..000000000 --- a/res/images/icon_firmware_error.bmp +++ /dev/null diff --git a/res/images/icon_firmware_error.png b/res/images/icon_firmware_error.png Binary files differnew file mode 100644 index 000000000..0c32c9ede --- /dev/null +++ b/res/images/icon_firmware_error.png diff --git a/res/images/icon_firmware_install.bmp b/res/images/icon_firmware_install.bmp Binary files differdeleted file mode 100644 index b0f5f959b..000000000 --- a/res/images/icon_firmware_install.bmp +++ /dev/null diff --git a/res/images/icon_firmware_install.png b/res/images/icon_firmware_install.png Binary files differnew file mode 100644 index 000000000..ee2afac5d --- /dev/null +++ b/res/images/icon_firmware_install.png diff --git a/res/images/icon_installing.bmp b/res/images/icon_installing.bmp Binary files differdeleted file mode 100644 index fff99fd7e..000000000 --- a/res/images/icon_installing.bmp +++ /dev/null diff --git a/res/images/icon_installing.png b/res/images/icon_installing.png Binary files differnew file mode 100644 index 000000000..f24f2e33f --- /dev/null +++ b/res/images/icon_installing.png diff --git a/res/images/icon_unpacking.bmp b/res/images/icon_unpacking.bmp Binary files differdeleted file mode 100644 index ab6548c58..000000000 --- a/res/images/icon_unpacking.bmp +++ /dev/null diff --git a/res/images/indeterminate1.bmp b/res/images/indeterminate1.bmp Binary files differdeleted file mode 100644 index 716c92568..000000000 --- a/res/images/indeterminate1.bmp +++ /dev/null diff --git a/res/images/indeterminate1.png b/res/images/indeterminate1.png Binary files differnew file mode 100644 index 000000000..264bf27e5 --- /dev/null +++ b/res/images/indeterminate1.png diff --git a/res/images/indeterminate2.bmp b/res/images/indeterminate2.bmp Binary files differdeleted file mode 100644 index 223cd3c1e..000000000 --- a/res/images/indeterminate2.bmp +++ /dev/null diff --git a/res/images/indeterminate2.png b/res/images/indeterminate2.png Binary files differnew file mode 100644 index 000000000..c30c049ab --- /dev/null +++ b/res/images/indeterminate2.png diff --git a/res/images/indeterminate3.bmp b/res/images/indeterminate3.bmp Binary files differdeleted file mode 100644 index fd9086a1f..000000000 --- a/res/images/indeterminate3.bmp +++ /dev/null diff --git a/res/images/indeterminate3.png b/res/images/indeterminate3.png Binary files differnew file mode 100644 index 000000000..891a00095 --- /dev/null +++ b/res/images/indeterminate3.png diff --git a/res/images/indeterminate4.bmp b/res/images/indeterminate4.bmp Binary files differdeleted file mode 100644 index 87b264034..000000000 --- a/res/images/indeterminate4.bmp +++ /dev/null diff --git a/res/images/indeterminate4.png b/res/images/indeterminate4.png Binary files differnew file mode 100644 index 000000000..7a6415149 --- /dev/null +++ b/res/images/indeterminate4.png diff --git a/res/images/indeterminate5.bmp b/res/images/indeterminate5.bmp Binary files differdeleted file mode 100644 index e16efb04c..000000000 --- a/res/images/indeterminate5.bmp +++ /dev/null diff --git a/res/images/indeterminate5.png b/res/images/indeterminate5.png Binary files differnew file mode 100644 index 000000000..cd6ab20a7 --- /dev/null +++ b/res/images/indeterminate5.png diff --git a/res/images/indeterminate6.bmp b/res/images/indeterminate6.bmp Binary files differdeleted file mode 100644 index 085ad951a..000000000 --- a/res/images/indeterminate6.bmp +++ /dev/null diff --git a/res/images/indeterminate6.png b/res/images/indeterminate6.png Binary files differnew file mode 100644 index 000000000..ddd9e7384 --- /dev/null +++ b/res/images/indeterminate6.png diff --git a/res/images/progress_bar_empty.bmp b/res/images/progress_bar_empty.bmp Binary files differdeleted file mode 100644 index 8e512fd92..000000000 --- a/res/images/progress_bar_empty.bmp +++ /dev/null diff --git a/res/images/progress_bar_empty.png b/res/images/progress_bar_empty.png Binary files differnew file mode 100644 index 000000000..9013f04ac --- /dev/null +++ b/res/images/progress_bar_empty.png diff --git a/res/images/progress_bar_empty_left_round.bmp b/res/images/progress_bar_empty_left_round.bmp Binary files differdeleted file mode 100644 index c4e2f44fc..000000000 --- a/res/images/progress_bar_empty_left_round.bmp +++ /dev/null diff --git a/res/images/progress_bar_empty_left_round.png b/res/images/progress_bar_empty_left_round.png Binary files differnew file mode 100644 index 000000000..dae7d5d13 --- /dev/null +++ b/res/images/progress_bar_empty_left_round.png diff --git a/res/images/progress_bar_empty_right_round.bmp b/res/images/progress_bar_empty_right_round.bmp Binary files differdeleted file mode 100644 index 1906f6209..000000000 --- a/res/images/progress_bar_empty_right_round.bmp +++ /dev/null diff --git a/res/images/progress_bar_empty_right_round.png b/res/images/progress_bar_empty_right_round.png Binary files differnew file mode 100644 index 000000000..542708823 --- /dev/null +++ b/res/images/progress_bar_empty_right_round.png diff --git a/res/images/progress_bar_fill.bmp b/res/images/progress_bar_fill.bmp Binary files differdeleted file mode 100644 index 8d57d8117..000000000 --- a/res/images/progress_bar_fill.bmp +++ /dev/null diff --git a/res/images/progress_bar_fill.png b/res/images/progress_bar_fill.png Binary files differnew file mode 100644 index 000000000..37c04b4f4 --- /dev/null +++ b/res/images/progress_bar_fill.png diff --git a/res/images/progress_bar_left_round.bmp b/res/images/progress_bar_left_round.bmp Binary files differdeleted file mode 100644 index 6d2df8d6a..000000000 --- a/res/images/progress_bar_left_round.bmp +++ /dev/null diff --git a/res/images/progress_bar_left_round.png b/res/images/progress_bar_left_round.png Binary files differnew file mode 100644 index 000000000..e72af47d4 --- /dev/null +++ b/res/images/progress_bar_left_round.png diff --git a/res/images/progress_bar_right_round.bmp b/res/images/progress_bar_right_round.bmp Binary files differdeleted file mode 100644 index 68bb6fe37..000000000 --- a/res/images/progress_bar_right_round.bmp +++ /dev/null diff --git a/res/images/progress_bar_right_round.png b/res/images/progress_bar_right_round.png Binary files differnew file mode 100644 index 000000000..d04c980b9 --- /dev/null +++ b/res/images/progress_bar_right_round.png @@ -46,7 +46,6 @@ static gr_surface gProgressBarEmpty[NUM_SIDES]; static gr_surface gProgressBarFill[NUM_SIDES]; static const struct { gr_surface* surface; const char *name; } BITMAPS[] = { - { &gBackgroundIcon[BACKGROUND_ICON_UNPACKING], "icon_unpacking" }, { &gBackgroundIcon[BACKGROUND_ICON_INSTALLING], "icon_installing" }, { &gBackgroundIcon[BACKGROUND_ICON_ERROR], "icon_error" }, { &gBackgroundIcon[BACKGROUND_ICON_FIRMWARE_INSTALLING], |