Merge "Add a new option in recovery menu to test the background texts"

This commit is contained in:
Tianjie Xu
2017-09-27 17:39:05 +00:00
committed by Gerrit Code Review
7 changed files with 153 additions and 21 deletions
+23 -21
View File
@@ -17,34 +17,36 @@
#include "device.h" #include "device.h"
static const char* MENU_ITEMS[] = { static const char* MENU_ITEMS[] = {
"Reboot system now", "Reboot system now",
"Reboot to bootloader", "Reboot to bootloader",
"Apply update from ADB", "Apply update from ADB",
"Apply update from SD card", "Apply update from SD card",
"Wipe data/factory reset", "Wipe data/factory reset",
#ifndef AB_OTA_UPDATER #ifndef AB_OTA_UPDATER
"Wipe cache partition", "Wipe cache partition",
#endif // !AB_OTA_UPDATER #endif // !AB_OTA_UPDATER
"Mount /system", "Mount /system",
"View recovery logs", "View recovery logs",
"Run graphics test", "Run graphics test",
"Power off", "Run locale test",
NULL, "Power off",
nullptr,
}; };
static const Device::BuiltinAction MENU_ACTIONS[] = { static const Device::BuiltinAction MENU_ACTIONS[] = {
Device::REBOOT, Device::REBOOT,
Device::REBOOT_BOOTLOADER, Device::REBOOT_BOOTLOADER,
Device::APPLY_ADB_SIDELOAD, Device::APPLY_ADB_SIDELOAD,
Device::APPLY_SDCARD, Device::APPLY_SDCARD,
Device::WIPE_DATA, Device::WIPE_DATA,
#ifndef AB_OTA_UPDATER #ifndef AB_OTA_UPDATER
Device::WIPE_CACHE, Device::WIPE_CACHE,
#endif // !AB_OTA_UPDATER #endif // !AB_OTA_UPDATER
Device::MOUNT_SYSTEM, Device::MOUNT_SYSTEM,
Device::VIEW_RECOVERY_LOGS, Device::VIEW_RECOVERY_LOGS,
Device::RUN_GRAPHICS_TEST, Device::RUN_GRAPHICS_TEST,
Device::SHUTDOWN, Device::RUN_LOCALE_TEST,
Device::SHUTDOWN,
}; };
static_assert(sizeof(MENU_ITEMS) / sizeof(MENU_ITEMS[0]) == static_assert(sizeof(MENU_ITEMS) / sizeof(MENU_ITEMS[0]) ==
+1
View File
@@ -66,6 +66,7 @@ class Device {
VIEW_RECOVERY_LOGS = 9, VIEW_RECOVERY_LOGS = 9,
MOUNT_SYSTEM = 10, MOUNT_SYSTEM = 10,
RUN_GRAPHICS_TEST = 11, RUN_GRAPHICS_TEST = 11,
RUN_LOCALE_TEST = 12,
}; };
// Return the list of menu items (an array of strings, NULL-terminated). The menu_position passed // Return the list of menu items (an array of strings, NULL-terminated). The menu_position passed
+4
View File
@@ -21,6 +21,7 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include <vector>
// //
// Graphics. // Graphics.
@@ -129,6 +130,9 @@ int res_create_alpha_surface(const char* name, GRSurface** pSurface);
int res_create_localized_alpha_surface(const char* name, const char* locale, int res_create_localized_alpha_surface(const char* name, const char* locale,
GRSurface** pSurface); GRSurface** pSurface);
// Return a list of locale strings embedded in |png_name|. Return a empty list in case of failure.
std::vector<std::string> get_locales_in_png(const std::string& png_name);
// Free a surface allocated by any of the res_create_*_surface() // Free a surface allocated by any of the res_create_*_surface()
// functions. // functions.
void res_free_surface(GRSurface* surface); void res_free_surface(GRSurface* surface);
+35
View File
@@ -396,6 +396,41 @@ bool matches_locale(const std::string& prefix, const std::string& locale) {
return std::regex_match(locale, loc_regex); return std::regex_match(locale, loc_regex);
} }
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());
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);
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);
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_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
return result;
}
int res_create_localized_alpha_surface(const char* name, int res_create_localized_alpha_surface(const char* name,
const char* locale, const char* locale,
GRSurface** pSurface) { GRSurface** pSurface) {
+5
View File
@@ -1191,6 +1191,11 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
run_graphics_test(); run_graphics_test();
break; break;
case Device::RUN_LOCALE_TEST: {
ScreenRecoveryUI* screen_ui = static_cast<ScreenRecoveryUI*>(ui);
screen_ui->CheckBackgroundTextImages(locale);
break;
}
case Device::MOUNT_SYSTEM: case Device::MOUNT_SYSTEM:
// For a system image built with the root directory (i.e. system_root_image == "true"), we // For a system image built with the root directory (i.e. system_root_image == "true"), we
// mount it to /system_root, and symlink /system to /system_root/system to make adb shell // mount it to /system_root, and symlink /system to /system_root/system to make adb shell
+77
View File
@@ -31,7 +31,9 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include <android-base/logging.h> #include <android-base/logging.h>
@@ -258,6 +260,81 @@ void ScreenRecoveryUI::SetColor(UIElement e) const {
} }
} }
void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector<std::string>& locales_entries,
size_t sel) {
SetLocale(locales_entries[sel]);
std::vector<std::string> text_name = { "erasing_text", "error_text", "installing_text",
"installing_security_text", "no_command_text" };
std::unordered_map<std::string, std::unique_ptr<GRSurface, decltype(&free)>> surfaces;
for (const auto& name : text_name) {
GRSurface* text_image = nullptr;
LoadLocalizedBitmap(name.c_str(), &text_image);
if (!text_image) {
Print("Failed to load %s\n", name.c_str());
return;
}
surfaces.emplace(name, std::unique_ptr<GRSurface, decltype(&free)>(text_image, &free));
}
pthread_mutex_lock(&updateMutex);
gr_color(0, 0, 0, 255);
gr_clear();
int text_y = kMarginHeight;
int text_x = kMarginWidth;
int line_spacing = gr_sys_font()->char_height; // Put some extra space between images.
// Write the header and descriptive texts.
SetColor(INFO);
std::string header = "Show background text image";
text_y += DrawTextLine(text_x, text_y, header.c_str(), true);
std::string locale_selection = android::base::StringPrintf(
"Current locale: %s, %zu/%zu", locales_entries[sel].c_str(), sel, locales_entries.size());
const char* instruction[] = { locale_selection.c_str(),
"Use volume up/down to switch locales and power to exit.",
nullptr };
text_y += DrawWrappedTextLines(text_x, text_y, instruction);
// Iterate through the text images and display them in order for the current locale.
for (const auto& p : surfaces) {
text_y += line_spacing;
SetColor(LOG);
text_y += DrawTextLine(text_x, text_y, p.first.c_str(), false);
gr_color(255, 255, 255, 255);
gr_texticon(text_x, text_y, p.second.get());
text_y += gr_get_height(p.second.get());
}
// Update the whole screen.
gr_flip();
pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::CheckBackgroundTextImages(const std::string& saved_locale) {
// Load a list of locales embedded in one of the resource files.
std::vector<std::string> locales_entries = get_locales_in_png("installing_text");
if (locales_entries.empty()) {
Print("Failed to load locales from the resource files\n");
return;
}
size_t selected = 0;
SelectAndShowBackgroundText(locales_entries, selected);
FlushKeys();
while (true) {
int key = WaitKey();
if (key == KEY_POWER || key == KEY_ENTER) {
break;
} else if (key == KEY_UP || key == KEY_VOLUMEUP) {
selected = (selected == 0) ? locales_entries.size() - 1 : selected - 1;
SelectAndShowBackgroundText(locales_entries, selected);
} else if (key == KEY_DOWN || key == KEY_VOLUMEDOWN) {
selected = (selected == locales_entries.size() - 1) ? 0 : selected + 1;
SelectAndShowBackgroundText(locales_entries, selected);
}
}
SetLocale(saved_locale);
}
int ScreenRecoveryUI::DrawHorizontalRule(int y) const { int ScreenRecoveryUI::DrawHorizontalRule(int y) const {
gr_fill(0, y + 4, gr_fb_width(), y + 6); gr_fill(0, y + 4, gr_fb_width(), y + 6);
return 8; return 8;
+8
View File
@@ -80,6 +80,10 @@ class ScreenRecoveryUI : public RecoveryUI {
void SetColor(UIElement e) const; void SetColor(UIElement e) const;
// Check the background text image. Use volume up/down button to cycle through the locales
// embedded in the png file, and power button to go back to recovery main menu.
void CheckBackgroundTextImages(const std::string& saved_locale);
protected: protected:
// The margin that we don't want to use for showing texts (e.g. round screen, or screen with // The margin that we don't want to use for showing texts (e.g. round screen, or screen with
// rounded corners). // rounded corners).
@@ -199,6 +203,10 @@ class ScreenRecoveryUI : public RecoveryUI {
private: private:
void SetLocale(const std::string&); void SetLocale(const std::string&);
// Display the background texts for "erasing", "error", "no_command" and "installing" for the
// selected locale.
void SelectAndShowBackgroundText(const std::vector<std::string>& locales_entries, size_t sel);
}; };
#endif // RECOVERY_UI_H #endif // RECOVERY_UI_H