android 9.0关机充电流程,充电图标和电量显示百分比修改 您所在的位置:网站首页 关机图标文件 android 9.0关机充电流程,充电图标和电量显示百分比修改

android 9.0关机充电流程,充电图标和电量显示百分比修改

2023-08-19 14:15| 来源: 网络整理| 查看: 265

android 9.0关机充电流程,充电图标和电量显示百分比修改

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

原文链接:https://blog.csdn.net/yy782101688/article/details/102852180

android 9.0关机充电图标和字体修改

相关源文件电量显示百分比字体替换充电图标替换

 

相关源文件 system/core/healthd/healthd_draw.cpp system/core/healthd/images/battery_fail.png system/core/healthd/images/battery_scale.png /system/core/healthd/ charger.cpp hardware/interfaces/health/2.0/default/healthd_common.cpp system/core/healthd/healthd_mode_charger.cpp bootable/recovery/minui/graphics.cpp bootable/recovery/minui/font_10x18.h 电量显示百分比字体替换

android默认文字和充电图标分开。android 9.0的充电图标和电量百分比显示主要在函数 healthd_mode_charger_heartbeat中实现。

void healthd_mode_charger_heartbeat() { charger* charger = &charger_state; int64_t now = curr_time_ms(); handle_input_state(charger, now); handle_power_supply_state(charger, now); /* do screen update last in case any of the above want to start * screen transitions (animations, etc) */ update_screen_state(charger, now); } static void update_screen_state(charger* charger, int64_t now) { animation* batt_anim = charger->batt_anim; int disp_time; if (!batt_anim->run || now < charger->next_screen_transition) return; if (healthd_draw == nullptr) { if (healthd_config && healthd_config->screen_on) { if (!healthd_config->screen_on(batt_prop)) { LOGV("[%" PRId64 "] leave screen off\n", now); batt_anim->run = false; charger->next_screen_transition = -1; if (charger->charger_connected) request_suspend(true); return; } } healthd_draw.reset(new HealthdDraw(batt_anim)); #ifndef CHARGER_DISABLE_INIT_BLANK set_backlight(false); healthd_draw->blank_screen(true); #endif } /*如果当前显示的循环次数已经为设置的最大cycle,就做灭屏处理,等待下次按下*/ /*power键或者拔掉usb*/ /* animation is over, blank screen and leave */ if (batt_anim->num_cycles > 0 && batt_anim->cur_cycle == batt_anim->num_cycles) { reset_animation(batt_anim); charger->next_screen_transition = -1; set_backlight(false); healthd_draw->blank_screen(true); LOGV("[%" PRId64 "] animation done\n", now); if (charger->charger_connected) request_suspend(true); return; } /*设置一帧,即一个png图片的显示时间*/ disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time; /*充电休眠过程中按power键或者插第一次刚开始充电时候亮屏*/ /* unblank the screen on first cycle and first frame */ if (batt_anim->cur_cycle == 0 && batt_anim->cur_frame == 0) { healthd_draw->blank_screen(false); set_backlight(true); } /*当前帧如果是第一帧(按下power键唤醒或者第一次刚开始充电)*/ /*根据实际电量,确认起始帧(即从第几张png图片开始显示),起始*/ /*帧显示时间加first_frame_repeats*/ /* animation starting, set up the animation */ if (batt_anim->cur_frame == 0) { LOGV("[%" PRId64 "] animation starting\n", now); if (batt_prop) { batt_anim->cur_level = batt_prop->batteryLevel; batt_anim->cur_status = batt_prop->batteryStatus; if (batt_prop->batteryLevel >= 0 && batt_anim->num_frames != 0) { /* find first frame given current battery level */ for (int i = 0; i < batt_anim->num_frames; i++) { if (batt_anim->cur_level >= batt_anim->frames[i].min_level && batt_anim->cur_level frames[i].max_level) { batt_anim->cur_frame = i; break; } } // repeat the first frame first_frame_repeats times disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time * batt_anim->first_frame_repeats; } } } /*设定起始帧之后,开始调用redraw_screen显示充电画面,包括文字*/ /* draw the new frame (@ cur_frame) */ healthd_draw->redraw_screen(charger->batt_anim, charger->surf_unknown); /* if we don't have anim frames, we only have one image, so just bump * the cycle counter and exit */ if (batt_anim->num_frames == 0 || batt_anim->cur_level < 0) { LOGW("[%" PRId64 "] animation missing or unknown battery status\n", now); charger->next_screen_transition = now + BATTERY_UNKNOWN_TIME; batt_anim->cur_cycle++; return; } /*显示一帧需要等待的耗时*/ /* schedule next screen transition */ charger->next_screen_transition = now + disp_time; /* advance frame cntr to the next valid frame only if we are charging * if necessary, advance cycle cntr, and reset frame cntr */ if (charger->charger_connected) { batt_anim->cur_frame++; while (batt_anim->cur_frame < batt_anim->num_frames && (batt_anim->cur_level < batt_anim->frames[batt_anim->cur_frame].min_level || batt_anim->cur_level > batt_anim->frames[batt_anim->cur_frame].max_level)) { batt_anim->cur_frame++; } /*第N轮显示结束,进入第N+1轮显示,直到cycle为设置的最大的值,进入灭屏*/ if (batt_anim->cur_frame >= batt_anim->num_frames) { batt_anim->cur_cycle++; batt_anim->cur_frame = 0; /* don't reset the cycle counter, since we use that as a signal * in a test above to check if animation is over */ } } else { /* Stop animating if we're not charging. * If we stop it immediately instead of going through this loop, then * the animation would stop somewhere in the middle. */ batt_anim->cur_frame = 0; batt_anim->cur_cycle++; } } void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) { clear_screen(); /* try to display *something* */ if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) draw_unknown(surf_unknown); else draw_battery(batt_anim); gr_flip(); }

显示充电图标,电量百分比和时间。

void HealthdDraw::draw_battery(const animation* anim) { const animation::frame& frame = anim->frames[anim->cur_frame]; if (anim->num_frames != 0) { draw_surface_centered(frame.surface); LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, frame.min_level, frame.disp_time); } draw_clock(anim); draw_percent(anim); }

显示充电图标的实际为draw_surface_centered,draw_percent为显示文字点亮百分比,默认代码未初始化field.font,即字体font。使用minui默认字体进行显示。

void HealthdDraw::draw_percent(const animation* anim) { int cur_level = anim->cur_level; if (anim->cur_status == BATTERY_STATUS_FULL) { cur_level = 100; } if (cur_level < 0) return; const animation::text_field& field = anim->text_percent; if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) { return; } std::string str = base::StringPrintf("%d%%", cur_level); int x, y; determine_xy(field, str.size(), &x, &y); LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); /*设置颜色,根据field.font指定的字体显示百分比,x,y为显示的坐标,显示大小*/ 由font指定*/ gr_color(field.color_r, field.color_g, field.color_b, field.color_a); draw_text(field.font, x, y, str.c_str()); }

由于默认代码field.font为空,不会显示电量百分比,添加以下代码,用字体gr_font显示百分比。gr_font的初始化在gr_init_font中。

/* bootable/recovery/minui/graphics.cpp*/ const GRFont* gr_sys_font() { return gr_font; }

gr_init_font() 初始化gr_font主要是两个逻辑。逻辑一:调用 int res = gr_init_font(“font”, &gr_font);最终会根据name “font”,找到res/images/font.png,依据font.png初始化gr_font,然后return,不会进入逻辑二。font.png的位置在out目录recovery/root/res/images/font.png。recovery模式下,就是走的这个流程。

/*build/make/core/Makefile默认使用bootable/recovery/fonts下的18x32.png初始化 *recovery模式下字体。*/ ifneq (,$(filter xxxhdpi 560dpi xxhdpi 400dpi xhdpi,$(recovery_density))) recovery_font := $(call include-path-for, recovery)/fonts/18x32.png else recovery_font := $(call include-path-for, recovery)/fonts/12x22.png endif

逻辑二:如果res/images/font.png不存在,就会根据"font_10x18.h"这个头文件定义的font初始化,这个默认字体文件在源码路径bootable/recovery/minui/font_10x18.h。关机充电电量百分比显示的字体格式根据此头文件初始化,替换验证。

/*bootable/recovery/minui/font_10x18.h*/ struct { unsigned width; unsigned height; unsigned char_width; unsigned char_height; unsigned char rundata[2973]; } font = { .width = 960, .height = 18, .char_width = 10, .char_height = 18, .rundata = { ...... }   static void update_screen_state(charger* charger, int64_t now) { animation* batt_anim = charger->batt_anim; int disp_time; if (!batt_anim->run || now < charger->next_screen_transition) return; if (healthd_draw == nullptr) { if (healthd_config && healthd_config->screen_on) { if (!healthd_config->screen_on(batt_prop)) { LOGV("[%" PRId64 "] leave screen off\n", now); batt_anim->run = false; charger->next_screen_transition = -1; if (charger->charger_connected) request_suspend(true); return; } } healthd_draw.reset(new HealthdDraw(batt_anim)); #ifndef CHARGER_DISABLE_INIT_BLANK set_backlight(false); healthd_draw->blank_screen(true); #endif } ...... } HealthdDraw::HealthdDraw(animation* anim) : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN), kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) { gr_init(); ...... } int gr_init() { gr_init_font(); ...... } static void gr_init_font(void) { /*逻辑一*/ int res = gr_init_font("font", &gr_font); if (res == 0) { return; } /*逻辑二*/ printf("failed to read font: res=%d\n", res); // fall back to the compiled-in font. gr_font = static_cast(calloc(1, sizeof(*gr_font))); gr_font->texture = static_cast(malloc(sizeof(*gr_font->texture))); gr_font->texture->width = font.width; gr_font->texture->height = font.height; gr_font->texture->row_bytes = font.width; gr_font->texture->pixel_bytes = 1; unsigned char* bits = static_cast(malloc(font.width * font.height)); gr_font->texture->data = bits; unsigned char data; unsigned char* in = font.rundata; while ((data = *in++)) { memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f); bits += (data & 0x7f); } gr_font->char_width = font.char_width; gr_font->char_height = font.char_height; } /*逻辑二recovery 模式下字体初始化,最终找到res/images/font.png*/ int gr_init_font(const char* name, GRFont** dest) { ...... int res = res_create_alpha_surface(name, &(font->texture)); if (res < 0) { free(font); return res; } ...... } PngHandler::PngHandler(const std::string& name) : error_code_(0), png_fp_(nullptr, fclose) { std::string res_path = android::base::StringPrintf("/res/images/%s.png", name.c_str()); png_fp_.reset(fopen(res_path.c_str(), "rbe")); if (!png_fp_) { error_code_ = -1; return; } ...... } 充电图标替换

不同于android6.0,android7.0及以上版本默认关机充电图标已经变更一张battery_scale.png。修改默认关机充电图标,实际上要替换battery_scale.png。

battery_scale.png文件制作

利用系统源码中的工具bootable/recovery/interlace-frames.py,即能将battery_scale.png拆分成几张png图片,也能将若干张png合成一张battery_scale.png。

拆分指令 python interlace-frames.py -d battery_scale.png -o battery.png  

结果生成battery00.png~battery05.png共6个PNG文件,对应c源码配置:

static animation::frame default_animation_frames[] = { { .disp_time = 750, .min_level = 0, .max_level = 19, .surface = NULL, }, { .disp_time = 750, .min_level = 0, .max_level = 39, .surface = NULL, }, { .disp_time = 750, .min_level = 0, .max_level = 59, .surface = NULL, }, { .disp_time = 750, .min_level = 0, .max_level = 79, .surface = NULL, }, { .disp_time = 750, .min_level = 80, .max_level = 95, .surface = NULL, }, { .disp_time = 750, .min_level = 0, .max_level = 100, .surface = NULL, }, };

在这里插入图片描述 将生成的battery00.png~battery05.png替换成定制的充电图片,并使用合并指令,重新生成新的battery_scale.png。

合并指令 python interlace-frames.py -o battery_scale.png oem/battery00.png oem/battery01.png oem/battery02.png oem/battery03.png oem/battery04.png oem/battery05.png 验证方法 adb root adb remount setenforce 0 adb push battery_scale.png res/images/charger adb reboot


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有