icon_installing.png
icon_installing_overlay01.png
静态部分提供了一个大的背景图icon_install.png,动态部分是在背景图上进行覆盖的7张小图片installationOverlay01-07.png,实现机器人肚子上旋转的动画。void ScreenRecoveryUI::draw_install_overlay_locked(int frame) {
if (installationOverlay == NULL || overlay_offset_x < 0) return;
gr_surface surface = installationOverlay[frame];
int iconWidth = gr_get_width(surface);
int iconHeight = gr_get_height(surface);
// 改变iconX和iconY的位置,修改overlay图片的描画坐标,数值自己定
int iconX = (gr_fb_width()-127) / 2;
int iconY = (gr_fb_height()-192) / 2;
gr_blit(surface, 0, 0, iconWidth, iconHeight,
iconX, iconY);
}
void ScreenRecoveryUI::draw_progress_locked()
{
if (currentIcon == ERROR) return;
if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
draw_install_overlay_locked(installingFrame);
}
if (progressBarType != EMPTY) {
int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]);
int width = gr_get_width(progressBarEmpty);
int height = gr_get_height(progressBarEmpty);
//修改dx dy的数值,改变progressbar的位置显示
int dx = (gr_fb_width() - width)/2;
int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
// Erase behind the progress bar (in case this was a progress-only update)
gr_color(0, 0, 0, 255);
gr_fill(dx, dy, width, height);
if (progressBarType == DETERMINATE) {
float p = progressScopeStart + progress * progressScopeSize;
int pos = (int) (p * width);
if (rtl_locale) {
// Fill the progress bar from right to left.
if (pos > 0) {
gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy);
}
if (pos < width-1) {
gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy);
}
} else {
// Fill the progress bar from left to right.
if (pos > 0) {
gr_blit(progressBarFill, 0, 0, pos, height, dx, dy);
}
if (pos < width-1) {
gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
}
}
}
if (progressBarType == INDETERMINATE) {
static int frame = 0;
gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
// in RTL locales, we run the animation backwards, which
// makes the spinner spin the other way.
if (rtl_locale) {
frame = (frame + indeterminate_frames - 1) % indeterminate_frames;
} else {
frame = (frame + 1) % indeterminate_frames;
}
}
}
}
void ScreenRecoveryUI::draw_background_locked(Icon icon)
{
pagesIdentical = false;
gr_color(0, 0, 0, 255);
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
if (icon) {
gr_surface surface = backgroundIcon[icon];
gr_surface text_surface = backgroundText[icon];
int iconWidth = gr_get_width(surface);
int iconHeight = gr_get_height(surface);
int textWidth = gr_get_width(text_surface);
int textHeight = gr_get_height(text_surface);
int iconX = (gr_fb_width() - iconWidth) / 2;
int iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2;
//这里改变文字的位置坐标,会同时影响恢复出厂设置和升级界面显示下的文字位置
int textX = (gr_fb_width() - textWidth) / 2;
int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40;
gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY);
if (icon == INSTALLING_UPDATE || icon == ERASING) {
draw_install_overlay_locked(installingFrame);
}
gr_color(255, 255, 255, 255);
gr_texticon(textX, textY, text_surface);
}
}
void ScreenRecoveryUI::progress_loop() {
double interval = 1.0 / animation_fps;
......
}
}
int
main(int argc, char **argv) {
......
int arg;
while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
switch (arg) {
case 'p': previous_runs = atoi(optarg); break;
case 's': send_intent = optarg; break;
case 'u': update_package = optarg; break;
case 'w': wipe_data = wipe_cache = 1; break;
case 'c': wipe_cache = 1; break;
case 't': show_text = 1; break;
case 'x': just_exit = true; break;
case 'l': locale = optarg; break;
case 'g': {
if (stage == NULL || *stage == '\0') {
char buffer[20] = "1/";
strncat(buffer, optarg, sizeof(buffer)-3);
stage = strdup(buffer);
}
break;
}
case '?':
LOGE("Invalid command argument\n");
continue;
}
}
if (locale == NULL) {
load_locale_from_cache();
}
......
}
static void
load_locale_from_cache() {
// LOCALE_FILE就是/cache/recovery/last_locale
FILE* fp = fopen_path(LOCALE_FILE, "r");
char buffer[80];
if (fp != NULL) {
fgets(buffer, sizeof(buffer), fp);
int j = 0;
unsigned int i;
for (i = 0; i < sizeof(buffer) && buffer[i]; ++i) {
if (!isspace(buffer[i])) {
buffer[j++] = buffer[i];
}
}
buffer[j] = 0;
locale = strdup(buffer);
check_and_fclose(fp, LOCALE_FILE);
}
}
刚开始接触底层,有些可能说的不对,希望自己对底层一点点的熟悉起来。对于这部分的代码可以通过LOGI来进行log输出,然后在恢复出厂后在/cache/recovery/last_log中查看到自己打印的log信息。
另外看了下android 7.1的这部分的代码,发现貌似已经可以利用max_stage是否为-1来控制不显示图片,只显示文字了。