recovery: Fix the broken UI text.

UI text is broken (doesn't show any text during FDR) due to commit
d530449e54, which reordered the calls to
RecoveryUI::SetLocale() and RecoveryUI::Init().

Because Init() uses the locale info to load the localized texts (from
images), the locale must be set prior to that via SetLocale(). This CL
refactors Init() to take the locale parameter, and removes the odd
SetLocale() API.

Bug: 34029338
Test: 'Run graphics test' under recovery.
Change-Id: I620394a3d4e3705e9af5a1f6299285d143ae1b01
This commit is contained in:
Tao Bao 2017-01-03 10:15:33 -08:00
parent 71633ebfb0
commit 736d59c567
9 changed files with 238 additions and 230 deletions

View file

@ -1506,11 +1506,10 @@ int main(int argc, char **argv) {
Device* device = make_device();
ui = device->GetUI();
if (!ui->Init()) {
if (!ui->Init(locale)) {
printf("Failed to initialize UI, use stub UI instead.");
ui = new StubRecoveryUI();
}
ui->SetLocale(locale.c_str());
// Set background string to "installing security update" for security update,
// otherwise set it to "installing system update".
ui->SetSystemUpdateText(security_update);

View file

@ -29,6 +29,7 @@
#include <time.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <android-base/logging.h>
@ -51,9 +52,8 @@ static double now() {
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
ScreenRecoveryUI::ScreenRecoveryUI() :
currentIcon(NONE),
locale(nullptr),
ScreenRecoveryUI::ScreenRecoveryUI()
: currentIcon(NONE),
progressBarType(EMPTY),
progressScopeStart(0),
progressScopeSize(0),
@ -79,9 +79,7 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
animation_fps(30), // TODO: there's currently no way to infer this.
stage(-1),
max_stage(-1),
updateMutex(PTHREAD_MUTEX_INITIALIZER),
rtl_locale(false) {
}
updateMutex(PTHREAD_MUTEX_INITIALIZER) {}
GRSurface* ScreenRecoveryUI::GetCurrentFrame() {
if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
@ -197,13 +195,13 @@ void ScreenRecoveryUI::draw_foreground_locked() {
if (progressBarType == DETERMINATE) {
float p = progressScopeStart + progress * progressScopeSize;
int pos = (int) (p * width);
int pos = static_cast<int>(p * width);
if (rtl_locale) {
if (rtl_locale_) {
// Fill the progress bar from right to left.
if (pos > 0) {
gr_blit(progressBarFill, width-pos, 0, pos, height,
progress_x+width-pos, progress_y);
gr_blit(progressBarFill, width - pos, 0, pos, height, progress_x + width - pos,
progress_y);
}
if (pos < width - 1) {
gr_blit(progressBarEmpty, 0, 0, width - pos, height, progress_x, progress_y);
@ -214,8 +212,7 @@ void ScreenRecoveryUI::draw_foreground_locked() {
gr_blit(progressBarFill, 0, 0, pos, height, progress_x, progress_y);
}
if (pos < width - 1) {
gr_blit(progressBarEmpty, pos, 0, width-pos, height,
progress_x+pos, progress_y);
gr_blit(progressBarEmpty, pos, 0, width - pos, height, progress_x + pos, progress_y);
}
}
}
@ -423,7 +420,7 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) {
}
void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, GRSurface** surface) {
int result = res_create_localized_alpha_surface(filename, locale, surface);
int result = res_create_localized_alpha_surface(filename, locale_.c_str(), surface);
if (result < 0) {
LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")";
}
@ -459,8 +456,8 @@ bool ScreenRecoveryUI::InitTextParams() {
return true;
}
bool ScreenRecoveryUI::Init() {
RecoveryUI::Init();
bool ScreenRecoveryUI::Init(const std::string& locale) {
RecoveryUI::Init(locale);
if (!InitTextParams()) {
return false;
}
@ -539,31 +536,6 @@ void ScreenRecoveryUI::LoadAnimation() {
}
}
void ScreenRecoveryUI::SetLocale(const char* new_locale) {
this->locale = new_locale;
this->rtl_locale = false;
if (locale) {
char* lang = strdup(locale);
for (char* p = lang; *p; ++p) {
if (*p == '_') {
*p = '\0';
break;
}
}
// A bit cheesy: keep an explicit list of supported RTL languages.
if (strcmp(lang, "ar") == 0 || // Arabic
strcmp(lang, "fa") == 0 || // Persian (Farsi)
strcmp(lang, "he") == 0 || // Hebrew (new language code)
strcmp(lang, "iw") == 0 || // Hebrew (old language code)
strcmp(lang, "ur") == 0) { // Urdu
rtl_locale = true;
}
free(lang);
}
}
void ScreenRecoveryUI::SetBackground(Icon icon) {
pthread_mutex_lock(&updateMutex);

View file

@ -20,6 +20,8 @@
#include <pthread.h>
#include <stdio.h>
#include <string>
#include "ui.h"
#include "minui/minui.h"
@ -29,8 +31,7 @@ class ScreenRecoveryUI : public RecoveryUI {
public:
ScreenRecoveryUI();
bool Init() override;
void SetLocale(const char* locale);
bool Init(const std::string& locale) override;
// overall recovery state ("background image")
void SetBackground(Icon icon);
@ -71,8 +72,6 @@ class ScreenRecoveryUI : public RecoveryUI {
protected:
Icon currentIcon;
const char* locale;
// The scale factor from dp to pixels. 1.0 for mdpi, 4.0 for xxxhdpi.
float density_;
// The layout to use.
@ -135,7 +134,6 @@ class ScreenRecoveryUI : public RecoveryUI {
int char_width_;
int char_height_;
pthread_mutex_t updateMutex;
bool rtl_locale;
virtual bool InitTextParams();

View file

@ -24,8 +24,6 @@ class StubRecoveryUI : public RecoveryUI {
public:
StubRecoveryUI() = default;
void SetLocale(const char* locale) override {}
void SetBackground(Icon icon) override {}
void SetSystemUpdateText(bool security_update) override {}

View file

@ -40,38 +40,44 @@
RecoveryUI* ui = NULL;
class MockUI : public RecoveryUI {
bool Init() { return true; }
void SetStage(int, int) { }
void SetLocale(const char*) { }
void SetBackground(Icon /*icon*/) { }
void SetSystemUpdateText(bool /*security_update*/) { }
bool Init(const std::string&) override {
return true;
}
void SetStage(int, int) override {}
void SetBackground(Icon /*icon*/) override {}
void SetSystemUpdateText(bool /*security_update*/) override {}
void SetProgressType(ProgressType /*determinate*/) { }
void ShowProgress(float /*portion*/, float /*seconds*/) { }
void SetProgress(float /*fraction*/) { }
void SetProgressType(ProgressType /*determinate*/) override {}
void ShowProgress(float /*portion*/, float /*seconds*/) override {}
void SetProgress(float /*fraction*/) override {}
void ShowText(bool /*visible*/) { }
bool IsTextVisible() { return false; }
bool WasTextEverVisible() { return false; }
void Print(const char* fmt, ...) {
void ShowText(bool /*visible*/) override {}
bool IsTextVisible() override {
return false;
}
bool WasTextEverVisible() override {
return false;
}
void Print(const char* fmt, ...) override {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void PrintOnScreenOnly(const char* fmt, ...) {
void PrintOnScreenOnly(const char* fmt, ...) override {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void ShowFile(const char*) { }
void ShowFile(const char*) override {}
void StartMenu(const char* const* /*headers*/,
const char* const* /*items*/,
int /*initial_selection*/) { }
int SelectMenu(int /*sel*/) { return 0; }
void EndMenu() { }
void StartMenu(const char* const* /*headers*/, const char* const* /*items*/,
int /*initial_selection*/) override {}
int SelectMenu(int /*sel*/) override {
return 0;
}
void EndMenu() override {}
};
void

35
ui.cpp
View file

@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "ui.h"
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
@ -28,6 +30,8 @@
#include <time.h>
#include <unistd.h>
#include <string>
#include <android-base/properties.h>
#include <cutils/android_reboot.h>
@ -35,13 +39,13 @@
#include "roots.h"
#include "device.h"
#include "minui/minui.h"
#include "screen_ui.h"
#include "ui.h"
#define UI_WAIT_KEY_TIMEOUT_SEC 120
RecoveryUI::RecoveryUI()
: key_queue_len(0),
: locale_(""),
rtl_locale_(false),
key_queue_len(0),
key_last_down(-1),
key_long_press(false),
key_down_count(0),
@ -80,7 +84,10 @@ static void* InputThreadLoop(void*) {
return nullptr;
}
bool RecoveryUI::Init() {
bool RecoveryUI::Init(const std::string& locale) {
// Set up the locale info.
SetLocale(locale);
ev_init(InputCallback, this);
ev_iterate_available_keys(std::bind(&RecoveryUI::OnKeyDetected, this, std::placeholders::_1));
@ -338,3 +345,23 @@ void RecoveryUI::SetEnableReboot(bool enabled) {
enable_reboot = enabled;
pthread_mutex_unlock(&key_queue_mutex);
}
void RecoveryUI::SetLocale(const std::string& new_locale) {
this->locale_ = new_locale;
this->rtl_locale_ = false;
if (!new_locale.empty()) {
size_t underscore = new_locale.find('_');
// lang has the language prefix prior to '_', or full string if '_' doesn't exist.
std::string lang = new_locale.substr(0, underscore);
// A bit cheesy: keep an explicit list of supported RTL languages.
if (lang == "ar" || // Arabic
lang == "fa" || // Persian (Farsi)
lang == "he" || // Hebrew (new language code)
lang == "iw" || // Hebrew (old language code)
lang == "ur") { // Urdu
rtl_locale_ = true;
}
}
}

17
ui.h
View file

@ -21,6 +21,8 @@
#include <pthread.h>
#include <time.h>
#include <string>
// Abstract class for controlling the user interface during recovery.
class RecoveryUI {
public:
@ -28,14 +30,13 @@ class RecoveryUI {
virtual ~RecoveryUI() { }
// Initialize the object; called before anything else. Returns true on success.
virtual bool Init();
// Initialize the object; called before anything else. UI texts will be
// initialized according to the given locale. Returns true on success.
virtual bool Init(const std::string& locale);
// Show a stage indicator. Call immediately after Init().
virtual void SetStage(int current, int max) = 0;
// After calling Init(), you can tell the UI what locale it is operating in.
virtual void SetLocale(const char* locale) = 0;
// Set the overall recovery state ("background image").
enum Icon { NONE, INSTALLING_UPDATE, ERASING, NO_COMMAND, ERROR };
virtual void SetBackground(Icon icon) = 0;
@ -125,6 +126,10 @@ class RecoveryUI {
protected:
void EnqueueKey(int key_code);
// The locale that's used to show the rendered texts.
std::string locale_;
bool rtl_locale_;
private:
// Key event input queue
pthread_mutex_t key_queue_mutex;
@ -162,6 +167,8 @@ private:
static void* time_key_helper(void* cookie);
void time_key(int key_code, int count);
void SetLocale(const std::string&);
};
#endif // RECOVERY_UI_H

View file

@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "wear_ui.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
@ -25,11 +27,11 @@
#include <time.h>
#include <unistd.h>
#include <string>
#include <vector>
#include "common.h"
#include "device.h"
#include "wear_ui.h"
#include "android-base/properties.h"
#include "android-base/strings.h"
#include "android-base/stringprintf.h"
@ -204,8 +206,8 @@ bool WearRecoveryUI::InitTextParams() {
return true;
}
bool WearRecoveryUI::Init() {
if (!ScreenRecoveryUI::Init()) {
bool WearRecoveryUI::Init(const std::string& locale) {
if (!ScreenRecoveryUI::Init(locale)) {
return false;
}
@ -218,12 +220,9 @@ bool WearRecoveryUI::Init() {
return true;
}
void WearRecoveryUI::SetStage(int current, int max)
{
}
void WearRecoveryUI::SetStage(int current, int max) {}
void WearRecoveryUI::Print(const char *fmt, ...)
{
void WearRecoveryUI::Print(const char* fmt, ...) {
char buf[256];
va_list ap;
va_start(ap, fmt);

View file

@ -19,11 +19,13 @@
#include "screen_ui.h"
#include <string>
class WearRecoveryUI : public ScreenRecoveryUI {
public:
WearRecoveryUI();
bool Init() override;
bool Init(const std::string& locale) override;
void SetStage(int current, int max) override;