From bbb00e78ef87e45ffb25b9347c648a04fac00b6e Mon Sep 17 00:00:00 2001
From: Nicolas Geoffray <ngeoffray@google.com>
Date: Tue, 15 Dec 2020 10:50:29 +0000
Subject: [PATCH] Support for showing percent progress in boot animation.

Bug: 175686819
Test: boot with manual changes updating the progress

Change-Id: I2d936e3391f56796308c90deb39ecacc58797721
Merged-In: I2d936e3391f56796308c90deb39ecacc58797721
---
 cmds/bootanimation/BootAnimation.cpp     |  60 ++++++++++++++++++++++-
 cmds/bootanimation/BootAnimation.h       |   3 ++
 cmds/bootanimation/FORMAT.md             |  10 +++-
 core/res/assets/images/progress_font.png | Bin 0 -> 17515 bytes
 4 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 core/res/assets/images/progress_font.png

diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 2c7ee212b7b5..854982f825dc 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -92,6 +92,8 @@ static const char SYSTEM_TIME_DIR_NAME[] = "time";
 static const char SYSTEM_TIME_DIR_PATH[] = "/data/system/time";
 static const char CLOCK_FONT_ASSET[] = "images/clock_font.png";
 static const char CLOCK_FONT_ZIP_NAME[] = "clock_font.png";
+static const char PROGRESS_FONT_ASSET[] = "images/progress_font.png";
+static const char PROGRESS_FONT_ZIP_NAME[] = "progress_font.png";
 static const char LAST_TIME_CHANGED_FILE_NAME[] = "last_time_change";
 static const char LAST_TIME_CHANGED_FILE_PATH[] = "/data/system/time/last_time_change";
 static const char ACCURATE_TIME_FLAG_FILE_NAME[] = "time_is_accurate";
@@ -107,6 +109,7 @@ static constexpr size_t FONT_NUM_ROWS = FONT_NUM_CHARS / FONT_NUM_COLS;
 static const int TEXT_CENTER_VALUE = INT_MAX;
 static const int TEXT_MISSING_VALUE = INT_MIN;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
+static const char PROGRESS_PROP_NAME[] = "service.bootanim.progress";
 static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
 static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
 static constexpr size_t TEXT_POS_LEN_MAX = 16;
@@ -891,6 +894,18 @@ void BootAnimation::drawClock(const Font& font, const int xPos, const int yPos)
     drawText(out, font, false, &x, &y);
 }
 
+void BootAnimation::drawProgress(int percent, const Font& font, const int xPos, const int yPos) {
+    static constexpr int PERCENT_LENGTH = 5;
+
+    char percentBuff[PERCENT_LENGTH];
+    // ';' has the ascii code just after ':', and the font resource contains '%'
+    // for that ascii code.
+    sprintf(percentBuff, "%d;", percent);
+    int x = xPos;
+    int y = yPos;
+    drawText(percentBuff, font, false, &x, &y);
+}
+
 bool BootAnimation::parseAnimationDesc(Animation& animation)  {
     String8 desString;
 
@@ -910,6 +925,7 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)  {
         int height = 0;
         int count = 0;
         int pause = 0;
+        int progress = 0;
         int framesToFadeCount = 0;
         char path[ANIM_ENTRY_NAME_MAX];
         char color[7] = "000000"; // default to black if unspecified
@@ -919,11 +935,17 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)  {
 
         int nextReadPos;
 
-        if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
-            // SLOGD("> w=%d, h=%d, fps=%d", width, height, fps);
+        int topLineNumbers = sscanf(l, "%d %d %d %d", &width, &height, &fps, &progress);
+        if (topLineNumbers == 3 || topLineNumbers == 4) {
+            // SLOGD("> w=%d, h=%d, fps=%d, progress=%d", width, height, fps, progress);
             animation.width = width;
             animation.height = height;
             animation.fps = fps;
+            if (topLineNumbers == 4) {
+              animation.progressEnabled = (progress != 0);
+            } else {
+              animation.progressEnabled = false;
+            }
         } else if (sscanf(l, "%c %d %d %" STRTO(ANIM_PATH_MAX) "s%n",
                           &pathType, &count, &pause, path, &nextReadPos) >= 4) {
             if (pathType == 'f') {
@@ -1000,6 +1022,14 @@ bool BootAnimation::preloadZip(Animation& animation) {
                 continue;
             }
 
+            if (entryName == PROGRESS_FONT_ZIP_NAME) {
+                FileMap* map = zip->createEntryFileMap(entry);
+                if (map) {
+                    animation.progressFont.map = map;
+                }
+                continue;
+            }
+
             for (size_t j = 0; j < pcount; j++) {
                 if (path == animation.parts[j].path) {
                     uint16_t method;
@@ -1131,6 +1161,8 @@ bool BootAnimation::movie() {
         mClockEnabled = clockFontInitialized;
     }
 
+    initFont(&mAnimation->progressFont, PROGRESS_FONT_ASSET);
+
     if (mClockEnabled && !updateIsTimeAccurate()) {
         mTimeCheckThread = new TimeCheckThread(this);
         mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
@@ -1166,6 +1198,7 @@ bool BootAnimation::playAnimation(const Animation& animation) {
             elapsedRealtime());
 
     int fadedFramesCount = 0;
+    int lastDisplayedProgress = 0;
     for (size_t i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
         const size_t fcount = part.frames.size();
@@ -1191,6 +1224,12 @@ bool BootAnimation::playAnimation(const Animation& animation) {
                     part.backgroundColor[2],
                     1.0f);
 
+            // For the last animation, if we have progress indicator from
+            // the system, display it.
+            int currentProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);
+            bool displayProgress = animation.progressEnabled &&
+                (i == (pcount -1)) && currentProgress != 0;
+
             for (size_t j=0 ; j<fcount ; j++) {
                 if (shouldStopPlayingPart(part, fadedFramesCount)) break;
 
@@ -1248,6 +1287,23 @@ bool BootAnimation::playAnimation(const Animation& animation) {
                     drawClock(animation.clockFont, part.clockPosX, part.clockPosY);
                 }
 
+                if (displayProgress) {
+                    int newProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);
+                    // In case the new progress jumped suddenly, still show an
+                    // increment of 1.
+                    if (lastDisplayedProgress != 100) {
+                      // Artificially sleep 1/10th a second to slow down the animation.
+                      usleep(100000);
+                      if (lastDisplayedProgress < newProgress) {
+                        lastDisplayedProgress++;
+                      }
+                    }
+                    // Put the progress percentage right below the animation.
+                    int posY = animation.height / 3;
+                    int posX = TEXT_CENTER_VALUE;
+                    drawProgress(lastDisplayedProgress, animation.progressFont, posX, posY);
+                }
+
                 handleViewport(frameDuration);
 
                 eglSwapBuffers(mDisplay, mSurface);
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index aee385387f57..b52222c799b0 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -100,11 +100,13 @@ public:
         int fps;
         int width;
         int height;
+        bool progressEnabled;
         Vector<Part> parts;
         String8 audioConf;
         String8 fileName;
         ZipFileRO* zip;
         Font clockFont;
+        Font progressFont;
     };
 
     // All callbacks will be called from this class's internal thread.
@@ -168,6 +170,7 @@ private:
     bool movie();
     void drawText(const char* str, const Font& font, bool bold, int* x, int* y);
     void drawClock(const Font& font, const int xPos, const int yPos);
+    void drawProgress(int percent, const Font& font, const int xPos, const int yPos);
     void fadeFrame(int frameLeft, int frameBottom, int frameWidth, int frameHeight,
                    const Animation::Part& part, int fadedFramesCount);
     bool validClock(const Animation::Part& part);
diff --git a/cmds/bootanimation/FORMAT.md b/cmds/bootanimation/FORMAT.md
index f9b83c957d5b..1678053c48d9 100644
--- a/cmds/bootanimation/FORMAT.md
+++ b/cmds/bootanimation/FORMAT.md
@@ -22,11 +22,14 @@ The `bootanimation.zip` archive file includes:
 
 The first line defines the general parameters of the animation:
 
-    WIDTH HEIGHT FPS
+    WIDTH HEIGHT FPS [PROGRESS]
 
   * **WIDTH:** animation width (pixels)
   * **HEIGHT:** animation height (pixels)
   * **FPS:** frames per second, e.g. 60
+  * **PROGRESS:** whether to show a progress percentage on the last part
+      + The percentage will be displayed with an x-coordinate of 'c', and a
+        y-coordinate set to 1/3 of the animation height.
 
 It is followed by a number of rows of the form:
 
@@ -77,6 +80,11 @@ The file used to draw the time on top of the boot animation. The font format is
   * Each row is divided in half: regular weight glyphs on the top half, bold glyphs on the bottom
   * For a NxM image each character glyph will be N/16 pixels wide and M/(12*2) pixels high
 
+## progress_font.png
+
+The file used to draw the boot progress in percentage on top of the boot animation. The font format
+follows the same specification as the one described for clock_font.png.
+
 ## loading and playing frames
 
 Each part is scanned and loaded directly from the zip archive. Within a part directory, every file
diff --git a/core/res/assets/images/progress_font.png b/core/res/assets/images/progress_font.png
new file mode 100644
index 0000000000000000000000000000000000000000..78c3ed9cd6998f140c9dce9578ddc0ea15156043
GIT binary patch
literal 17515
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

literal 0
HcmV?d00001

-- 
GitLab