Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbb00e78 authored by Nicolas Geoffray's avatar Nicolas Geoffray
Browse files

Support for showing percent progress in boot animation.

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

Change-Id: I2d936e3391f56796308c90deb39ecacc58797721
Merged-In: I2d936e3391f56796308c90deb39ecacc58797721
parent 73218cd5
Loading
Loading
Loading
Loading
+58 −2
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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);
+9 −1
Original line number Diff line number Diff line
@@ -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
+17.1 KiB
Loading image diff...