android4.4修改Recovery动画(包含恢复出厂部分)

修改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)

最后,区别恢复出厂设置和系统升级的背景动画(遇到的问题是虽然逻辑上做了区分,但是恢复出厂也始终显示升级的动画)。解决方式见上段代码的红色注释行。


至此,动画修改工作完成。


你可能感兴趣的:(Android)