Update TWRP to AOSP 7.1.2
Change-Id: I19c1546efb4182aac62c690e3cc05b04e3a9a32e
diff --git a/Android.mk b/Android.mk
index 5a37b62..3d3428f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -652,9 +652,9 @@
include $(commands_recovery_local_path)/minadbd/Android.mk \
$(commands_recovery_local_path)/minui/Android.mk
else
- TARGET_GLOBAL_CFLAGS += -DTW_USE_OLD_MINUI_H
- include $(commands_recovery_local_path)/minadbd.old/Android.mk \
- $(commands_recovery_local_path)/minui.old/Android.mk
+ TARGET_GLOBAL_CFLAGS += -DTW_USE_MINUI_21
+ include $(commands_recovery_local_path)/minadbd21/Android.mk \
+ $(commands_recovery_local_path)/minui21/Android.mk
endif
#includes for TWRP
diff --git a/error_code.h b/error_code.h
index fe38ba4..dfea0eb 100644
--- a/error_code.h
+++ b/error_code.h
@@ -44,4 +44,26 @@
kVendorFailure = 200
};
+enum UncryptErrorCode {
+ kUncryptNoError = -1,
+ kUncryptErrorPlaceholder = 50,
+ kUncryptTimeoutError = 100,
+ kUncryptFileRemoveError,
+ kUncryptFileOpenError,
+ kUncryptSocketOpenError,
+ kUncryptSocketWriteError,
+ kUncryptSocketListenError,
+ kUncryptSocketAcceptError,
+ kUncryptFstabReadError,
+ kUncryptFileStatError,
+ kUncryptBlockOpenError,
+ kUncryptIoctlError,
+ kUncryptReadError,
+ kUncryptWriteError,
+ kUncryptFileSyncError,
+ kUncryptFileCloseError,
+ kUncryptFileRenameError,
+ kUncryptPackageMissingError,
+};
+
#endif
diff --git a/install.cpp b/install.cpp
index 02c845c..e144d9b 100644
--- a/install.cpp
+++ b/install.cpp
@@ -30,6 +30,7 @@
#include <string>
#include <vector>
+#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
@@ -54,6 +55,7 @@
static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
#define PUBLIC_KEYS_FILE "/res/keys"
static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
+static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
// Default allocation of progress bar segments to operations
static const int VERIFICATION_PROGRESS_TIME = 60;
@@ -371,6 +373,14 @@
}
pid_t pid = fork();
+
+ if (pid == -1) {
+ close(pipefd[0]);
+ close(pipefd[1]);
+ LOGE("Failed to fork update binary: %s\n", strerror(errno));
+ return INSTALL_ERROR;
+ }
+
if (pid == 0) {
umask(022);
close(pipefd[0]);
@@ -511,13 +521,6 @@
modified_flash = true;
auto start = std::chrono::system_clock::now();
- FILE* install_log = fopen_path(install_file, "w");
- if (install_log) {
- fputs(path, install_log);
- fputc('\n', install_log);
- } else {
- LOGE("failed to open last_install: %s\n", strerror(errno));
- }
int result;
std::vector<std::string> log_buffer;
if (setup_install_mounts() != 0) {
@@ -526,21 +529,40 @@
} else {
result = really_install_package(path, wipe_cache, needs_mount, log_buffer, retry_count);
}
- if (install_log != nullptr) {
- fputc(result == INSTALL_SUCCESS ? '1' : '0', install_log);
- fputc('\n', install_log);
- std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
- int count = static_cast<int>(duration.count());
- // Report the time spent to apply OTA update in seconds.
- fprintf(install_log, "time_total: %d\n", count);
- fprintf(install_log, "retry: %d\n", retry_count);
- for (const auto& s : log_buffer) {
- fprintf(install_log, "%s\n", s.c_str());
+ // Measure the time spent to apply OTA update in seconds.
+ std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
+ int time_total = static_cast<int>(duration.count());
+
+ if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
+ LOGW("Can't mount %s\n", UNCRYPT_STATUS);
+ } else {
+ std::string uncrypt_status;
+ if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
+ LOGW("failed to read uncrypt status: %s\n", strerror(errno));
+ } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
+ LOGW("corrupted uncrypt_status: %s: %s\n", uncrypt_status.c_str(), strerror(errno));
+ } else {
+ log_buffer.push_back(android::base::Trim(uncrypt_status));
}
-
- fclose(install_log);
}
+
+ // The first two lines need to be the package name and install result.
+ std::vector<std::string> log_header = {
+ path,
+ result == INSTALL_SUCCESS ? "1" : "0",
+ "time_total: " + std::to_string(time_total),
+ "retry: " + std::to_string(retry_count),
+ };
+ std::string log_content = android::base::Join(log_header, "\n") + "\n" +
+ android::base::Join(log_buffer, "\n");
+ if (!android::base::WriteStringToFile(log_content, install_file)) {
+ LOGE("failed to write %s: %s\n", install_file, strerror(errno));
+ }
+
+ // Write a copy into last_log.
+ LOGI("%s\n", log_content.c_str());
+
return result;
}
diff --git a/minadbd.old/Android.mk b/minadbd21/Android.mk
similarity index 100%
rename from minadbd.old/Android.mk
rename to minadbd21/Android.mk
diff --git a/minadbd.old/README.txt b/minadbd21/README.txt
similarity index 100%
rename from minadbd.old/README.txt
rename to minadbd21/README.txt
diff --git a/minadbd.old/adb.c b/minadbd21/adb.c
similarity index 100%
rename from minadbd.old/adb.c
rename to minadbd21/adb.c
diff --git a/minadbd.old/adb.h b/minadbd21/adb.h
similarity index 100%
rename from minadbd.old/adb.h
rename to minadbd21/adb.h
diff --git a/minadbd.old/fdevent.c b/minadbd21/fdevent.c
similarity index 100%
rename from minadbd.old/fdevent.c
rename to minadbd21/fdevent.c
diff --git a/minadbd.old/fdevent.h b/minadbd21/fdevent.h
similarity index 100%
rename from minadbd.old/fdevent.h
rename to minadbd21/fdevent.h
diff --git a/minadbd.old/fuse_adb_provider.c b/minadbd21/fuse_adb_provider.c
similarity index 100%
rename from minadbd.old/fuse_adb_provider.c
rename to minadbd21/fuse_adb_provider.c
diff --git a/minadbd.old/fuse_adb_provider.h b/minadbd21/fuse_adb_provider.h
similarity index 100%
rename from minadbd.old/fuse_adb_provider.h
rename to minadbd21/fuse_adb_provider.h
diff --git a/minadbd.old/mutex_list.h b/minadbd21/mutex_list.h
similarity index 100%
rename from minadbd.old/mutex_list.h
rename to minadbd21/mutex_list.h
diff --git a/minadbd.old/services.c b/minadbd21/services.c
similarity index 100%
rename from minadbd.old/services.c
rename to minadbd21/services.c
diff --git a/minadbd.old/sockets.c b/minadbd21/sockets.c
similarity index 100%
rename from minadbd.old/sockets.c
rename to minadbd21/sockets.c
diff --git a/minadbd.old/sysdeps.h b/minadbd21/sysdeps.h
similarity index 100%
rename from minadbd.old/sysdeps.h
rename to minadbd21/sysdeps.h
diff --git a/minadbd.old/transport.c b/minadbd21/transport.c
similarity index 100%
rename from minadbd.old/transport.c
rename to minadbd21/transport.c
diff --git a/minadbd.old/transport.h b/minadbd21/transport.h
similarity index 100%
rename from minadbd.old/transport.h
rename to minadbd21/transport.h
diff --git a/minadbd.old/transport_usb.c b/minadbd21/transport_usb.c
similarity index 100%
rename from minadbd.old/transport_usb.c
rename to minadbd21/transport_usb.c
diff --git a/minadbd.old/usb_linux_client.c b/minadbd21/usb_linux_client.c
similarity index 100%
rename from minadbd.old/usb_linux_client.c
rename to minadbd21/usb_linux_client.c
diff --git a/minadbd.old/utils.c b/minadbd21/utils.c
similarity index 100%
rename from minadbd.old/utils.c
rename to minadbd21/utils.c
diff --git a/minadbd.old/utils.h b/minadbd21/utils.h
similarity index 100%
rename from minadbd.old/utils.h
rename to minadbd21/utils.h
diff --git a/minui/Android.mk b/minui/Android.mk
index 09409a4..34bf5f5 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -79,6 +79,9 @@
ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT)
endif
+ifneq ($(wildcard system/core/healthd/animation.h),)
+ LOCAL_CFLAGS += -DTW_USE_MINUI_CUSTOM_FONTS
+endif
include $(BUILD_STATIC_LIBRARY)
# Used by OEMs for factory test images.
diff --git a/minui/font_10x18.h b/minui/font_10x18.h
index 29d7053..30dfb9c 100644
--- a/minui/font_10x18.h
+++ b/minui/font_10x18.h
@@ -1,14 +1,14 @@
struct {
unsigned width;
unsigned height;
- unsigned cwidth;
- unsigned cheight;
+ unsigned char_width;
+ unsigned char_height;
unsigned char rundata[2973];
} font = {
.width = 960,
.height = 18,
- .cwidth = 10,
- .cheight = 18,
+ .char_width = 10,
+ .char_height = 18,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x55,0x82,0x06,0x82,0x02,0x82,0x10,0x82,
0x11,0x83,0x08,0x82,0x0a,0x82,0x04,0x82,0x46,0x82,0x08,0x82,0x07,0x84,0x06,
diff --git a/minui/graphics.cpp b/minui/graphics.cpp
index 244db3c..3d847b5 100644
--- a/minui/graphics.cpp
+++ b/minui/graphics.cpp
@@ -40,12 +40,6 @@
#include "minui.h"
#include "graphics.h"
-struct GRFont {
- GRSurface* texture;
- int cwidth;
- int cheight;
-};
-
static GRFont* gr_font = NULL;
static minui_backend* gr_backend = NULL;
@@ -68,17 +62,35 @@
{
return x < 0 || x >= gr_draw->width || y < 0 || y >= gr_draw->height;
}
-
+//#define TW_USE_MINUI_CUSTOM_FONTS 1
+#ifndef TW_USE_MINUI_CUSTOM_FONTS
int gr_measure(const char *s)
{
- return gr_font->cwidth * strlen(s);
+ return gr_font->char_width * strlen(s);
}
void gr_font_size(int *x, int *y)
{
- *x = gr_font->cwidth;
- *y = gr_font->cheight;
+ *x = gr_font->char_width;
+ *y = gr_font->char_height;
}
+#else // TW_USE_MINUI_CUSTOM_FONTS
+const GRFont* gr_sys_font()
+{
+ return gr_font;
+}
+
+int gr_measure(const GRFont* font, const char *s)
+{
+ return font->char_width * strlen(s);
+}
+
+void gr_font_size(const GRFont* font, int *x, int *y)
+{
+ *x = font->char_width;
+ *y = font->char_height;
+}
+#endif // TW_USE_MINUI_CUSTOM_FONTS
void blend_16bpp(unsigned char* px, unsigned r5, unsigned g5, unsigned b5, unsigned char a)
{
@@ -146,36 +158,67 @@
}
}
+#ifndef TW_USE_MINUI_CUSTOM_FONTS
void gr_text(int x, int y, const char *s, bool bold)
{
GRFont* font = gr_font;
if (!font->texture || gr_current_a == 0) return;
- bold = bold && (font->texture->height != font->cheight);
+ bold = bold && (font->texture->height != font->char_height);
x += overscan_offset_x;
y += overscan_offset_y;
unsigned char ch;
while ((ch = *s++)) {
- if (outside(x, y) || outside(x+font->cwidth-1, y+font->cheight-1)) break;
+ if (outside(x, y) || outside(x+font->char_width-1, y+font->char_height-1)) break;
if (ch < ' ' || ch > '~') {
ch = '?';
}
- unsigned char* src_p = font->texture->data + ((ch - ' ') * font->cwidth) +
- (bold ? font->cheight * font->texture->row_bytes : 0);
+ unsigned char* src_p = font->texture->data + ((ch - ' ') * font->char_width) +
+ (bold ? font->char_height * font->texture->row_bytes : 0);
unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
text_blend(src_p, font->texture->row_bytes,
dst_p, gr_draw->row_bytes,
- font->cwidth, font->cheight);
+ font->char_width, font->char_height);
- x += font->cwidth;
+ x += font->char_width;
}
}
+#else //TW_USE_MINUI_CUSTOM_FONTS
+void gr_text(const GRFont* font, int x, int y, const char *s, bool bold)
+{
+ if (!font->texture || gr_current_a == 0) return;
+
+ bold = bold && (font->texture->height != font->char_height);
+
+ x += overscan_offset_x;
+ y += overscan_offset_y;
+
+ unsigned char ch;
+ while ((ch = *s++)) {
+ if (outside(x, y) || outside(x+font->char_width-1, y+font->char_height-1)) break;
+
+ if (ch < ' ' || ch > '~') {
+ ch = '?';
+ }
+
+ unsigned char* src_p = font->texture->data + ((ch - ' ') * font->char_width) +
+ (bold ? font->char_height * font->texture->row_bytes : 0);
+ unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
+
+ text_blend(src_p, font->texture->row_bytes,
+ dst_p, gr_draw->row_bytes,
+ font->char_width, font->char_height);
+
+ x += font->char_width;
+ }
+}
+#endif //TW_USE_MINUI_CUSTOM_FONTS
void gr_texticon(int x, int y, GRSurface* icon) {
if (icon == NULL) return;
@@ -383,6 +426,7 @@
return surface->height;
}
+#ifndef TW_USE_MINUI_CUSTOM_FONTS
static void gr_init_font(void)
{
gr_font = reinterpret_cast<GRFont*>(calloc(sizeof(*gr_font), 1));
@@ -392,8 +436,8 @@
// The font image should be a 96x2 array of character images. The
// columns are the printable ASCII characters 0x20 - 0x7f. The
// top row is regular text; the bottom row is bold.
- gr_font->cwidth = gr_font->texture->width / 96;
- gr_font->cheight = gr_font->texture->height / 2;
+ gr_font->char_width = gr_font->texture->width / 96;
+ gr_font->char_height = gr_font->texture->height / 2;
} else {
printf("failed to read font: res=%d\n", res);
@@ -414,11 +458,73 @@
bits += (data & 0x7f);
}
- gr_font->cwidth = font.cwidth;
- gr_font->cheight = font.cheight;
+ gr_font->char_width = font.char_width;
+ gr_font->char_height = font.char_height;
}
}
+void gr_set_font(__attribute__ ((unused))const char* name) {
+ //this cm function is made to change font. Don't care, just init the font:
+ gr_init_font();
+ return;
+}
+#else
+int gr_init_font(const char* name, GRFont** dest) {
+ GRFont* font = reinterpret_cast<GRFont*>(calloc(1, sizeof(*gr_font)));
+ if (font == nullptr) {
+ return -1;
+ }
+
+ int res = res_create_alpha_surface(name, &(font->texture));
+ if (res < 0) {
+ free(font);
+ return res;
+ }
+
+ // The font image should be a 96x2 array of character images. The
+ // columns are the printable ASCII characters 0x20 - 0x7f. The
+ // top row is regular text; the bottom row is bold.
+ font->char_width = font->texture->width / 96;
+ font->char_height = font->texture->height / 2;
+
+ *dest = font;
+
+ return 0;
+}
+
+static void gr_init_font(void)
+{
+ int res = gr_init_font("font", &gr_font);
+ if (res == 0) {
+ return;
+ }
+
+ printf("failed to read font: res=%d\n", res);
+
+
+ // fall back to the compiled-in font.
+ gr_font = reinterpret_cast<GRFont*>(calloc(1, sizeof(*gr_font)));
+ gr_font->texture = reinterpret_cast<GRSurface*>(malloc(sizeof(*gr_font->texture)));
+ gr_font->texture->width = font.width;
+ gr_font->texture->height = font.height;
+ gr_font->texture->row_bytes = font.width;
+ gr_font->texture->pixel_bytes = 1;
+
+ unsigned char* bits = reinterpret_cast<unsigned char*>(malloc(font.width * font.height));
+ gr_font->texture->data = reinterpret_cast<unsigned char*>(bits);
+
+ unsigned char data;
+ unsigned char* in = font.rundata;
+ while((data = *in++)) {
+ memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
+ bits += (data & 0x7f);
+ }
+
+ gr_font->char_width = font.char_width;
+ gr_font->char_height = font.char_height;
+}
+#endif
+
#if 0
// Exercises many of the gr_*() functions; useful for testing.
static void gr_test() {
@@ -547,9 +653,3 @@
{
gr_backend->blank(gr_backend, blank);
}
-
-void gr_set_font(__attribute__ ((unused))const char* name) {
- //this cm function is made to change font. Don't care, just init the font:
- gr_init_font();
- return;
-}
diff --git a/minui/minui.h b/minui/minui.h
index dee4641..abef036 100644
--- a/minui/minui.h
+++ b/minui/minui.h
@@ -17,7 +17,7 @@
#ifndef _MINUI_H_
#define _MINUI_H_
-#ifndef TW_USE_OLD_MINUI_H
+#ifndef TW_USE_MINUI_21
#include <sys/types.h>
@@ -35,6 +35,12 @@
unsigned char* data;
};
+struct GRFont {
+ GRSurface* texture;
+ int char_width;
+ int char_height;
+};
+
int gr_init();
void gr_exit();
@@ -47,11 +53,21 @@
void gr_clear(); // clear entire surface to current color
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
void gr_fill(int x1, int y1, int x2, int y2);
-void gr_text(int x, int y, const char *s, bool bold);
+
void gr_texticon(int x, int y, GRSurface* icon);
+#ifndef TW_USE_MINUI_CUSTOM_FONTS
+void gr_text(int x, int y, const char *s, bool bold);
int gr_measure(const char *s);
void gr_font_size(int *x, int *y);
void gr_set_font(__attribute__ ((unused))const char* name);
+#else
+
+const GRFont* gr_sys_font();
+int gr_init_font(const char* name, GRFont** dest);
+void gr_text(const GRFont* font, int x, int y, const char *s, bool bold);
+int gr_measure(const GRFont* font, const char *s);
+void gr_font_size(const GRFont* font, int *x, int *y);
+#endif
void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy);
unsigned int gr_get_width(GRSurface* surface);
@@ -127,9 +143,9 @@
// functions.
void res_free_surface(GRSurface* surface);
-#else //ifndef TW_USE_OLD_MINUI_H
+#else //ifndef TW_USE_MINUI_21
-// This the old minui.old/minui.h for compatibility with building TWRP
+// This the old minui21/minui.h for compatibility with building TWRP
// in pre 6.0 trees.
#include <stdbool.h>
@@ -217,5 +233,5 @@
}
#endif
-#endif // ifndef TW_USE_OLD_MINUI_H
+#endif // ifndef TW_USE_MINUI_21
#endif // ifndef _MINUI_H_
diff --git a/minui/roboto_10x18.h b/minui/roboto_10x18.h
index 0d118ba..2d1535b 100644
--- a/minui/roboto_10x18.h
+++ b/minui/roboto_10x18.h
@@ -1,14 +1,14 @@
struct {
unsigned width;
unsigned height;
- unsigned cwidth;
- unsigned cheight;
+ unsigned char_width;
+ unsigned char_height;
unsigned char rundata[2718];
} font = {
.width = 960,
.height = 18,
- .cwidth = 10,
- .cheight = 18,
+ .char_width = 10,
+ .char_height = 18,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
0x3b,0x81,0x29,0x81,0x06,0x81,0x3f,0x81,0x7f,0x7f,0x7f,0x37,0x83,0x05,0x81,
diff --git a/minui/roboto_15x24.h b/minui/roboto_15x24.h
index 7857c59..aea1cbf 100644
--- a/minui/roboto_15x24.h
+++ b/minui/roboto_15x24.h
@@ -1,14 +1,14 @@
struct {
unsigned width;
unsigned height;
- unsigned cwidth;
- unsigned cheight;
+ unsigned char_width;
+ unsigned char_height;
unsigned char rundata[3979];
} font = {
.width = 1440,
.height = 24,
- .cwidth = 15,
- .cheight = 24,
+ .char_width = 15,
+ .char_height = 24,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x6e,0x81,0x3e,0x81,
0x07,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x76,0x84,0x17,0x84,0x7f,0x7f,0x7f,0x7f,
diff --git a/minui/roboto_23x41.h b/minui/roboto_23x41.h
index 6af2abc..793f784 100644
--- a/minui/roboto_23x41.h
+++ b/minui/roboto_23x41.h
@@ -1,14 +1,14 @@
struct {
unsigned width;
unsigned height;
- unsigned cwidth;
- unsigned cheight;
+ unsigned char_width;
+ unsigned char_height;
unsigned char rundata[6679];
} font = {
.width = 2208,
.height = 41,
- .cwidth = 23,
- .cheight = 41,
+ .char_width = 23,
+ .char_height = 41,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
0x7f,0x7f,0x7f,0x17,0x83,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
diff --git a/minui.old/Android.mk b/minui21/Android.mk
similarity index 100%
rename from minui.old/Android.mk
rename to minui21/Android.mk
diff --git a/minui.old/events.c b/minui21/events.c
similarity index 100%
rename from minui.old/events.c
rename to minui21/events.c
diff --git a/minui.old/font_10x18.h b/minui21/font_10x18.h
similarity index 100%
rename from minui.old/font_10x18.h
rename to minui21/font_10x18.h
diff --git a/minui.old/font_7x16.h b/minui21/font_7x16.h
similarity index 100%
rename from minui.old/font_7x16.h
rename to minui21/font_7x16.h
diff --git a/minui.old/graphics.c b/minui21/graphics.c
similarity index 100%
rename from minui.old/graphics.c
rename to minui21/graphics.c
diff --git a/minui.old/graphics_overlay.c b/minui21/graphics_overlay.c
similarity index 100%
rename from minui.old/graphics_overlay.c
rename to minui21/graphics_overlay.c
diff --git a/minui.old/include/linux/msm_ion.h b/minui21/include/linux/msm_ion.h
similarity index 100%
rename from minui.old/include/linux/msm_ion.h
rename to minui21/include/linux/msm_ion.h
diff --git a/minui.old/include/linux/msm_mdp.h b/minui21/include/linux/msm_mdp.h
similarity index 100%
rename from minui.old/include/linux/msm_mdp.h
rename to minui21/include/linux/msm_mdp.h
diff --git a/minui.old/minui.h b/minui21/minui.h
similarity index 100%
rename from minui.old/minui.h
rename to minui21/minui.h
diff --git a/minui.old/mkfont.c b/minui21/mkfont.c
similarity index 100%
rename from minui.old/mkfont.c
rename to minui21/mkfont.c
diff --git a/minui.old/resources.c b/minui21/resources.c
similarity index 100%
rename from minui.old/resources.c
rename to minui21/resources.c
diff --git a/minui.old/roboto_10x18.h b/minui21/roboto_10x18.h
similarity index 100%
rename from minui.old/roboto_10x18.h
rename to minui21/roboto_10x18.h
diff --git a/minui.old/roboto_15x24.h b/minui21/roboto_15x24.h
similarity index 100%
rename from minui.old/roboto_15x24.h
rename to minui21/roboto_15x24.h
diff --git a/minui.old/roboto_23x41.h b/minui21/roboto_23x41.h
similarity index 100%
rename from minui.old/roboto_23x41.h
rename to minui21/roboto_23x41.h
diff --git a/recovery.cpp b/recovery.cpp
index ccb2d22..0f0b978 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -1429,15 +1429,18 @@
}
static void log_failure_code(ErrorCode code, const char *update_package) {
- FILE* install_log = fopen_path(TEMPORARY_INSTALL_FILE, "w");
- if (install_log != nullptr) {
- fprintf(install_log, "%s\n", update_package);
- fprintf(install_log, "0\n");
- fprintf(install_log, "error: %d\n", code);
- fclose(install_log);
- } else {
- LOGE("failed to open last_install: %s\n", strerror(errno));
+ std::vector<std::string> log_buffer = {
+ update_package,
+ "0", // install result
+ "error: " + std::to_string(code),
+ };
+ std::string log_content = android::base::Join(log_buffer, "\n");
+ if (!android::base::WriteStringToFile(log_content, TEMPORARY_INSTALL_FILE)) {
+ LOGE("failed to write %s: %s\n", TEMPORARY_INSTALL_FILE, strerror(errno));
}
+
+ // Also write the info into last_log.
+ LOGI("%s\n", log_content.c_str());
}
static ssize_t logbasename(
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 2a0769e..95b97d1 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -53,8 +53,6 @@
ScreenRecoveryUI::ScreenRecoveryUI() :
currentIcon(NONE),
locale(nullptr),
- intro_done(false),
- current_frame(0),
progressBarType(EMPTY),
progressScopeStart(0),
progressScopeSize(0),
@@ -75,6 +73,8 @@
file_viewer_text_(nullptr),
intro_frames(0),
loop_frames(0),
+ current_frame(0),
+ intro_done(false),
animation_fps(30), // TODO: there's currently no way to infer this.
stage(-1),
max_stage(-1),
@@ -259,7 +259,7 @@
}
void ScreenRecoveryUI::DrawTextLine(int x, int* y, const char* line, bool bold) {
- gr_text(x, *y, line, bold);
+ gr_text(gr_sys_font(), x, *y, line, bold);
*y += char_height_ + 4;
}
@@ -315,10 +315,10 @@
gr_fill(0, y - 2, gr_fb_width(), y + char_height_ + 2);
// Bold white text for the selected item.
SetColor(MENU_SEL_FG);
- gr_text(4, y, menu_[i], true);
+ gr_text(gr_sys_font(), 4, y, menu_[i], true);
SetColor(MENU);
} else {
- gr_text(4, y, menu_[i], false);
+ gr_text(gr_sys_font(), 4, y, menu_[i], false);
}
y += char_height_ + 4;
}
@@ -334,7 +334,7 @@
for (int ty = gr_fb_height() - char_height_;
ty >= y && count < text_rows_;
ty -= char_height_, ++count) {
- gr_text(0, ty, text_[row], false);
+ gr_text(gr_sys_font(), 0, ty, text_[row], false);
--row;
if (row < 0) row = text_rows_ - 1;
}
@@ -447,9 +447,18 @@
Redraw();
}
-void ScreenRecoveryUI::Init() {
+void ScreenRecoveryUI::InitTextParams() {
gr_init();
+ gr_font_size(gr_sys_font(), &char_width_, &char_height_);
+ text_rows_ = gr_fb_height() / char_height_;
+ text_cols_ = gr_fb_width() / char_width_;
+}
+
+void ScreenRecoveryUI::Init() {
+ RecoveryUI::Init();
+ InitTextParams();
+
density_ = static_cast<float>(property_get_int32("ro.sf.lcd_density", 160)) / 160.f;
// Are we portrait or landscape?
@@ -457,10 +466,6 @@
// Are we the large variant of our base layout?
if (gr_fb_height() > PixelsFromDp(800)) ++layout_;
- gr_font_size(&char_width_, &char_height_);
- text_rows_ = gr_fb_height() / char_height_;
- text_cols_ = gr_fb_width() / char_width_;
-
text_ = Alloc2d(text_rows_, text_cols_ + 1);
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
menu_ = Alloc2d(text_rows_, text_cols_ + 1);
@@ -487,37 +492,42 @@
LoadAnimation();
pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this);
-
- RecoveryUI::Init();
}
void ScreenRecoveryUI::LoadAnimation() {
- // How many frames of intro and loop do we have?
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/res/images"), closedir);
dirent* de;
+ std::vector<std::string> intro_frame_names;
+ std::vector<std::string> loop_frame_names;
+
while ((de = readdir(dir.get())) != nullptr) {
- int value;
- if (sscanf(de->d_name, "intro%d", &value) == 1 && intro_frames < (value + 1)) {
- intro_frames = value + 1;
- } else if (sscanf(de->d_name, "loop%d", &value) == 1 && loop_frames < (value + 1)) {
- loop_frames = value + 1;
+ int value, num_chars;
+ if (sscanf(de->d_name, "intro%d%n.png", &value, &num_chars) == 1) {
+ intro_frame_names.emplace_back(de->d_name, num_chars);
+ } else if (sscanf(de->d_name, "loop%d%n.png", &value, &num_chars) == 1) {
+ loop_frame_names.emplace_back(de->d_name, num_chars);
}
}
+ intro_frames = intro_frame_names.size();
+ loop_frames = loop_frame_names.size();
+
// It's okay to not have an intro.
if (intro_frames == 0) intro_done = true;
// But you must have an animation.
if (loop_frames == 0) abort();
+ std::sort(intro_frame_names.begin(), intro_frame_names.end());
+ std::sort(loop_frame_names.begin(), loop_frame_names.end());
+
introFrames = new GRSurface*[intro_frames];
- for (int i = 0; i < intro_frames; ++i) {
- // TODO: remember the names above, so we don't have to hard-code the number of 0s.
- LoadBitmap(android::base::StringPrintf("intro%05d", i).c_str(), &introFrames[i]);
+ for (size_t i = 0; i < intro_frames; i++) {
+ LoadBitmap(intro_frame_names.at(i).c_str(), &introFrames[i]);
}
loopFrames = new GRSurface*[loop_frames];
- for (int i = 0; i < loop_frames; ++i) {
- LoadBitmap(android::base::StringPrintf("loop%05d", i).c_str(), &loopFrames[i]);
+ for (size_t i = 0; i < loop_frames; i++) {
+ LoadBitmap(loop_frame_names.at(i).c_str(), &loopFrames[i]);
}
}
diff --git a/screen_ui.h b/screen_ui.h
index 8987757..de7b644 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -37,16 +37,16 @@
void SetSystemUpdateText(bool security_update);
// progress indicator
- void SetProgressType(ProgressType type);
- void ShowProgress(float portion, float seconds);
- void SetProgress(float fraction);
+ void SetProgressType(ProgressType type) override;
+ void ShowProgress(float portion, float seconds) override;
+ void SetProgress(float fraction) override;
- void SetStage(int current, int max);
+ void SetStage(int current, int max) override;
// text log
- void ShowText(bool visible);
- bool IsTextVisible();
- bool WasTextEverVisible();
+ void ShowText(bool visible) override;
+ bool IsTextVisible() override;
+ bool WasTextEverVisible() override;
// printing messages
void Print(const char* fmt, ...) __printflike(2, 3);
@@ -72,8 +72,6 @@
Icon currentIcon;
const char* locale;
- bool intro_done;
- int current_frame;
// The scale factor from dp to pixels. 1.0 for mdpi, 4.0 for xxxhdpi.
float density_;
@@ -123,8 +121,11 @@
pthread_t progress_thread_;
// Number of intro frames and loop frames in the animation.
- int intro_frames;
- int loop_frames;
+ size_t intro_frames;
+ size_t loop_frames;
+
+ size_t current_frame;
+ bool intro_done;
// Number of frames per sec (default: 30) for both parts of the animation.
int animation_fps;
@@ -136,11 +137,13 @@
pthread_mutex_t updateMutex;
bool rtl_locale;
- void draw_background_locked();
- void draw_foreground_locked();
- void draw_screen_locked();
- void update_screen_locked();
- void update_progress_locked();
+ virtual void InitTextParams();
+
+ virtual void draw_background_locked();
+ virtual void draw_foreground_locked();
+ virtual void draw_screen_locked();
+ virtual void update_screen_locked();
+ virtual void update_progress_locked();
GRSurface* GetCurrentFrame();
GRSurface* GetCurrentText();
@@ -148,8 +151,8 @@
static void* ProgressThreadStartRoutine(void* data);
void ProgressThreadLoop();
- void ShowFile(FILE*);
- void PrintV(const char*, bool, va_list);
+ virtual void ShowFile(FILE*);
+ virtual void PrintV(const char*, bool, va_list);
void PutChar(char);
void ClearText();
@@ -158,9 +161,9 @@
void LoadLocalizedBitmap(const char* filename, GRSurface** surface);
int PixelsFromDp(int dp);
- int GetAnimationBaseline();
- int GetProgressBaseline();
- int GetTextBaseline();
+ virtual int GetAnimationBaseline();
+ virtual int GetProgressBaseline();
+ virtual int GetTextBaseline();
void DrawHorizontalRule(int* y);
void DrawTextLine(int x, int* y, const char* line, bool bold);
diff --git a/twrp.cpp b/twrp.cpp
index 977fea2..6fd8f24 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -49,7 +49,7 @@
#include "adb.h"
#else
extern "C" {
-#include "minadbd.old/adb.h"
+#include "minadbd21/adb.h"
}
#endif
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 5e804bc..280568d 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -118,6 +118,7 @@
#define LOG_TAG "uncrypt"
#include <log/log.h>
+#include "error_code.h"
#include "unique_fd.h"
#define WINDOW_SIZE 5
@@ -134,6 +135,7 @@
// devices, on which /cache partitions always exist.
static const std::string CACHE_BLOCK_MAP = "/cache/recovery/block.map";
static const std::string UNCRYPT_PATH_FILE = "/cache/recovery/uncrypt_file";
+static const std::string UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
static const std::string UNCRYPT_SOCKET = "uncrypt";
static struct fstab* fstab = nullptr;
@@ -234,25 +236,25 @@
std::string err;
if (!android::base::RemoveFileIfExists(map_file, &err)) {
ALOGE("failed to remove the existing map file %s: %s", map_file, err.c_str());
- return -1;
+ return kUncryptFileRemoveError;
}
std::string tmp_map_file = std::string(map_file) + ".tmp";
unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
if (!mapfd) {
ALOGE("failed to open %s: %s\n", tmp_map_file.c_str(), strerror(errno));
- return -1;
+ return kUncryptFileOpenError;
}
// Make sure we can write to the socket.
if (!write_status_to_socket(0, socket)) {
ALOGE("failed to write to socket %d\n", socket);
- return -1;
+ return kUncryptSocketWriteError;
}
struct stat sb;
if (stat(path, &sb) != 0) {
ALOGE("failed to stat %s", path);
- return -1;
+ return kUncryptFileStatError;
}
ALOGI(" block size: %ld bytes", static_cast<long>(sb.st_blksize));
@@ -266,7 +268,7 @@
blk_dev, sb.st_size, static_cast<long>(sb.st_blksize));
if (!android::base::WriteStringToFd(s, mapfd.get())) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
- return -1;
+ return kUncryptWriteError;
}
std::vector<std::vector<unsigned char>> buffers;
@@ -279,7 +281,7 @@
unique_fd fd(open(path, O_RDONLY));
if (!fd) {
ALOGE("failed to open %s for reading: %s", path, strerror(errno));
- return -1;
+ return kUncryptFileOpenError;
}
unique_fd wfd(-1);
@@ -287,7 +289,7 @@
wfd = open(blk_dev, O_WRONLY);
if (!wfd) {
ALOGE("failed to open fd for writing: %s", strerror(errno));
- return -1;
+ return kUncryptBlockOpenError;
}
}
@@ -306,13 +308,13 @@
int block = head_block;
if (ioctl(fd.get(), FIBMAP, &block) != 0) {
ALOGE("failed to find block %d", head_block);
- return -1;
+ return kUncryptIoctlError;
}
add_block_to_ranges(ranges, block);
if (encrypted) {
if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
static_cast<off64_t>(sb.st_blksize) * block) != 0) {
- return -1;
+ return kUncryptWriteError;
}
}
head = (head + 1) % WINDOW_SIZE;
@@ -325,7 +327,7 @@
std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos));
if (!android::base::ReadFully(fd.get(), buffers[tail].data(), to_read)) {
ALOGE("failed to read: %s", strerror(errno));
- return -1;
+ return kUncryptReadError;
}
pos += to_read;
} else {
@@ -342,13 +344,13 @@
int block = head_block;
if (ioctl(fd.get(), FIBMAP, &block) != 0) {
ALOGE("failed to find block %d", head_block);
- return -1;
+ return kUncryptIoctlError;
}
add_block_to_ranges(ranges, block);
if (encrypted) {
if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
static_cast<off64_t>(sb.st_blksize) * block) != 0) {
- return -1;
+ return kUncryptWriteError;
}
}
head = (head + 1) % WINDOW_SIZE;
@@ -358,41 +360,41 @@
if (!android::base::WriteStringToFd(
android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd.get())) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
- return -1;
+ return kUncryptWriteError;
}
for (size_t i = 0; i < ranges.size(); i += 2) {
if (!android::base::WriteStringToFd(
android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd.get())) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
- return -1;
+ return kUncryptWriteError;
}
}
if (fsync(mapfd.get()) == -1) {
ALOGE("failed to fsync \"%s\": %s", tmp_map_file.c_str(), strerror(errno));
- return -1;
+ return kUncryptFileSyncError;
}
if (close(mapfd.get()) == -1) {
ALOGE("failed to close %s: %s", tmp_map_file.c_str(), strerror(errno));
- return -1;
+ return kUncryptFileCloseError;
}
mapfd = -1;
if (encrypted) {
if (fsync(wfd.get()) == -1) {
ALOGE("failed to fsync \"%s\": %s", blk_dev, strerror(errno));
- return -1;
+ return kUncryptFileSyncError;
}
if (close(wfd.get()) == -1) {
ALOGE("failed to close %s: %s", blk_dev, strerror(errno));
- return -1;
+ return kUncryptFileCloseError;
}
wfd = -1;
}
if (rename(tmp_map_file.c_str(), map_file) == -1) {
ALOGE("failed to rename %s to %s: %s", tmp_map_file.c_str(), map_file, strerror(errno));
- return -1;
+ return kUncryptFileRenameError;
}
// Sync dir to make rename() result written to disk.
std::string file_name = map_file;
@@ -400,15 +402,15 @@
unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
if (!dfd) {
ALOGE("failed to open dir %s: %s", dir_name.c_str(), strerror(errno));
- return -1;
+ return kUncryptFileOpenError;
}
if (fsync(dfd.get()) == -1) {
ALOGE("failed to fsync %s: %s", dir_name.c_str(), strerror(errno));
- return -1;
+ return kUncryptFileSyncError;
}
if (close(dfd.get()) == -1) {
ALOGE("failed to close %s: %s", dir_name.c_str(), strerror(errno));
- return -1;
+ return kUncryptFileCloseError;
}
dfd = -1;
return 0;
@@ -448,30 +450,58 @@
// and /sdcard we leave the file alone.
if (strncmp(path, "/data/", 6) == 0) {
ALOGI("writing block map %s", map_file);
- if (produce_block_map(path, map_file, blk_dev, encrypted, socket) != 0) {
- return 1;
- }
+ return produce_block_map(path, map_file, blk_dev, encrypted, socket);
}
return 0;
}
+static void log_uncrypt_error_code(UncryptErrorCode error_code) {
+ if (!android::base::WriteStringToFile(android::base::StringPrintf(
+ "uncrypt_error: %d\n", error_code), UNCRYPT_STATUS)) {
+ ALOGW("failed to write to %s: %s", UNCRYPT_STATUS.c_str(), strerror(errno));
+ }
+}
+
static bool uncrypt_wrapper(const char* input_path, const char* map_file, const int socket) {
+ // Initialize the uncrypt error to kUncryptErrorPlaceholder.
+ log_uncrypt_error_code(kUncryptErrorPlaceholder);
+
std::string package;
if (input_path == nullptr) {
if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) {
write_status_to_socket(-1, socket);
+ // Overwrite the error message.
+ log_uncrypt_error_code(kUncryptPackageMissingError);
return false;
}
input_path = package.c_str();
}
CHECK(map_file != nullptr);
+
+ auto start = std::chrono::system_clock::now();
int status = uncrypt(input_path, map_file, socket);
+ std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
+ int count = static_cast<int>(duration.count());
+
+ std::string uncrypt_message = android::base::StringPrintf("uncrypt_time: %d\n", count);
if (status != 0) {
+ // Log the time cost and error code if uncrypt fails.
+ uncrypt_message += android::base::StringPrintf("uncrypt_error: %d\n", status);
+ if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
+ ALOGW("failed to write to %s: %s", UNCRYPT_STATUS.c_str(), strerror(errno));
+ }
+
write_status_to_socket(-1, socket);
return false;
}
+
+ if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
+ ALOGW("failed to write to %s: %s", UNCRYPT_STATUS.c_str(), strerror(errno));
+ }
+
write_status_to_socket(100, socket);
+
return true;
}
@@ -561,6 +591,7 @@
}
if ((fstab = read_fstab()) == nullptr) {
+ log_uncrypt_error_code(kUncryptFstabReadError);
return 1;
}
@@ -569,18 +600,21 @@
unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
if (!service_socket) {
ALOGE("failed to open socket \"%s\": %s", UNCRYPT_SOCKET.c_str(), strerror(errno));
+ log_uncrypt_error_code(kUncryptSocketOpenError);
return 1;
}
fcntl(service_socket.get(), F_SETFD, FD_CLOEXEC);
if (listen(service_socket.get(), 1) == -1) {
ALOGE("failed to listen on socket %d: %s", service_socket.get(), strerror(errno));
+ log_uncrypt_error_code(kUncryptSocketListenError);
return 1;
}
unique_fd socket_fd(accept4(service_socket.get(), nullptr, nullptr, SOCK_CLOEXEC));
if (!socket_fd) {
ALOGE("failed to accept on socket %d: %s", service_socket.get(), strerror(errno));
+ log_uncrypt_error_code(kUncryptSocketAcceptError);
return 1;
}
diff --git a/updater/install.cpp b/updater/install.cpp
index d4ae64e..1c79640 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -35,8 +35,10 @@
#include <inttypes.h>
#include <memory>
+#include <string>
#include <vector>
+#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
@@ -970,7 +972,6 @@
return StringValue(strdup(value));
}
-
// file_getprop(file, key)
//
// interprets 'file' as a getprop-style file (key=value pairs, one
@@ -1432,6 +1433,31 @@
return v;
}
+// write_value(value, filename)
+// Writes 'value' to 'filename'.
+// Example: write_value("960000", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq")
+Value* WriteValueFn(const char* name, State* state, int argc, Expr* argv[]) {
+ if (argc != 2) {
+ return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc);
+ }
+
+ char* value;
+ char* filename;
+ if (ReadArgs(state, argv, 2, &value, &filename) < 0) {
+ return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)",
+ name);
+ }
+
+ bool ret = android::base::WriteStringToFile(value, filename);
+ if (!ret) {
+ printf("%s: Failed to write to \"%s\": %s\n", name, filename, strerror(errno));
+ }
+
+ free(value);
+ free(filename);
+ return StringValue(strdup(ret ? "t" : ""));
+}
+
// Immediately reboot the device. Recovery is not finished normally,
// so if you reboot into recovery it will re-start applying the
// current package (because nothing has cleared the copy of the
@@ -1638,6 +1664,7 @@
RegisterFunction("read_file", ReadFileFn);
RegisterFunction("sha1_check", Sha1CheckFn);
RegisterFunction("rename", RenameFn);
+ RegisterFunction("write_value", WriteValueFn);
RegisterFunction("wipe_cache", WipeCacheFn);
diff --git a/verifier.cpp b/verifier.cpp
index c4cd612..229cc9d 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -154,6 +154,12 @@
LOGI("comment is %zu bytes; signature %zu bytes from end\n",
comment_size, signature_start);
+ if (signature_start > comment_size) {
+ LOGE("signature start: %zu is larger than comment size: %zu\n", signature_start,
+ comment_size);
+ return VERIFY_FAILURE;
+ }
+
if (signature_start <= FOOTER_SIZE) {
LOGE("Signature start is in the footer");
return VERIFY_FAILURE;
diff --git a/wear_ui.cpp b/wear_ui.cpp
index b437fd0..660a078 100644
--- a/wear_ui.cpp
+++ b/wear_ui.cpp
@@ -47,32 +47,13 @@
}
WearRecoveryUI::WearRecoveryUI() :
- progress_bar_height(3),
- progress_bar_width(200),
progress_bar_y(259),
outer_height(0),
outer_width(0),
- menu_unusable_rows(0),
- intro_frames(22),
- loop_frames(60),
- animation_fps(30),
- currentIcon(NONE),
- intro_done(false),
- current_frame(0),
- progressBarType(EMPTY),
- progressScopeStart(0),
- progressScopeSize(0),
- progress(0),
- text_cols(0),
- text_rows(0),
- text_col(0),
- text_row(0),
- text_top(0),
- show_text(false),
- show_text_ever(false),
- show_menu(false),
- menu_items(0),
- menu_sel(0) {
+ menu_unusable_rows(0) {
+ intro_frames = 22;
+ loop_frames = 60;
+ animation_fps = 30;
for (size_t i = 0; i < 5; i++)
backgroundIcon[i] = NULL;
@@ -80,16 +61,22 @@
self = this;
}
+int WearRecoveryUI::GetProgressBaseline() {
+ return progress_bar_y;
+}
+
// Draw background frame on the screen. Does not flip pages.
// Should only be called with updateMutex locked.
-void WearRecoveryUI::draw_background_locked(Icon icon)
+// TODO merge drawing routines with screen_ui
+void WearRecoveryUI::draw_background_locked()
{
+ pagesIdentical = false;
gr_color(0, 0, 0, 255);
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
- if (icon) {
+ if (currentIcon != NONE) {
GRSurface* surface;
- if (icon == INSTALLING_UPDATE || icon == ERASING) {
+ if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
if (!intro_done) {
surface = introFrames[current_frame];
} else {
@@ -97,7 +84,7 @@
}
}
else {
- surface = backgroundIcon[icon];
+ surface = backgroundIcon[currentIcon];
}
int width = gr_get_width(surface);
@@ -110,36 +97,6 @@
}
}
-// Draw the progress bar (if any) on the screen. Does not flip pages.
-// Should only be called with updateMutex locked.
-void WearRecoveryUI::draw_progress_locked()
-{
- if (currentIcon == ERROR) return;
- if (progressBarType != DETERMINATE) return;
-
- int width = progress_bar_width;
- int height = progress_bar_height;
- int dx = (gr_fb_width() - width)/2;
- int dy = progress_bar_y;
-
- float p = progressScopeStart + progress * progressScopeSize;
- int pos = (int) (p * width);
-
- gr_color(0x43, 0x43, 0x43, 0xff);
- gr_fill(dx, dy, dx + width, dy + height);
-
- if (pos > 0) {
- gr_color(0x02, 0xa8, 0xf3, 255);
- if (rtl_locale) {
- // Fill the progress bar from right to left.
- gr_fill(dx + width - pos, dy, dx + width, dy + height);
- } else {
- // Fill the progress bar from left to right.
- gr_fill(dx, dy, dx + pos, dy + height);
- }
- }
-}
-
static const char* HEADERS[] = {
"Swipe up/down to move.",
"Swipe left/right to select.",
@@ -147,13 +104,15 @@
NULL
};
+// TODO merge drawing routines with screen_ui
void WearRecoveryUI::draw_screen_locked()
{
- draw_background_locked(currentIcon);
- draw_progress_locked();
char cur_selection_str[50];
- if (show_text) {
+ draw_background_locked();
+ if (!show_text) {
+ draw_foreground_locked();
+ } else {
SetColor(TEXT_FILL);
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
@@ -177,7 +136,7 @@
// items don't fit on the screen.
if (menu_items > menu_end - menu_start) {
sprintf(cur_selection_str, "Current item: %d/%d", menu_sel + 1, menu_items);
- gr_text(x+4, y, cur_selection_str, 1);
+ gr_text(gr_sys_font(), x+4, y, cur_selection_str, 1);
y += char_height_+4;
}
@@ -192,10 +151,12 @@
gr_fill(x, y-2, gr_fb_width()-x, y+char_height_+2);
// white text of selected item
SetColor(MENU_SEL_FG);
- if (menu[i][0]) gr_text(x+4, y, menu[i], 1);
+ if (menu_[i][0]) {
+ gr_text(gr_sys_font(), x + 4, y, menu_[i], 1);
+ }
SetColor(MENU);
- } else {
- if (menu[i][0]) gr_text(x+4, y, menu[i], 0);
+ } else if (menu_[i][0]) {
+ gr_text(gr_sys_font(), x + 4, y, menu_[i], 0);
}
y += char_height_+4;
}
@@ -211,163 +172,43 @@
// screen, the bottom of the menu, or we've displayed the
// entire text buffer.
int ty;
- int row = (text_top+text_rows-1) % text_rows;
+ int row = (text_top_ + text_rows_ - 1) % text_rows_;
size_t count = 0;
for (int ty = gr_fb_height() - char_height_ - outer_height;
- ty > y+2 && count < text_rows;
+ ty > y + 2 && count < text_rows_;
ty -= char_height_, ++count) {
- gr_text(x+4, ty, text[row], 0);
+ gr_text(gr_sys_font(), x+4, ty, text_[row], 0);
--row;
- if (row < 0) row = text_rows-1;
+ if (row < 0) row = text_rows_ - 1;
}
}
}
-void WearRecoveryUI::update_screen_locked()
-{
+// TODO merge drawing routines with screen_ui
+void WearRecoveryUI::update_progress_locked() {
draw_screen_locked();
gr_flip();
}
-// Keeps the progress bar updated, even when the process is otherwise busy.
-void* WearRecoveryUI::progress_thread(void *cookie) {
- self->progress_loop();
- return NULL;
-}
+void WearRecoveryUI::InitTextParams() {
+ ScreenRecoveryUI::InitTextParams();
-void WearRecoveryUI::progress_loop() {
- double interval = 1.0 / animation_fps;
- for (;;) {
- double start = now();
- pthread_mutex_lock(&updateMutex);
- int redraw = 0;
+ text_cols_ = (gr_fb_width() - (outer_width * 2)) / char_width_;
- if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING)
- && !show_text) {
- if (!intro_done) {
- if (current_frame >= intro_frames - 1) {
- intro_done = true;
- current_frame = 0;
- } else {
- current_frame++;
- }
- } else {
- current_frame = (current_frame + 1) % loop_frames;
- }
- redraw = 1;
- }
+ if (text_rows_ > kMaxRows) text_rows_ = kMaxRows;
+ if (text_cols_ > kMaxCols) text_cols_ = kMaxCols;
- // move the progress bar forward on timed intervals, if configured
- int duration = progressScopeDuration;
- if (progressBarType == DETERMINATE && duration > 0) {
- double elapsed = now() - progressScopeTime;
- float p = 1.0 * elapsed / duration;
- if (p > 1.0) p = 1.0;
- if (p > progress) {
- progress = p;
- redraw = 1;
- }
- }
-
- if (redraw)
- update_screen_locked();
-
- pthread_mutex_unlock(&updateMutex);
- double end = now();
- // minimum of 20ms delay between frames
- double delay = interval - (end-start);
- if (delay < 0.02) delay = 0.02;
- usleep((long)(delay * 1000000));
- }
-}
-
-void WearRecoveryUI::Init()
-{
- gr_init();
-
- gr_font_size(&char_width_, &char_height_);
-
- text_col = text_row = 0;
- text_rows = (gr_fb_height()) / char_height_;
visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height_;
- if (text_rows > kMaxRows) text_rows = kMaxRows;
- text_top = 1;
+}
- text_cols = (gr_fb_width() - (outer_width * 2)) / char_width_;
- if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
+void WearRecoveryUI::Init() {
+ ScreenRecoveryUI::Init();
- LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]);
- backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
LoadBitmap("icon_error", &backgroundIcon[ERROR]);
backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];
- introFrames = (GRSurface**)malloc(intro_frames * sizeof(GRSurface*));
- for (int i = 0; i < intro_frames; ++i) {
- char filename[40];
- sprintf(filename, "intro%02d", i);
- LoadBitmap(filename, introFrames + i);
- }
-
- loopFrames = (GRSurface**)malloc(loop_frames * sizeof(GRSurface*));
- for (int i = 0; i < loop_frames; ++i) {
- char filename[40];
- sprintf(filename, "loop%02d", i);
- LoadBitmap(filename, loopFrames + i);
- }
-
- pthread_create(&progress_t, NULL, progress_thread, NULL);
- RecoveryUI::Init();
-}
-
-void WearRecoveryUI::SetBackground(Icon icon)
-{
- pthread_mutex_lock(&updateMutex);
- currentIcon = icon;
- update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
-}
-
-void WearRecoveryUI::SetProgressType(ProgressType type)
-{
- pthread_mutex_lock(&updateMutex);
- if (progressBarType != type) {
- progressBarType = type;
- }
- progressScopeStart = 0;
- progressScopeSize = 0;
- progress = 0;
- update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
-}
-
-void WearRecoveryUI::ShowProgress(float portion, float seconds)
-{
- pthread_mutex_lock(&updateMutex);
- progressBarType = DETERMINATE;
- progressScopeStart += progressScopeSize;
- progressScopeSize = portion;
- progressScopeTime = now();
- progressScopeDuration = seconds;
- progress = 0;
- update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
-}
-
-void WearRecoveryUI::SetProgress(float fraction)
-{
- pthread_mutex_lock(&updateMutex);
- if (fraction < 0.0) fraction = 0.0;
- if (fraction > 1.0) fraction = 1.0;
- if (progressBarType == DETERMINATE && fraction > progress) {
- // Skip updates that aren't visibly different.
- int width = progress_bar_width;
- float scale = width * progressScopeSize;
- if ((int) (progress * scale) != (int) (fraction * scale)) {
- progress = fraction;
- update_screen_locked();
- }
- }
- pthread_mutex_unlock(&updateMutex);
+ // This leaves backgroundIcon[INSTALLING_UPDATE] and backgroundIcon[ERASING]
+ // as NULL which is fine since draw_background_locked() doesn't use them.
}
void WearRecoveryUI::SetStage(int current, int max)
@@ -386,40 +227,40 @@
// This can get called before ui_init(), so be careful.
pthread_mutex_lock(&updateMutex);
- if (text_rows > 0 && text_cols > 0) {
+ if (text_rows_ > 0 && text_cols_ > 0) {
char *ptr;
for (ptr = buf; *ptr != '\0'; ++ptr) {
- if (*ptr == '\n' || text_col >= text_cols) {
- text[text_row][text_col] = '\0';
- text_col = 0;
- text_row = (text_row + 1) % text_rows;
- if (text_row == text_top) text_top = (text_top + 1) % text_rows;
+ if (*ptr == '\n' || text_col_ >= text_cols_) {
+ text_[text_row_][text_col_] = '\0';
+ text_col_ = 0;
+ text_row_ = (text_row_ + 1) % text_rows_;
+ if (text_row_ == text_top_) text_top_ = (text_top_ + 1) % text_rows_;
}
- if (*ptr != '\n') text[text_row][text_col++] = *ptr;
+ if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
}
- text[text_row][text_col] = '\0';
+ text_[text_row_][text_col_] = '\0';
update_screen_locked();
}
pthread_mutex_unlock(&updateMutex);
}
void WearRecoveryUI::StartMenu(const char* const * headers, const char* const * items,
- int initial_selection) {
+ int initial_selection) {
pthread_mutex_lock(&updateMutex);
- if (text_rows > 0 && text_cols > 0) {
+ if (text_rows_ > 0 && text_cols_ > 0) {
menu_headers_ = headers;
size_t i = 0;
- // "i < text_rows" is removed from the loop termination condition,
+ // "i < text_rows_" is removed from the loop termination condition,
// which is different from the one in ScreenRecoveryUI::StartMenu().
// Because WearRecoveryUI supports scrollable menu, it's fine to have
- // more entries than text_rows. The menu may be truncated otherwise.
+ // more entries than text_rows_. The menu may be truncated otherwise.
// Bug: 23752519
for (; items[i] != nullptr; i++) {
- strncpy(menu[i], items[i], text_cols - 1);
- menu[i][text_cols - 1] = '\0';
+ strncpy(menu_[i], items[i], text_cols_ - 1);
+ menu_[i][text_cols_ - 1] = '\0';
}
menu_items = i;
- show_menu = 1;
+ show_menu = true;
menu_sel = initial_selection;
menu_start = 0;
menu_end = visible_text_rows - 1 - menu_unusable_rows;
@@ -433,7 +274,7 @@
int WearRecoveryUI::SelectMenu(int sel) {
int old_sel;
pthread_mutex_lock(&updateMutex);
- if (show_menu > 0) {
+ if (show_menu) {
old_sel = menu_sel;
menu_sel = sel;
if (menu_sel < 0) menu_sel = 0;
@@ -452,53 +293,6 @@
return sel;
}
-void WearRecoveryUI::EndMenu() {
- int i;
- pthread_mutex_lock(&updateMutex);
- if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
- show_menu = 0;
- update_screen_locked();
- }
- pthread_mutex_unlock(&updateMutex);
-}
-
-bool WearRecoveryUI::IsTextVisible()
-{
- pthread_mutex_lock(&updateMutex);
- int visible = show_text;
- pthread_mutex_unlock(&updateMutex);
- return visible;
-}
-
-bool WearRecoveryUI::WasTextEverVisible()
-{
- pthread_mutex_lock(&updateMutex);
- int ever_visible = show_text_ever;
- pthread_mutex_unlock(&updateMutex);
- return ever_visible;
-}
-
-void WearRecoveryUI::ShowText(bool visible)
-{
- pthread_mutex_lock(&updateMutex);
- // Don't show text during ota install or factory reset
- if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
- pthread_mutex_unlock(&updateMutex);
- return;
- }
- show_text = visible;
- if (show_text) show_text_ever = 1;
- update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
-}
-
-void WearRecoveryUI::Redraw()
-{
- pthread_mutex_lock(&updateMutex);
- update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
-}
-
void WearRecoveryUI::ShowFile(FILE* fp) {
std::vector<long> offsets;
offsets.push_back(ftell(fp));
@@ -538,12 +332,12 @@
int ch = getc(fp);
if (ch == EOF) {
- text_row = text_top = text_rows - 2;
+ text_row_ = text_top_ = text_rows_ - 2;
show_prompt = true;
} else {
PutChar(ch);
- if (text_col == 0 && text_row >= text_rows - 2) {
- text_top = text_row;
+ if (text_col_ == 0 && text_row_ >= text_rows_ - 2) {
+ text_top_ = text_row_;
show_prompt = true;
}
}
@@ -552,10 +346,10 @@
void WearRecoveryUI::PutChar(char ch) {
pthread_mutex_lock(&updateMutex);
- if (ch != '\n') text[text_row][text_col++] = ch;
- if (ch == '\n' || text_col >= text_cols) {
- text_col = 0;
- ++text_row;
+ if (ch != '\n') text_[text_row_][text_col_++] = ch;
+ if (ch == '\n' || text_col_ >= text_cols_) {
+ text_col_ = 0;
+ ++text_row_;
}
pthread_mutex_unlock(&updateMutex);
}
@@ -572,11 +366,11 @@
void WearRecoveryUI::ClearText() {
pthread_mutex_lock(&updateMutex);
- text_col = 0;
- text_row = 0;
- text_top = 1;
- for (size_t i = 0; i < text_rows; ++i) {
- memset(text[i], 0, text_cols + 1);
+ text_col_ = 0;
+ text_row_ = 0;
+ text_top_ = 1;
+ for (size_t i = 0; i < text_rows_; ++i) {
+ memset(text_[i], 0, text_cols_ + 1);
}
pthread_mutex_unlock(&updateMutex);
}
@@ -597,17 +391,17 @@
}
pthread_mutex_lock(&updateMutex);
- if (text_rows > 0 && text_cols > 0) {
+ if (text_rows_ > 0 && text_cols_ > 0) {
for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) {
- if (*ptr == '\n' || text_col >= text_cols) {
- text[text_row][text_col] = '\0';
- text_col = 0;
- text_row = (text_row + 1) % text_rows;
- if (text_row == text_top) text_top = (text_top + 1) % text_rows;
+ if (*ptr == '\n' || text_col_ >= text_cols_) {
+ text_[text_row_][text_col_] = '\0';
+ text_col_ = 0;
+ text_row_ = (text_row_ + 1) % text_rows_;
+ if (text_row_ == text_top_) text_top_ = (text_top_ + 1) % text_rows_;
}
- if (*ptr != '\n') text[text_row][text_col++] = *ptr;
+ if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
}
- text[text_row][text_col] = '\0';
+ text_[text_row_][text_col_] = '\0';
update_screen_locked();
}
pthread_mutex_unlock(&updateMutex);
diff --git a/wear_ui.h b/wear_ui.h
index e2d6fe0..9351d41 100644
--- a/wear_ui.h
+++ b/wear_ui.h
@@ -23,39 +23,22 @@
public:
WearRecoveryUI();
- void Init();
- // overall recovery state ("background image")
- void SetBackground(Icon icon);
+ void Init() override;
- // progress indicator
- void SetProgressType(ProgressType type);
- void ShowProgress(float portion, float seconds);
- void SetProgress(float fraction);
-
- void SetStage(int current, int max);
-
- // text log
- void ShowText(bool visible);
- bool IsTextVisible();
- bool WasTextEverVisible();
+ void SetStage(int current, int max) override;
// printing messages
- void Print(const char* fmt, ...);
- void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3);
- void ShowFile(const char* filename);
- void ShowFile(FILE* fp);
+ void Print(const char* fmt, ...) override;
+ void PrintOnScreenOnly(const char* fmt, ...) override __printflike(2, 3);
+ void ShowFile(const char* filename) override;
+ void ShowFile(FILE* fp) override;
// menu display
void StartMenu(const char* const * headers, const char* const * items,
- int initial_selection);
- int SelectMenu(int sel);
- void EndMenu();
-
- void Redraw();
+ int initial_selection) override;
+ int SelectMenu(int sel) override;
protected:
- int progress_bar_height, progress_bar_width;
-
// progress bar vertical position, it's centered horizontally
int progress_bar_y;
@@ -67,59 +50,34 @@
// that may otherwise go out of the screen.
int menu_unusable_rows;
- // number of intro frames (default: 22) and loop frames (default: 60)
- int intro_frames;
- int loop_frames;
+ int GetProgressBaseline() override;
- // Number of frames per sec (default: 30) for both of intro and loop.
- int animation_fps;
+ void InitTextParams() override;
+
+ void update_progress_locked() override;
+
+ void PrintV(const char*, bool, va_list) override;
private:
- Icon currentIcon;
-
- bool intro_done;
-
- int current_frame;
-
GRSurface* backgroundIcon[5];
- GRSurface* *introFrames;
- GRSurface* *loopFrames;
-
- ProgressType progressBarType;
-
- float progressScopeStart, progressScopeSize, progress;
- double progressScopeTime, progressScopeDuration;
static const int kMaxCols = 96;
static const int kMaxRows = 96;
- // Log text overlay, displayed when a magic key is pressed
- char text[kMaxRows][kMaxCols];
- size_t text_cols, text_rows;
// Number of text rows seen on screen
int visible_text_rows;
- size_t text_col, text_row, text_top;
- bool show_text;
- bool show_text_ever; // has show_text ever been true?
- char menu[kMaxRows][kMaxCols];
- bool show_menu;
const char* const* menu_headers_;
- int menu_items, menu_sel;
int menu_start, menu_end;
pthread_t progress_t;
- private:
- void draw_background_locked(Icon icon);
+ void draw_background_locked() override;
+ void draw_screen_locked() override;
void draw_progress_locked();
- void draw_screen_locked();
- void update_screen_locked();
- static void* progress_thread(void* cookie);
- void progress_loop();
+
void PutChar(char);
void ClearText();
- void PrintV(const char*, bool, va_list);
};
#endif // RECOVERY_WEAR_UI_H