Commit 84d61ce3 authored by Ethan Yonker's avatar Ethan Yonker

Update TWRP to AOSP 7.1.2

Change-Id: I19c1546efb4182aac62c690e3cc05b04e3a9a32e
parents 6355b56c f1278966
......@@ -652,9 +652,9 @@ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -gt 22; echo $$?),0)
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
......
......@@ -44,4 +44,26 @@ enum CauseCode {
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
......@@ -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_PROPERTIES = "payload_properties.txt
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 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache,
}
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 @@ install_package(const char* path, bool* wipe_cache, const char* install_file,
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 @@ install_package(const char* path, bool* wipe_cache, const char* install_file,
} 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;
}
......
......@@ -79,6 +79,9 @@ endif
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.
......
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,
......
......@@ -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,18 +62,36 @@ static bool outside(int x, int y)
{
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)
{
unsigned char orig[2];
......@@ -146,36 +158,67 @@ static void text_blend(unsigned char* src_p, int src_row_bytes,
}
}
#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->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;
}
}
#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->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;
}
}
#endif //TW_USE_MINUI_CUSTOM_FONTS
void gr_texticon(int x, int y, GRSurface* icon) {
if (icon == NULL) return;
......@@ -383,6 +426,7 @@ unsigned int gr_get_height(GRSurface* surface) {
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 @@ static void gr_init_font(void)
// 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 @@ static void gr_init_font(void)
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 @@ void gr_fb_blank(bool blank)
{
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;
}
......@@ -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 @@ struct GRSurface {
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_fb_blank(bool blank);
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 @@ int res_create_localized_alpha_surface(const char* name, const char* locale,
// 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 @@ void gr_clear();
}
#endif
#endif // ifndef TW_USE_OLD_MINUI_H
#endif // ifndef TW_USE_MINUI_21
#endif // ifndef _MINUI_H_
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,
......
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,
......
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,
......
......@@ -1429,15 +1429,18 @@ static bool bootreason_in_blacklist() {
}
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(
......
......@@ -53,8 +53,6 @@ static double now() {
ScreenRecoveryUI::ScreenRecoveryUI() :
currentIcon(NONE),
locale(nullptr),
intro_done(false),
current_frame(0),
progressBarType(EMPTY),
progressScopeStart(0),
progressScopeSize(0),
......@@ -75,6 +73,8 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
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::DrawHorizontalRule(int* y) {
}
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 @@ void ScreenRecoveryUI::draw_screen_locked() {
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 @@ void ScreenRecoveryUI::draw_screen_locked() {
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 @@ void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) {
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 @@ void ScreenRecoveryUI::Init() {
// 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 @@ void ScreenRecoveryUI::Init() {
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.