修改android原生的丑陋绿巨人,改为适合自己产品的动画。
首先,将recovery模式的log定位到串口,方便调试,修改recovery.cpp的mian函数,将如下两行
freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
替换为
mknod("/dev/__kmsg__", S_IFCHR | 0600, (1 << 8) | 11);
freopen("/dev/__kmsg__", "a", stdout); setbuf(stdout, NULL);
freopen("/dev/__kmsg__", "a", stderr); setbuf(stderr, NULL);
unlink("/dev/__kmsg__");
则串口即可出recovery过程中的log。
其次,本次调换初选方案是只修改动画,text和progressbar做适配调试。但由于产品硬件的LCD初始是按竖屏设计的,后在软件层面改为横屏显示,而系统在recovery阶段,android的系统资源几乎都没启动,recovery仅仅算是linux内核上跑起来的一个linux应用程序,这就使适配原生的text和progressbar方案显得不易实现。退而求其次,选择了将text做到每一帧动画图片中,将每一帧当做overlay去刷surface。
再次,当前系统中有三种输入法,需要recovery模式去做相应适配。这就要求setLocale方法提前调用。
diff --git a/recovery.cpp b/recovery.cpp
index 4f7078e..4ab16c9 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -1085,6 +1084,7 @@ main(int argc, char **argv) {
ui = device->GetUI();
gCurrentUI = ui;
+ ui->SetLocale(locale);
ui->Init();
int st_cur, st_max;
@@ -1092,9 +1092,8 @@ main(int argc, char **argv) {
ui->SetStage(st_cur, st_max);
}
- ui->SetLocale(locale);
ui->SetBackground(RecoveryUI::NONE);
以下是对动画部分的修改处理:
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 09a6d45..5bfd28a 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -37,6 +37,12 @@
static int char_width;
static int char_height;
+static int img_flag = NULL;
+
+#define ENGLISH_DEFAULT 1
+#define SIMPLIFY 2
+#define TRADITIONAL 3
+
// There's only (at most) one of these objects, and global callbacks
// (for pthread_create, and the input event system) need to find it,
// so use a global variable.
@@ -76,8 +82,8 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
// that overrides Init() to set these values appropriately and
// then call the superclass Init().
animation_fps(20),
- indeterminate_frames(6),
- installing_frames(7),
+ indeterminate_frames(5),
+ installing_frames(5),
install_overlay_offset_x(13),
install_overlay_offset_y(190),
overlay_offset_x(-1),
@@ -100,10 +106,14 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
void ScreenRecoveryUI::draw_install_overlay_locked(int frame) {
if (installationOverlay == NULL || overlay_offset_x < 0) return;
gr_surface surface = installationOverlay[frame];
+
int iconWidth = gr_get_width(surface);
int iconHeight = gr_get_height(surface);
- gr_blit(surface, 0, 0, iconWidth, iconHeight,
- overlay_offset_x, overlay_offset_y);
+ int stageHeight = gr_get_height(stageMarkerEmpty);
+
+ int iconX = (gr_fb_width() - (iconWidth+50)) / 2;
+ int iconY = (gr_fb_height() - iconHeight) / 2;
+ gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY);
}
// Clear the screen and draw the currently selected background icon (if any).
@@ -126,8 +136,8 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon)
int sh = (max_stage >= 0) ? stageHeight : 0;
- int iconX = (gr_fb_width() - iconWidth) / 2;
- int iconY = (gr_fb_height() - (iconHeight+textHeight+40+sh)) / 2;
+ int iconX = (gr_fb_width() - (iconWidth+50)) / 2;
+ int iconY = (gr_fb_height() - iconHeight) / 2;
int textX = (gr_fb_width() - textWidth) / 2;
int textY = ((gr_fb_height() - (iconHeight+textHeight+40+sh)) / 2) + iconHeight + 40;
@@ -144,12 +154,14 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon)
}
}
- if (icon == INSTALLING_UPDATE || icon == ERASING) {
+ if (icon == INSTALLING_UPDATE) {
+ draw_install_overlay_locked(installingFrame);
+ } else if (icon == ERASING) {
+ installationOverlay = progressBarIndeterminate;//解决两者动画重叠的问题
draw_install_overlay_locked(installingFrame);
}
gr_color(255, 255, 255, 255);
- gr_texticon(textX, textY, text_surface);
}
}
@@ -159,7 +171,10 @@ void ScreenRecoveryUI::draw_progress_locked()
{
if (currentIcon == ERROR) return;
- if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
+ if (currentIcon == INSTALLING_UPDATE) {
+ draw_install_overlay_locked(installingFrame);
+ } else if (currentIcon == ERASING) {
+ installationOverlay = progressBarIndeterminate;//解决两者动画重叠的问题
draw_install_overlay_locked(installingFrame);
}
@@ -353,14 +368,17 @@ void ScreenRecoveryUI::progress_loop() {
}
}
- if (redraw) update_progress_locked();
+ if (redraw) {
+ update_progress_locked();
+ update_screen_locked();
+ }
pthread_mutex_unlock(&updateMutex);
double end = now();
// minimum of 20ms delay between frames
double delay = interval - (end-start);
if (delay < 0.02) delay = 0.02;
- usleep((long)(delay * 1000000));
+ usleep((long)(300000));
}
}
@@ -392,9 +410,19 @@ void ScreenRecoveryUI::Init()
text_cols = gr_fb_width() / char_width;
if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1;
- LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]);
- backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
- LoadBitmap("icon_error", &backgroundIcon[ERROR]);
+ if (img_flag == ENGLISH_DEFAULT) {
+ LoadBitmap("icon_error", &backgroundIcon[ERROR]);
+ LoadBitmap("indeterminate", &backgroundIcon[ERASING]);
+ LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]);
+ } else if (img_flag == SIMPLIFY) {
+ LoadBitmap("icon_error_zh", &backgroundIcon[ERROR]);
+ LoadBitmap("indeterminate_zh", &backgroundIcon[ERASING]);
+ LoadBitmap("icon_installing_zh", &backgroundIcon[INSTALLING_UPDATE]);
+ } else if (img_flag == TRADITIONAL) {
+ LoadBitmap("icon_error_tw", &backgroundIcon[ERROR]);
+ LoadBitmap("indeterminate_tw", &backgroundIcon[ERASING]);
+ LoadBitmap("icon_installing_tw", &backgroundIcon[INSTALLING_UPDATE]);
+ }
backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR];
LoadBitmap("progress_empty", &progressBarEmpty);
@@ -414,7 +442,14 @@ void ScreenRecoveryUI::Init()
for (i = 0; i < indeterminate_frames; ++i) {
char filename[40];
// "indeterminate01.png", "indeterminate02.png", ...
- sprintf(filename, "indeterminate%02d", i+1);
+ //sprintf(filename, "indeterminate%02d", i+1);//对应恢复出厂设置的PNG图片,默认en,._zh为中文简体,*_tw为繁体中文
+ if (img_flag == ENGLISH_DEFAULT)
+ sprintf(filename, "indeterminate%02d", i+1);
+ else if (img_flag == SIMPLIFY)
+ sprintf(filename, "indeterminate_zh%02d", i+1);
+ else if (img_flag == TRADITIONAL)
+ sprintf(filename, "indeterminate_tw%02d", i+1);
+
LoadBitmap(filename, progressBarIndeterminate+i);
}
@@ -425,7 +460,13 @@ void ScreenRecoveryUI::Init()
char filename[40];
// "icon_installing_overlay01.png",
// "icon_installing_overlay02.png", ...
- sprintf(filename, "icon_installing_overlay%02d", i+1);
+ if (img_flag == ENGLISH_DEFAULT)
+ sprintf(filename, "icon_installing_overlay%02d", i+1);//对应OTA升级的PNG图片,默认en,._zh为中文简体,*_tw为繁体中文
+ else if (img_flag == SIMPLIFY)
+ sprintf(filename, "icon_installing_overlay_zh%02d", i+1);
+ else if (img_flag == TRADITIONAL)
+ sprintf(filename, "icon_installing_overlay_tw%02d", i+1);
+
LoadBitmap(filename, installationOverlay+i);
}
} else {
@@ -438,6 +479,10 @@ void ScreenRecoveryUI::Init()
}
void ScreenRecoveryUI::SetLocale(const char* locale) {
+ const char* locale_en = "en_US";
+ const char* locale_zh = "zh_CN";
+ const char* locale_tw = "zh_TW";
+
} else {
@@ -438,6 +479,10 @@ void ScreenRecoveryUI::Init()
}
void ScreenRecoveryUI::SetLocale(const char* locale) {
+ const char* locale_en = "en_US";
+ const char* locale_zh = "zh_CN";
+ const char* locale_tw = "zh_TW";
+
if (locale) {
char* lang = strdup(locale);
for (char* p = lang; *p; ++p) {
@@ -458,6 +503,15 @@ void ScreenRecoveryUI::SetLocale(const char* locale) {
}
free(lang);
}
+
+ if (locale == NULL || strstr(locale, locale_en))
+ img_flag = ENGLISH_DEFAULT;
+ else if (strstr(locale, locale_zh))
+ img_flag = SIMPLIFY;
+ else if (strstr(locale, locale_tw))
+ img_flag = TRADITIONAL;
+ else
+ img_flag = ENGLISH_DEFAULT;
}
void ScreenRecoveryUI::SetBackground(Icon icon)
最后,区别恢复出厂设置和系统升级的背景动画(遇到的问题是虽然逻辑上做了区分,但是恢复出厂也始终显示升级的动画)。解决方式见上段代码的红色注释行。
至此,动画修改工作完成。