Loading cmds/bootanimation/BootAnimation.cpp +58 −2 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading @@ -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') { Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading Loading @@ -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); Loading cmds/bootanimation/BootAnimation.h +3 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); Loading cmds/bootanimation/FORMAT.md +9 −1 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 Loading core/res/assets/images/progress_font.png 0 → 100644 +17.1 KiB Loading image diff... Loading
cmds/bootanimation/BootAnimation.cpp +58 −2 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading @@ -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') { Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading Loading @@ -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); Loading
cmds/bootanimation/BootAnimation.h +3 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); Loading
cmds/bootanimation/FORMAT.md +9 −1 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 Loading