release-request-b4bc7b84-64b6-4176-8f16-ce17068fad13-for-git_pi-release-4370135 snap-temp-L93500000107644030
Change-Id: Ib62a1fc76f33dd6600e4e581d761906544c9de86
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
subdirs = [
|
||||
"bootloader_message",
|
||||
"otafault",
|
||||
"otautil",
|
||||
]
|
||||
|
||||
@@ -263,7 +263,6 @@ include \
|
||||
$(LOCAL_PATH)/edify/Android.mk \
|
||||
$(LOCAL_PATH)/minadbd/Android.mk \
|
||||
$(LOCAL_PATH)/minui/Android.mk \
|
||||
$(LOCAL_PATH)/otafault/Android.mk \
|
||||
$(LOCAL_PATH)/tests/Android.mk \
|
||||
$(LOCAL_PATH)/tools/Android.mk \
|
||||
$(LOCAL_PATH)/uncrypt/Android.mk \
|
||||
|
||||
@@ -112,11 +112,13 @@ LOCAL_C_INCLUDES := bootable/recovery
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libapplypatch_modes \
|
||||
libapplypatch \
|
||||
libbase \
|
||||
libedify \
|
||||
libotafault \
|
||||
libcrypto \
|
||||
libbspatch \
|
||||
libbase \
|
||||
libziparchive \
|
||||
liblog \
|
||||
libcrypto \
|
||||
libbz
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbase \
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "edify/expr.h"
|
||||
#include "ota_io.h"
|
||||
#include "otafault/ota_io.h"
|
||||
#include "print_sha1.h"
|
||||
|
||||
static int LoadPartitionContents(const std::string& filename, FileContents* file);
|
||||
|
||||
+269
-276
@@ -25,10 +25,12 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <png.h>
|
||||
|
||||
@@ -46,89 +48,126 @@ static GRSurface* malloc_surface(size_t data_size) {
|
||||
return surface;
|
||||
}
|
||||
|
||||
static int open_png(const char* name, png_structp* png_ptr, png_infop* info_ptr,
|
||||
png_uint_32* width, png_uint_32* height, png_byte* channels) {
|
||||
char resPath[256];
|
||||
unsigned char header[8];
|
||||
int result = 0;
|
||||
int color_type, bit_depth;
|
||||
size_t bytesRead;
|
||||
// This class handles the png file parsing. It also holds the ownership of the png pointer and the
|
||||
// opened file pointer. Both will be destroyed/closed when this object goes out of scope.
|
||||
class PngHandler {
|
||||
public:
|
||||
PngHandler(const std::string& name);
|
||||
|
||||
snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name);
|
||||
resPath[sizeof(resPath)-1] = '\0';
|
||||
FILE* fp = fopen(resPath, "rbe");
|
||||
if (fp == NULL) {
|
||||
result = -1;
|
||||
goto exit;
|
||||
}
|
||||
~PngHandler();
|
||||
|
||||
bytesRead = fread(header, 1, sizeof(header), fp);
|
||||
if (bytesRead != sizeof(header)) {
|
||||
result = -2;
|
||||
goto exit;
|
||||
}
|
||||
png_uint_32 width() const {
|
||||
return width_;
|
||||
}
|
||||
|
||||
if (png_sig_cmp(header, 0, sizeof(header))) {
|
||||
result = -3;
|
||||
goto exit;
|
||||
}
|
||||
png_uint_32 height() const {
|
||||
return height_;
|
||||
}
|
||||
|
||||
*png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!*png_ptr) {
|
||||
result = -4;
|
||||
goto exit;
|
||||
}
|
||||
png_byte channels() const {
|
||||
return channels_;
|
||||
}
|
||||
|
||||
*info_ptr = png_create_info_struct(*png_ptr);
|
||||
if (!*info_ptr) {
|
||||
result = -5;
|
||||
goto exit;
|
||||
}
|
||||
png_structp png_ptr() const {
|
||||
return png_ptr_;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(*png_ptr))) {
|
||||
result = -6;
|
||||
goto exit;
|
||||
}
|
||||
png_infop info_ptr() const {
|
||||
return info_ptr_;
|
||||
}
|
||||
|
||||
png_init_io(*png_ptr, fp);
|
||||
png_set_sig_bytes(*png_ptr, sizeof(header));
|
||||
png_read_info(*png_ptr, *info_ptr);
|
||||
int error_code() const {
|
||||
return error_code_;
|
||||
};
|
||||
|
||||
png_get_IHDR(*png_ptr, *info_ptr, width, height, &bit_depth,
|
||||
&color_type, NULL, NULL, NULL);
|
||||
operator bool() const {
|
||||
return error_code_ == 0;
|
||||
}
|
||||
|
||||
*channels = png_get_channels(*png_ptr, *info_ptr);
|
||||
private:
|
||||
png_structp png_ptr_{ nullptr };
|
||||
png_infop info_ptr_{ nullptr };
|
||||
png_uint_32 width_;
|
||||
png_uint_32 height_;
|
||||
png_byte channels_;
|
||||
|
||||
if (bit_depth == 8 && *channels == 3 && color_type == PNG_COLOR_TYPE_RGB) {
|
||||
// 8-bit RGB images: great, nothing to do.
|
||||
} else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
// 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
|
||||
png_set_expand_gray_1_2_4_to_8(*png_ptr);
|
||||
} else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
// paletted images: expand to 8-bit RGB. Note that we DON'T
|
||||
// currently expand the tRNS chunk (if any) to an alpha
|
||||
// channel, because minui doesn't support alpha channels in
|
||||
// general.
|
||||
png_set_palette_to_rgb(*png_ptr);
|
||||
*channels = 3;
|
||||
} else {
|
||||
fprintf(stderr, "minui doesn't support PNG depth %d channels %d color_type %d\n",
|
||||
bit_depth, *channels, color_type);
|
||||
result = -7;
|
||||
goto exit;
|
||||
}
|
||||
// The |error_code_| is set to a negative value if an error occurs when opening the png file.
|
||||
int error_code_;
|
||||
// After initialization, we'll keep the file pointer open before destruction of PngHandler.
|
||||
std::unique_ptr<FILE, decltype(&fclose)> png_fp_;
|
||||
};
|
||||
|
||||
return result;
|
||||
PngHandler::PngHandler(const std::string& name) : error_code_(0), png_fp_(nullptr, fclose) {
|
||||
std::string res_path = android::base::StringPrintf("/res/images/%s.png", name.c_str());
|
||||
png_fp_.reset(fopen(res_path.c_str(), "rbe"));
|
||||
if (!png_fp_) {
|
||||
error_code_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (result < 0) {
|
||||
png_destroy_read_struct(png_ptr, info_ptr, NULL);
|
||||
}
|
||||
if (fp != NULL) {
|
||||
fclose(fp);
|
||||
}
|
||||
unsigned char header[8];
|
||||
size_t bytesRead = fread(header, 1, sizeof(header), png_fp_.get());
|
||||
if (bytesRead != sizeof(header)) {
|
||||
error_code_ = -2;
|
||||
return;
|
||||
}
|
||||
|
||||
return result;
|
||||
if (png_sig_cmp(header, 0, sizeof(header))) {
|
||||
error_code_ = -3;
|
||||
return;
|
||||
}
|
||||
|
||||
png_ptr_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png_ptr_) {
|
||||
error_code_ = -4;
|
||||
return;
|
||||
}
|
||||
|
||||
info_ptr_ = png_create_info_struct(png_ptr_);
|
||||
if (!info_ptr_) {
|
||||
error_code_ = -5;
|
||||
return;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr_))) {
|
||||
error_code_ = -6;
|
||||
return;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr_, png_fp_.get());
|
||||
png_set_sig_bytes(png_ptr_, sizeof(header));
|
||||
png_read_info(png_ptr_, info_ptr_);
|
||||
|
||||
int color_type;
|
||||
int bit_depth;
|
||||
png_get_IHDR(png_ptr_, info_ptr_, &width_, &height_, &bit_depth, &color_type, nullptr, nullptr,
|
||||
nullptr);
|
||||
|
||||
channels_ = png_get_channels(png_ptr_, info_ptr_);
|
||||
|
||||
if (bit_depth == 8 && channels_ == 3 && color_type == PNG_COLOR_TYPE_RGB) {
|
||||
// 8-bit RGB images: great, nothing to do.
|
||||
} else if (bit_depth <= 8 && channels_ == 1 && color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
// 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr_);
|
||||
} else if (bit_depth <= 8 && channels_ == 1 && color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
// paletted images: expand to 8-bit RGB. Note that we DON'T
|
||||
// currently expand the tRNS chunk (if any) to an alpha
|
||||
// channel, because minui doesn't support alpha channels in
|
||||
// general.
|
||||
png_set_palette_to_rgb(png_ptr_);
|
||||
channels_ = 3;
|
||||
} else {
|
||||
fprintf(stderr, "minui doesn't support PNG depth %d channels %d color_type %d\n", bit_depth,
|
||||
channels_, color_type);
|
||||
error_code_ = -7;
|
||||
}
|
||||
}
|
||||
|
||||
PngHandler::~PngHandler() {
|
||||
if (png_ptr_) {
|
||||
png_destroy_read_struct(&png_ptr_, &info_ptr_, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// "display" surfaces are transformed into the framebuffer's required
|
||||
@@ -198,178 +237,152 @@ static void transform_rgb_to_draw(unsigned char* input_row,
|
||||
}
|
||||
|
||||
int res_create_display_surface(const char* name, GRSurface** pSurface) {
|
||||
GRSurface* surface = NULL;
|
||||
int result = 0;
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
png_uint_32 width, height;
|
||||
png_byte channels;
|
||||
unsigned char* p_row;
|
||||
unsigned int y;
|
||||
*pSurface = nullptr;
|
||||
|
||||
*pSurface = NULL;
|
||||
PngHandler png_handler(name);
|
||||
if (!png_handler) return png_handler.error_code();
|
||||
|
||||
result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
|
||||
if (result < 0) return result;
|
||||
png_structp png_ptr = png_handler.png_ptr();
|
||||
png_uint_32 width = png_handler.width();
|
||||
png_uint_32 height = png_handler.height();
|
||||
|
||||
surface = init_display_surface(width, height);
|
||||
if (surface == NULL) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
GRSurface* surface = init_display_surface(width, height);
|
||||
if (!surface) {
|
||||
return -8;
|
||||
}
|
||||
|
||||
#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
|
||||
png_set_bgr(png_ptr);
|
||||
png_set_bgr(png_ptr);
|
||||
#endif
|
||||
|
||||
p_row = static_cast<unsigned char*>(malloc(width * 4));
|
||||
for (y = 0; y < height; ++y) {
|
||||
png_read_row(png_ptr, p_row, NULL);
|
||||
transform_rgb_to_draw(p_row, surface->data + y * surface->row_bytes, channels, width);
|
||||
}
|
||||
free(p_row);
|
||||
for (png_uint_32 y = 0; y < height; ++y) {
|
||||
std::vector<unsigned char> p_row(width * 4);
|
||||
png_read_row(png_ptr, p_row.data(), nullptr);
|
||||
transform_rgb_to_draw(p_row.data(), surface->data + y * surface->row_bytes,
|
||||
png_handler.channels(), width);
|
||||
}
|
||||
|
||||
*pSurface = surface;
|
||||
*pSurface = surface;
|
||||
|
||||
exit:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
if (result < 0 && surface != NULL) free(surface);
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int res_create_multi_display_surface(const char* name, int* frames, int* fps,
|
||||
GRSurface*** pSurface) {
|
||||
GRSurface** surface = NULL;
|
||||
int result = 0;
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
png_uint_32 width, height;
|
||||
png_byte channels;
|
||||
png_textp text;
|
||||
int num_text;
|
||||
unsigned char* p_row;
|
||||
unsigned int y;
|
||||
GRSurface*** pSurface) {
|
||||
*pSurface = nullptr;
|
||||
*frames = -1;
|
||||
|
||||
*pSurface = NULL;
|
||||
*frames = -1;
|
||||
PngHandler png_handler(name);
|
||||
if (!png_handler) return png_handler.error_code();
|
||||
|
||||
result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
|
||||
if (result < 0) return result;
|
||||
png_structp png_ptr = png_handler.png_ptr();
|
||||
png_uint_32 width = png_handler.width();
|
||||
png_uint_32 height = png_handler.height();
|
||||
|
||||
*frames = 1;
|
||||
*fps = 20;
|
||||
if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
|
||||
for (int i = 0; i < num_text; ++i) {
|
||||
if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
|
||||
*frames = atoi(text[i].text);
|
||||
} else if (text[i].key && strcmp(text[i].key, "FPS") == 0 && text[i].text) {
|
||||
*fps = atoi(text[i].text);
|
||||
}
|
||||
}
|
||||
printf(" found frames = %d\n", *frames);
|
||||
printf(" found fps = %d\n", *fps);
|
||||
*frames = 1;
|
||||
*fps = 20;
|
||||
png_textp text;
|
||||
int num_text;
|
||||
if (png_get_text(png_ptr, png_handler.info_ptr(), &text, &num_text)) {
|
||||
for (int i = 0; i < num_text; ++i) {
|
||||
if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
|
||||
*frames = atoi(text[i].text);
|
||||
} else if (text[i].key && strcmp(text[i].key, "FPS") == 0 && text[i].text) {
|
||||
*fps = atoi(text[i].text);
|
||||
}
|
||||
}
|
||||
printf(" found frames = %d\n", *frames);
|
||||
printf(" found fps = %d\n", *fps);
|
||||
}
|
||||
|
||||
if (*frames <= 0 || *fps <= 0) {
|
||||
printf("bad number of frames (%d) and/or FPS (%d)\n", *frames, *fps);
|
||||
result = -10;
|
||||
goto exit;
|
||||
}
|
||||
int result = 0;
|
||||
GRSurface** surface = nullptr;
|
||||
if (*frames <= 0 || *fps <= 0) {
|
||||
printf("bad number of frames (%d) and/or FPS (%d)\n", *frames, *fps);
|
||||
result = -10;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (height % *frames != 0) {
|
||||
printf("bad height (%d) for frame count (%d)\n", height, *frames);
|
||||
result = -9;
|
||||
goto exit;
|
||||
}
|
||||
if (height % *frames != 0) {
|
||||
printf("bad height (%d) for frame count (%d)\n", height, *frames);
|
||||
result = -9;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
surface = static_cast<GRSurface**>(calloc(*frames, sizeof(GRSurface*)));
|
||||
if (surface == NULL) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
for (int i = 0; i < *frames; ++i) {
|
||||
surface[i] = init_display_surface(width, height / *frames);
|
||||
if (surface[i] == NULL) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
surface = static_cast<GRSurface**>(calloc(*frames, sizeof(GRSurface*)));
|
||||
if (!surface) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
for (int i = 0; i < *frames; ++i) {
|
||||
surface[i] = init_display_surface(width, height / *frames);
|
||||
if (!surface[i]) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
|
||||
png_set_bgr(png_ptr);
|
||||
png_set_bgr(png_ptr);
|
||||
#endif
|
||||
|
||||
p_row = static_cast<unsigned char*>(malloc(width * 4));
|
||||
for (y = 0; y < height; ++y) {
|
||||
png_read_row(png_ptr, p_row, NULL);
|
||||
int frame = y % *frames;
|
||||
unsigned char* out_row = surface[frame]->data +
|
||||
(y / *frames) * surface[frame]->row_bytes;
|
||||
transform_rgb_to_draw(p_row, out_row, channels, width);
|
||||
}
|
||||
free(p_row);
|
||||
for (png_uint_32 y = 0; y < height; ++y) {
|
||||
std::vector<unsigned char> p_row(width * 4);
|
||||
png_read_row(png_ptr, p_row.data(), nullptr);
|
||||
int frame = y % *frames;
|
||||
unsigned char* out_row = surface[frame]->data + (y / *frames) * surface[frame]->row_bytes;
|
||||
transform_rgb_to_draw(p_row.data(), out_row, png_handler.channels(), width);
|
||||
}
|
||||
|
||||
*pSurface = surface;
|
||||
*pSurface = surface;
|
||||
|
||||
exit:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
|
||||
if (result < 0) {
|
||||
if (surface) {
|
||||
for (int i = 0; i < *frames; ++i) {
|
||||
free(surface[i]);
|
||||
}
|
||||
free(surface);
|
||||
}
|
||||
if (result < 0) {
|
||||
if (surface) {
|
||||
for (int i = 0; i < *frames; ++i) {
|
||||
free(surface[i]);
|
||||
}
|
||||
free(surface);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int res_create_alpha_surface(const char* name, GRSurface** pSurface) {
|
||||
GRSurface* surface = NULL;
|
||||
int result = 0;
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
png_uint_32 width, height;
|
||||
png_byte channels;
|
||||
*pSurface = nullptr;
|
||||
|
||||
*pSurface = NULL;
|
||||
PngHandler png_handler(name);
|
||||
if (!png_handler) return png_handler.error_code();
|
||||
|
||||
result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
|
||||
if (result < 0) return result;
|
||||
if (png_handler.channels() != 1) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
if (channels != 1) {
|
||||
result = -7;
|
||||
goto exit;
|
||||
}
|
||||
png_structp png_ptr = png_handler.png_ptr();
|
||||
png_uint_32 width = png_handler.width();
|
||||
png_uint_32 height = png_handler.height();
|
||||
|
||||
surface = malloc_surface(width * height);
|
||||
if (surface == NULL) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->row_bytes = width;
|
||||
surface->pixel_bytes = 1;
|
||||
GRSurface* surface = malloc_surface(width * height);
|
||||
if (!surface) {
|
||||
return -8;
|
||||
}
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->row_bytes = width;
|
||||
surface->pixel_bytes = 1;
|
||||
|
||||
#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
|
||||
png_set_bgr(png_ptr);
|
||||
png_set_bgr(png_ptr);
|
||||
#endif
|
||||
|
||||
unsigned char* p_row;
|
||||
unsigned int y;
|
||||
for (y = 0; y < height; ++y) {
|
||||
p_row = surface->data + y * surface->row_bytes;
|
||||
png_read_row(png_ptr, p_row, NULL);
|
||||
}
|
||||
for (png_uint_32 y = 0; y < height; ++y) {
|
||||
unsigned char* p_row = surface->data + y * surface->row_bytes;
|
||||
png_read_row(png_ptr, p_row, nullptr);
|
||||
}
|
||||
|
||||
*pSurface = surface;
|
||||
*pSurface = surface;
|
||||
|
||||
exit:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
if (result < 0 && surface != NULL) free(surface);
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function tests if a locale string stored in PNG (prefix) matches
|
||||
@@ -397,109 +410,89 @@ bool matches_locale(const std::string& prefix, const std::string& locale) {
|
||||
}
|
||||
|
||||
std::vector<std::string> get_locales_in_png(const std::string& png_name) {
|
||||
png_structp png_ptr = nullptr;
|
||||
png_infop info_ptr = nullptr;
|
||||
png_uint_32 width, height;
|
||||
png_byte channels;
|
||||
|
||||
int status = open_png(png_name.c_str(), &png_ptr, &info_ptr, &width, &height, &channels);
|
||||
if (status < 0) {
|
||||
printf("Failed to open %s\n", png_name.c_str());
|
||||
PngHandler png_handler(png_name);
|
||||
if (!png_handler) {
|
||||
printf("Failed to open %s, error: %d\n", png_name.c_str(), png_handler.error_code());
|
||||
return {};
|
||||
}
|
||||
if (channels != 1) {
|
||||
printf("Expect input png to have 1 data channel, this file has %d\n", channels);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
||||
if (png_handler.channels() != 1) {
|
||||
printf("Expect input png to have 1 data channel, this file has %d\n", png_handler.channels());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> result;
|
||||
std::vector<unsigned char> row(width);
|
||||
for (png_uint_32 y = 0; y < height; ++y) {
|
||||
png_read_row(png_ptr, row.data(), nullptr);
|
||||
std::vector<unsigned char> row(png_handler.width());
|
||||
for (png_uint_32 y = 0; y < png_handler.height(); ++y) {
|
||||
png_read_row(png_handler.png_ptr(), row.data(), nullptr);
|
||||
int h = (row[3] << 8) | row[2];
|
||||
std::string loc(reinterpret_cast<char*>(&row[5]));
|
||||
if (!loc.empty()) {
|
||||
result.push_back(loc);
|
||||
}
|
||||
for (int i = 0; i < h; ++i, ++y) {
|
||||
png_read_row(png_ptr, row.data(), NULL);
|
||||
png_read_row(png_handler.png_ptr(), row.data(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
int res_create_localized_alpha_surface(const char* name,
|
||||
const char* locale,
|
||||
GRSurface** pSurface) {
|
||||
GRSurface* surface = NULL;
|
||||
int result = 0;
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
png_uint_32 width, height;
|
||||
png_byte channels;
|
||||
png_uint_32 y;
|
||||
std::vector<unsigned char> row;
|
||||
*pSurface = nullptr;
|
||||
if (locale == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pSurface = NULL;
|
||||
PngHandler png_handler(name);
|
||||
if (!png_handler) return png_handler.error_code();
|
||||
|
||||
if (locale == NULL) {
|
||||
return result;
|
||||
if (png_handler.channels() != 1) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_handler.png_ptr();
|
||||
png_uint_32 width = png_handler.width();
|
||||
png_uint_32 height = png_handler.height();
|
||||
|
||||
for (png_uint_32 y = 0; y < height; ++y) {
|
||||
std::vector<unsigned char> row(width);
|
||||
png_read_row(png_ptr, row.data(), nullptr);
|
||||
int w = (row[1] << 8) | row[0];
|
||||
int h = (row[3] << 8) | row[2];
|
||||
__unused int len = row[4];
|
||||
char* loc = reinterpret_cast<char*>(&row[5]);
|
||||
|
||||
if (y + 1 + h >= height || matches_locale(loc, locale)) {
|
||||
printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);
|
||||
|
||||
GRSurface* surface = malloc_surface(w * h);
|
||||
if (!surface) {
|
||||
return -8;
|
||||
}
|
||||
surface->width = w;
|
||||
surface->height = h;
|
||||
surface->row_bytes = w;
|
||||
surface->pixel_bytes = 1;
|
||||
|
||||
for (int i = 0; i < h; ++i, ++y) {
|
||||
png_read_row(png_ptr, row.data(), nullptr);
|
||||
memcpy(surface->data + i * w, row.data(), w);
|
||||
}
|
||||
|
||||
*pSurface = surface;
|
||||
break;
|
||||
}
|
||||
|
||||
result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
|
||||
if (result < 0) return result;
|
||||
|
||||
if (channels != 1) {
|
||||
result = -7;
|
||||
goto exit;
|
||||
for (int i = 0; i < h; ++i, ++y) {
|
||||
png_read_row(png_ptr, row.data(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
row.resize(width);
|
||||
for (y = 0; y < height; ++y) {
|
||||
png_read_row(png_ptr, row.data(), NULL);
|
||||
int w = (row[1] << 8) | row[0];
|
||||
int h = (row[3] << 8) | row[2];
|
||||
__unused int len = row[4];
|
||||
char* loc = reinterpret_cast<char*>(&row[5]);
|
||||
|
||||
if (y+1+h >= height || matches_locale(loc, locale)) {
|
||||
printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);
|
||||
|
||||
surface = malloc_surface(w*h);
|
||||
if (surface == NULL) {
|
||||
result = -8;
|
||||
goto exit;
|
||||
}
|
||||
surface->width = w;
|
||||
surface->height = h;
|
||||
surface->row_bytes = w;
|
||||
surface->pixel_bytes = 1;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < h; ++i, ++y) {
|
||||
png_read_row(png_ptr, row.data(), NULL);
|
||||
memcpy(surface->data + i*w, row.data(), w);
|
||||
}
|
||||
|
||||
*pSurface = surface;
|
||||
break;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < h; ++i, ++y) {
|
||||
png_read_row(png_ptr, row.data(), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
if (result < 0 && surface != NULL) free(surface);
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void res_free_surface(GRSurface* surface) {
|
||||
free(surface);
|
||||
free(surface);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
cc_library_static {
|
||||
name: "libotafault",
|
||||
|
||||
srcs: [
|
||||
"config.cpp",
|
||||
"ota_io.cpp",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libziparchive",
|
||||
],
|
||||
|
||||
export_include_dirs: [
|
||||
"include",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wthread-safety",
|
||||
"-Wthread-safety-negative",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "otafault_test",
|
||||
|
||||
srcs: ["test.cpp"],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
|
||||
static_executable: true,
|
||||
|
||||
static_libs: [
|
||||
"libotafault",
|
||||
"libziparchive",
|
||||
"libbase",
|
||||
"liblog",
|
||||
],
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
# Copyright 2015 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific languae governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
otafault_static_libs := \
|
||||
libziparchive \
|
||||
libz \
|
||||
libselinux \
|
||||
libbase \
|
||||
liblog
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-Wthread-safety \
|
||||
-Wthread-safety-negative \
|
||||
-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
|
||||
|
||||
LOCAL_SRC_FILES := config.cpp ota_io.cpp
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
LOCAL_MODULE := libotafault
|
||||
LOCAL_C_INCLUDES := bootable/recovery
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs)
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# otafault_test (static executable)
|
||||
# ===============================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_MODULE := otafault_test
|
||||
LOCAL_STATIC_LIBRARIES := $(otafault_static_libs)
|
||||
LOCAL_CFLAGS := -Wall -Werror
|
||||
LOCAL_C_INCLUDES := bootable/recovery
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
+3
-5
@@ -14,17 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "otafault/config.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <ziparchive/zip_archive.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ota_io.h"
|
||||
#include "otafault/ota_io.h"
|
||||
|
||||
#define OTAIO_MAX_FNAME_SIZE 128
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Read configuration files in the OTA package to determine which files, if any, will trigger errors.
|
||||
* Read configuration files in the OTA package to determine which files, if any, will trigger
|
||||
* errors.
|
||||
*
|
||||
* OTA packages can be modified to trigger errors by adding a top-level
|
||||
* directory called .libotafault, which may optionally contain up to three
|
||||
* files called READ, WRITE, and FSYNC. Each one of these optional files
|
||||
* contains the name of a single file on the device disk which will cause
|
||||
* an IO error on the first call of the appropriate I/O action to that file.
|
||||
* OTA packages can be modified to trigger errors by adding a top-level directory called
|
||||
* .libotafault, which may optionally contain up to three files called READ, WRITE, and FSYNC.
|
||||
* Each one of these optional files contains the name of a single file on the device disk which
|
||||
* will cause an IO error on the first call of the appropriate I/O action to that file.
|
||||
*
|
||||
* Example:
|
||||
* ota.zip
|
||||
@@ -29,9 +29,9 @@
|
||||
* .libotafault
|
||||
* WRITE
|
||||
*
|
||||
* If the contents of the file WRITE were /system/build.prop, the first write
|
||||
* action to /system/build.prop would fail with EIO. Note that READ and
|
||||
* FSYNC files are absent, so these actions will not cause an error.
|
||||
* If the contents of the file WRITE were /system/build.prop, the first write action to
|
||||
* /system/build.prop would fail with EIO. Note that READ and FSYNC files are absent, so these
|
||||
* actions will not cause an error.
|
||||
*/
|
||||
|
||||
#ifndef _UPDATER_OTA_IO_CFG_H_
|
||||
@@ -39,8 +39,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ziparchive/zip_archive.h>
|
||||
|
||||
#define OTAIO_BASE_DIR ".libotafault"
|
||||
@@ -23,8 +23,9 @@
|
||||
#ifndef _UPDATER_OTA_IO_H_
|
||||
#define _UPDATER_OTA_IO_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/stat.h> // mode_t
|
||||
|
||||
#include <memory>
|
||||
|
||||
+5
-3
@@ -14,20 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ota_io.h"
|
||||
#include "otafault/ota_io.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <android-base/thread_annotations.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "otafault/config.h"
|
||||
|
||||
static std::mutex filename_mutex;
|
||||
static std::map<intptr_t, const char*> filename_cache GUARDED_BY(filename_mutex);
|
||||
|
||||
+3
-2
@@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ota_io.h"
|
||||
#include "otafault/ota_io.h"
|
||||
|
||||
int main(int /* argc */, char** /* argv */) {
|
||||
int fd = open("testdata/test.file", O_RDWR);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -68,8 +69,27 @@ void load_volume_table() {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Finds the volume specified by the given path. fs_mgr_get_entry_for_mount_point() does exact match
|
||||
// only, so it attempts the prefixes recursively (e.g. "/cache/recovery/last_log",
|
||||
// "/cache/recovery", "/cache", "/" for a given path of "/cache/recovery/last_log") and returns the
|
||||
// first match or nullptr.
|
||||
Volume* volume_for_path(const char* path) {
|
||||
return fs_mgr_get_entry_for_mount_point(fstab, path);
|
||||
if (path == nullptr || path[0] == '\0') return nullptr;
|
||||
std::string str(path);
|
||||
while (true) {
|
||||
Volume* result = fs_mgr_get_entry_for_mount_point(fstab, str.c_str());
|
||||
if (result != nullptr || str == "/") {
|
||||
return result;
|
||||
}
|
||||
size_t slash = str.find_last_of('/');
|
||||
if (slash == std::string::npos) return nullptr;
|
||||
if (slash == 0) {
|
||||
str = "/";
|
||||
} else {
|
||||
str = str.substr(0, slash);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Mount the volume specified by path at the given mount_point.
|
||||
@@ -178,16 +198,22 @@ static int exec_cmd(const std::vector<std::string>& args) {
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
static ssize_t get_file_size(int fd, uint64_t reserve_len) {
|
||||
static int64_t get_file_size(int fd, uint64_t reserve_len) {
|
||||
struct stat buf;
|
||||
int ret = fstat(fd, &buf);
|
||||
if (ret) return 0;
|
||||
|
||||
ssize_t computed_size;
|
||||
int64_t computed_size;
|
||||
if (S_ISREG(buf.st_mode)) {
|
||||
computed_size = buf.st_size - reserve_len;
|
||||
} else if (S_ISBLK(buf.st_mode)) {
|
||||
computed_size = get_block_device_size(fd) - reserve_len;
|
||||
uint64_t block_device_size = get_block_device_size(fd);
|
||||
if (block_device_size < reserve_len ||
|
||||
block_device_size > std::numeric_limits<int64_t>::max()) {
|
||||
computed_size = 0;
|
||||
} else {
|
||||
computed_size = block_device_size - reserve_len;
|
||||
}
|
||||
} else {
|
||||
computed_size = 0;
|
||||
}
|
||||
@@ -231,13 +257,13 @@ int format_volume(const char* volume, const char* directory) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
ssize_t length = 0;
|
||||
int64_t length = 0;
|
||||
if (v->length != 0) {
|
||||
length = v->length;
|
||||
} else if (v->key_loc != nullptr && strcmp(v->key_loc, "footer") == 0) {
|
||||
android::base::unique_fd fd(open(v->blk_device, O_RDONLY));
|
||||
if (fd == -1) {
|
||||
PLOG(ERROR) << "get_file_size: failed to open " << v->blk_device;
|
||||
PLOG(ERROR) << "format_volume: failed to open " << v->blk_device;
|
||||
return -1;
|
||||
}
|
||||
length = get_file_size(fd.get(), CRYPT_FOOTER_OFFSET);
|
||||
|
||||
+1
-1
@@ -143,7 +143,6 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libdivsufsort \
|
||||
libdivsufsort64 \
|
||||
libfs_mgr \
|
||||
liblog \
|
||||
libvintf_recovery \
|
||||
libvintf \
|
||||
libtinyxml2 \
|
||||
@@ -154,6 +153,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcrypto \
|
||||
libbz \
|
||||
libziparchive \
|
||||
liblog \
|
||||
libutils \
|
||||
libz \
|
||||
libbase \
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#include "edify/expr.h"
|
||||
#include "error_code.h"
|
||||
#include "ota_io.h"
|
||||
#include "otafault/ota_io.h"
|
||||
#include "print_sha1.h"
|
||||
#include "rangeset.h"
|
||||
#include "updater/install.h"
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@
|
||||
#include "edify/expr.h"
|
||||
#include "error_code.h"
|
||||
#include "mounts.h"
|
||||
#include "ota_io.h"
|
||||
#include "otafault/ota_io.h"
|
||||
#include "otautil/DirUtil.h"
|
||||
#include "print_sha1.h"
|
||||
#include "tune2fs.h"
|
||||
|
||||
+1
-1
@@ -30,8 +30,8 @@
|
||||
#include <selinux/selinux.h>
|
||||
#include <ziparchive/zip_archive.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "edify/expr.h"
|
||||
#include "otafault/config.h"
|
||||
#include "otautil/DirUtil.h"
|
||||
#include "otautil/SysUtil.h"
|
||||
#include "updater/blockimg.h"
|
||||
|
||||
Reference in New Issue
Block a user