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

Commit 8bd985ef authored by Nicolas Geoffray's avatar Nicolas Geoffray Committed by Automerger Merge Worker
Browse files

Merge "Support for showing percent progress in boot animation." am: 87d840ad am: b86c3a34

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1545805

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ic4b699c54e725f6bde23d9f0123536bd2f0d6366
parents 6564036d b86c3a34
Loading
Loading
Loading
Loading
+58 −2
Original line number Original line 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 SYSTEM_TIME_DIR_PATH[] = "/data/system/time";
static const char CLOCK_FONT_ASSET[] = "images/clock_font.png";
static const char CLOCK_FONT_ASSET[] = "images/clock_font.png";
static const char CLOCK_FONT_ZIP_NAME[] = "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_NAME[] = "last_time_change";
static const char LAST_TIME_CHANGED_FILE_PATH[] = "/data/system/time/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";
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_CENTER_VALUE = INT_MAX;
static const int TEXT_MISSING_VALUE = INT_MIN;
static const int TEXT_MISSING_VALUE = INT_MIN;
static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
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 char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
static constexpr size_t TEXT_POS_LEN_MAX = 16;
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);
    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)  {
bool BootAnimation::parseAnimationDesc(Animation& animation)  {
    String8 desString;
    String8 desString;


@@ -910,6 +925,7 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
        int height = 0;
        int height = 0;
        int count = 0;
        int count = 0;
        int pause = 0;
        int pause = 0;
        int progress = 0;
        int framesToFadeCount = 0;
        int framesToFadeCount = 0;
        char path[ANIM_ENTRY_NAME_MAX];
        char path[ANIM_ENTRY_NAME_MAX];
        char color[7] = "000000"; // default to black if unspecified
        char color[7] = "000000"; // default to black if unspecified
@@ -919,11 +935,17 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {


        int nextReadPos;
        int nextReadPos;


        if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
        int topLineNumbers = sscanf(l, "%d %d %d %d", &width, &height, &fps, &progress);
            // SLOGD("> w=%d, h=%d, fps=%d", width, height, fps);
        if (topLineNumbers == 3 || topLineNumbers == 4) {
            // SLOGD("> w=%d, h=%d, fps=%d, progress=%d", width, height, fps, progress);
            animation.width = width;
            animation.width = width;
            animation.height = height;
            animation.height = height;
            animation.fps = fps;
            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",
        } else if (sscanf(l, "%c %d %d %" STRTO(ANIM_PATH_MAX) "s%n",
                          &pathType, &count, &pause, path, &nextReadPos) >= 4) {
                          &pathType, &count, &pause, path, &nextReadPos) >= 4) {
            if (pathType == 'f') {
            if (pathType == 'f') {
@@ -1000,6 +1022,14 @@ bool BootAnimation::preloadZip(Animation& animation) {
                continue;
                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++) {
            for (size_t j = 0; j < pcount; j++) {
                if (path == animation.parts[j].path) {
                if (path == animation.parts[j].path) {
                    uint16_t method;
                    uint16_t method;
@@ -1131,6 +1161,8 @@ bool BootAnimation::movie() {
        mClockEnabled = clockFontInitialized;
        mClockEnabled = clockFontInitialized;
    }
    }


    initFont(&mAnimation->progressFont, PROGRESS_FONT_ASSET);

    if (mClockEnabled && !updateIsTimeAccurate()) {
    if (mClockEnabled && !updateIsTimeAccurate()) {
        mTimeCheckThread = new TimeCheckThread(this);
        mTimeCheckThread = new TimeCheckThread(this);
        mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
        mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
@@ -1166,6 +1198,7 @@ bool BootAnimation::playAnimation(const Animation& animation) {
            elapsedRealtime());
            elapsedRealtime());


    int fadedFramesCount = 0;
    int fadedFramesCount = 0;
    int lastDisplayedProgress = 0;
    for (size_t i=0 ; i<pcount ; i++) {
    for (size_t i=0 ; i<pcount ; i++) {
        const Animation::Part& part(animation.parts[i]);
        const Animation::Part& part(animation.parts[i]);
        const size_t fcount = part.frames.size();
        const size_t fcount = part.frames.size();
@@ -1191,6 +1224,12 @@ bool BootAnimation::playAnimation(const Animation& animation) {
                    part.backgroundColor[2],
                    part.backgroundColor[2],
                    1.0f);
                    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++) {
            for (size_t j=0 ; j<fcount ; j++) {
                if (shouldStopPlayingPart(part, fadedFramesCount)) break;
                if (shouldStopPlayingPart(part, fadedFramesCount)) break;


@@ -1248,6 +1287,23 @@ bool BootAnimation::playAnimation(const Animation& animation) {
                    drawClock(animation.clockFont, part.clockPosX, part.clockPosY);
                    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);
                handleViewport(frameDuration);


                eglSwapBuffers(mDisplay, mSurface);
                eglSwapBuffers(mDisplay, mSurface);
+3 −0
Original line number Original line Diff line number Diff line
@@ -100,11 +100,13 @@ public:
        int fps;
        int fps;
        int width;
        int width;
        int height;
        int height;
        bool progressEnabled;
        Vector<Part> parts;
        Vector<Part> parts;
        String8 audioConf;
        String8 audioConf;
        String8 fileName;
        String8 fileName;
        ZipFileRO* zip;
        ZipFileRO* zip;
        Font clockFont;
        Font clockFont;
        Font progressFont;
    };
    };


    // All callbacks will be called from this class's internal thread.
    // All callbacks will be called from this class's internal thread.
@@ -168,6 +170,7 @@ private:
    bool movie();
    bool movie();
    void drawText(const char* str, const Font& font, bool bold, int* x, int* y);
    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 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,
    void fadeFrame(int frameLeft, int frameBottom, int frameWidth, int frameHeight,
                   const Animation::Part& part, int fadedFramesCount);
                   const Animation::Part& part, int fadedFramesCount);
    bool validClock(const Animation::Part& part);
    bool validClock(const Animation::Part& part);
+9 −1
Original line number Original line 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:
The first line defines the general parameters of the animation:


    WIDTH HEIGHT FPS
    WIDTH HEIGHT FPS [PROGRESS]


  * **WIDTH:** animation width (pixels)
  * **WIDTH:** animation width (pixels)
  * **HEIGHT:** animation height (pixels)
  * **HEIGHT:** animation height (pixels)
  * **FPS:** frames per second, e.g. 60
  * **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:
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
  * 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
  * 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
## loading and playing frames


Each part is scanned and loaded directly from the zip archive. Within a part directory, every file
Each part is scanned and loaded directly from the zip archive. Within a part directory, every file
+17.1 KiB
Loading image diff...