Merge "Support for showing percent progress in boot animation."
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
BIN
core/res/assets/images/progress_font.png
Normal file
BIN
core/res/assets/images/progress_font.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Reference in New Issue
Block a user