Skip to content
This repository was archived by the owner on Nov 23, 2022. It is now read-only.

Commit

Permalink
Add a new option in recovery menu to test the background texts
Browse files Browse the repository at this point in the history
Add a new option "Run locale test" to check the background text
images (i.e. texts for "erasing", "error", "no_command" and "installing"
with different locales.)

Use volume up/down button to cycle through all the locales embedded in
the png file, and power button to go back to recovery main menu.

Test: Run locale test with bullhead.
Change-Id: Ib16e119f372110cdb5e611ef497b0f9b9b418f51
  • Loading branch information
Tianjie Xu committed Sep 27, 2017
1 parent 151f082 commit 29d5575
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 21 deletions.
44 changes: 23 additions & 21 deletions device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,36 @@
#include "device.h"

static const char* MENU_ITEMS[] = {
"Reboot system now",
"Reboot to bootloader",
"Apply update from ADB",
"Apply update from SD card",
"Wipe data/factory reset",
"Reboot system now",
"Reboot to bootloader",
"Apply update from ADB",
"Apply update from SD card",
"Wipe data/factory reset",
#ifndef AB_OTA_UPDATER
"Wipe cache partition",
"Wipe cache partition",
#endif // !AB_OTA_UPDATER
"Mount /system",
"View recovery logs",
"Run graphics test",
"Power off",
NULL,
"Mount /system",
"View recovery logs",
"Run graphics test",
"Run locale test",
"Power off",
nullptr,
};

static const Device::BuiltinAction MENU_ACTIONS[] = {
Device::REBOOT,
Device::REBOOT_BOOTLOADER,
Device::APPLY_ADB_SIDELOAD,
Device::APPLY_SDCARD,
Device::WIPE_DATA,
Device::REBOOT,
Device::REBOOT_BOOTLOADER,
Device::APPLY_ADB_SIDELOAD,
Device::APPLY_SDCARD,
Device::WIPE_DATA,
#ifndef AB_OTA_UPDATER
Device::WIPE_CACHE,
Device::WIPE_CACHE,
#endif // !AB_OTA_UPDATER
Device::MOUNT_SYSTEM,
Device::VIEW_RECOVERY_LOGS,
Device::RUN_GRAPHICS_TEST,
Device::SHUTDOWN,
Device::MOUNT_SYSTEM,
Device::VIEW_RECOVERY_LOGS,
Device::RUN_GRAPHICS_TEST,
Device::RUN_LOCALE_TEST,
Device::SHUTDOWN,
};

static_assert(sizeof(MENU_ITEMS) / sizeof(MENU_ITEMS[0]) ==
Expand Down
1 change: 1 addition & 0 deletions device.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Device {
VIEW_RECOVERY_LOGS = 9,
MOUNT_SYSTEM = 10,
RUN_GRAPHICS_TEST = 11,
RUN_LOCALE_TEST = 12,
};

// Return the list of menu items (an array of strings, NULL-terminated). The menu_position passed
Expand Down
4 changes: 4 additions & 0 deletions minui/include/minui/minui.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <functional>
#include <string>
#include <vector>

//
// Graphics.
Expand Down Expand Up @@ -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,
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()
// functions.
void res_free_surface(GRSurface* surface);
Expand Down
35 changes: 35 additions & 0 deletions minui/resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,41 @@ bool matches_locale(const std::string& prefix, const std::string& locale) {
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,
const char* locale,
GRSurface** pSurface) {
Expand Down
5 changes: 5 additions & 0 deletions recovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,11 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
run_graphics_test();
break;

case Device::RUN_LOCALE_TEST: {
ScreenRecoveryUI* screen_ui = static_cast<ScreenRecoveryUI*>(ui);
screen_ui->CheckBackgroundTextImages(locale);
break;
}
case Device::MOUNT_SYSTEM:
// 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
Expand Down
77 changes: 77 additions & 0 deletions screen_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
#include <time.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include <android-base/logging.h>
Expand Down Expand Up @@ -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 {
gr_fill(0, y + 4, gr_fb_width(), y + 6);
return 8;
Expand Down
8 changes: 8 additions & 0 deletions screen_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class ScreenRecoveryUI : public RecoveryUI {

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:
// The margin that we don't want to use for showing texts (e.g. round screen, or screen with
// rounded corners).
Expand Down Expand Up @@ -199,6 +203,10 @@ class ScreenRecoveryUI : public RecoveryUI {

private:
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

0 comments on commit 29d5575

Please sign in to comment.