关机充电动画:流程与定制
基于MTK平台Android 11分析
生成logo.bin
关机充电动画是由一系列的bmp图片组成的,这些图片资源存在于vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo
目录下(当然不仅保护关机充电动画,还包括开机logo)。根据设备屏幕的不同,分别制作了适合不同分辨率的图片。这些图片在编译过程中会被制作成logo.bin
文件刷入设备。
该目录下,存在一个子目录tool
,存放了用于格式转换及压缩打包的工具。还存在名为rules.mk
的文件,该文件定义了生成logo.bin
文件的规则。
在vendor/mediatek/proprietary/bootable/bootloader/lk/scripts
下,存放了用于制作logo.bin
的工具。
下面先来看一下logo.bin
具体是怎么制作的。
vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/rules.mk
LOCAL_DIR := $(GET_LOCAL_DIR)
BOOT_LOGO_DIR := $(LOCAL_DIR)#fix no boot_logo config
#LOCAL_CFLAGS += -DBOOT_LOGO=wvgaifeq ($(strip $(BOOT_LOGO)),)BOOT_LOGO = fwvga
endififeq ($(strip $(MTK_LK_CAMERA_SUPPORT)), yes)BOOT_LOGO = fhd
endif$(info BOOT_LOGO = $(BOOT_LOGO))
$(info lk/logo/dir=$(LOCAL_DIR),builddir=$(BUILDDIR))# 定义工具的位置
ifeq ($(HOST_OS),darwin)
BMP_TO_RAW := $(BOOT_LOGO_DIR)/tool/bmp_to_raw.darwin
ZPIPE := $(BOOT_LOGO_DIR)/tool/zpipe.darwin
MKIMG := $(LOCAL_DIR)/../../scripts/mkimage.darwin
else
BMP_TO_RAW := $(BOOT_LOGO_DIR)/tool/bmp_to_raw
ZPIPE := $(BOOT_LOGO_DIR)/tool/zpipe
MKIMG := $(LOCAL_DIR)/../../scripts/mkimage
endif
IMG_HDR_CFG := $(LOCAL_DIR)/img_hdr_logo.cfgEMPTY :=
UNDER_LINE := _
TEMP := $(strip $(subst $(UNDER_LINE), $(EMPTY), $(BOOT_LOGO)))
COUNT := $(words $(TEMP))
BASE_LOGO := $(word $(COUNT),$(TEMP))
EXIST := $(shell if [ -e $(BOOT_LOGO_DIR)/$(BASE_LOGO) ]; then echo "exist"; else echo "noexist"; fi;)
ifeq ($(EXIST), "noexist")BASE_LOGO := $(BOOT_LOGO)
endif# 是否支持快充
SUPPORT_PUMP_EXPRESS = no
ifeq ($(strip $(MTK_PUMP_EXPRESS_SUPPORT)), yes)SUPPORT_PUMP_EXPRESS = yes
elseifeq ($(strip $(MTK_PUMP_EXPRESS_PLUS_SUPPORT)), yes)SUPPORT_PUMP_EXPRESS = yesendif
endif# 打包后的文件
BOOT_LOGO_RESOURCE := $(BUILDDIR)/$(BOOT_LOGO_DIR)/boot_logo.raw
# 产物名
LOGO_IMAGE := $(BUILDDIR)/logo.bindefine generate_logo_executableifneq ($(strip $(MACH_TYPE)), 2701)
ifneq ($(strip $(MTK_ALPS_BOX_SUPPORT)), yes)
# 资源文件列表,有顺序,索引值从0开始
RESOURCE_OBJ_LIST += \$(BOOT_LOGO_DIR)/$(1)/$(1)_uboot.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_battery.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_charger_ov.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_0.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_1.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_2.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_3.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_4.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_5.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_6.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_7.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_8.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_9.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_num_percent.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_02.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_03.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_04.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_05.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_06.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_07.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_08.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_09.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_animation_10.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_02.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_03.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_04.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_05.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_06.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_07.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_08.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_09.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_10_10.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_bg.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_img.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_bat_100.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_kernel.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery02.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery_remind.raw
endif
endif# 如果支持快充
ifeq ($(strip $(SUPPORT_PUMP_EXPRESS)), yes)
RESOURCE_OBJ_LIST += \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_100.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_ani-01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_ani-02.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_ani-03.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_ani-04.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_ani-05.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_ani-06.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_00.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_02.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_03.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_04.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_05.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_06.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_07.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_08.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_09.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_fast_charging_percent.raw
endif# 如果支持无线充电
ifeq ($(strip $(MTK_WIRELESS_CHARGER_SUPPORT)), yes)
RESOURCE_OBJ_LIST += \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_00.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_02.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_03.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_04.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_05.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_06.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_07.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_08.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_09.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_num_percent.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_10_0.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_10_1.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_10_2.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_10_3.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_30_0.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_30_1.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_30_2.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_30_3.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_60_0.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_60_1.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_60_2.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_60_3.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_90_0.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_90_1.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_90_2.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_90_3.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_0.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_wireless_bat_100.raw
endifendef$(foreach BASE_LOGO,$(BOOT_LOGO),$(eval $(call generate_logo_executable,$(BASE_LOGO))))GENERATED += \$(BOOT_LOGO_RESOURCE) \$(LOGO_IMAGE) \$(addprefix $(BUILDDIR)/,$(RESOURCE_OBJ_LIST))# 目标
all:: $(LOGO_IMAGE)#logo.bin具体的的制作命令
$(LOGO_IMAGE):$(MKIMG) $(BOOT_LOGO_RESOURCE)@echo "MKING $(LOGO_IMAGE) start"@echo $(MKIMG)@echo $(BOOT_LOGO_RESOURCE)@echo $(LOGO_IMAGE)$(MKIMG) $(BOOT_LOGO_RESOURCE) $(IMG_HDR_CFG) > $(LOGO_IMAGE)# 压缩打包
$(BOOT_LOGO_RESOURCE): $(addprefix $(BUILDDIR)/,$(RESOURCE_OBJ_LIST)) $(ZPIPE)@$(MKDIR)@echo "zpiping "$(ZPIPE) -l 9 $@ $(addprefix $(BUILDDIR)/,$(RESOURCE_OBJ_LIST))# 格式转换
$(BUILDDIR)/%.raw: %.bmp $(BMP_TO_RAW)@$(MKDIR)@echo "Compiling_BMP_TO_RAW $<"$(BMP_TO_RAW) $@ $<
从编译Log中可以看到更详细过程:
- 将bmp图像格式转换成raw格式
- 压缩raw文件,最终打包成boot_logo.raw文件
- 生成
logo.bin
镜像
实际刷入机器的并不是这个logo.bin,还需要签名,形成logo-verified.bin
。
充电动画main()函数
充电动画的入口函数,由init
进程启动。负责处理充电动画和充电期间的按键控制。
/vendor/mediatek/proprietary/external/charger/main.cpp
#include <sys/resource.h>
#include "main.h"// add prefer power and backlight keys in below arrays.
int pwrkeys[] = {KEY_POWER, KEY_END};void exit_charger(int reason) //退出充电的几种情况
{KPOC_LOGI("exit_charger: %d \n", reason);switch(reason) {case EXIT_ALARM_BOOT:case EXIT_POWER_UP:case EXIT_REBOOT_UBOOT:reboot(RB_AUTOBOOT);break;case EXIT_CHARGING_MODE:case EXIT_ERROR_SHUTDOWN:case EXIT_NORMAL_SHUTDOWN:default:reboot(RB_POWER_OFF);break;}
}int main(__attribute__((unused))int argc, __attribute__((unused))char *argv[])
{set_draw_anim_mode(1); //设置充电动画绘制模式(DRAW_ANIM_MODE_FB)。pthread_mutex_init(&lights_mutex, NULL); //互斥锁,与灯光控制相关。setpriority(PRIO_PROCESS, 0, -20); //设置了进程的优先级。FILE *oom_adj = fopen("/proc/self/oom_score_adj", "w");if (oom_adj) {if (fputs("-17", oom_adj) == EOF) {KPOC_LOGI("fputs error\n");}fclose(oom_adj);}health_service_init(); //初始化health服务,跟电池健康、充电状态有关。light_init(); //灯光初始化。//stop_backlight();KPOC_LOGI("stop_backlight 1\n");bootlogo_init(); //充电动画初始化。charging_control(); //充电的相关控制逻辑。unsigned int i;for (i=0; i< ARRAY_SIZE(pwrkeys); i++)KPOC_LOGI("pwrkeys[%d]:%d\n",i,pwrkeys[i]);key_control(pwrkeys, ARRAY_SIZE(pwrkeys)); //will loop inside //充电期间的按键处理。return 0;
}
set_draw_anim_mode()函数
根据running_mode
设置动画绘制模式。最终会修改vendor/mediatek/proprietary/external/libshowlogo/charging_animation.cpp
中的全局变量
draw_anim_mode
,由于running_mode被写死为1,所以动画绘制模式永远为DRAW_ANIM_MODE_FB
。
vendor/mediatek/proprietary/external/charger/bootlogo.cpp
/** Set charging animation drawing method according to running mode:* running IPO : using surface flinger , DRAW_ANIM_MODE_SURFACE * running KPOC: using framebuffer , DRAW_ANIM_MODE_FB*///传入的running_mode为1
void set_draw_anim_mode(int running_mode)
{int draw_anim_mode = DRAW_ANIM_MODE_SURFACE;KPOC_LOGD("[ChargingAnimation %s %d]kpoc flag == 1 ? : running_mode = %d \n ",__FUNCTION__,__LINE__ ,running_mode);if(running_mode == 1) {draw_anim_mode = DRAW_ANIM_MODE_FB;KPOC_LOGD("[ChargingAnimation %s %d]under kernel power off charging mode, use fb to draw animation!",__FUNCTION__,__LINE__ );} else {draw_anim_mode = DRAW_ANIM_MODE_SURFACE; } set_draw_mode(draw_anim_mode);
// set_draw_mode(DRAW_ANIM_MODE_SURFACE);
}
/home/mh/mediatek/proprietary/external/libshowlogo/charging_animation.cpp
...
static int draw_anim_mode = DRAW_ANIM_MODE_SURFACE;
.../** Set charging animation drawing method**/
void set_draw_mode(int draw_mode)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]0 --use framebuffer, 1--use surface flinger ,draw_anim_mode = :%d",__FUNCTION__,__LINE__ ,draw_mode);}if ((draw_mode != (DRAW_ANIM_MODE_FB)) && (draw_mode != (DRAW_ANIM_MODE_SURFACE))) {draw_anim_mode = DRAW_ANIM_MODE_SURFACE;} else {draw_anim_mode = draw_mode;}
}
bootlogo_init()函数
bootlogo_init()函数主要做了两件事情:
- 设置充电动画的样式
- 充电动画的初始化
/mediatek/proprietary/external/charger/bootlogo.cpp
/** Init charging animation version , drawing method and other parameters**/
void bootlogo_init()
{KPOC_LOGI("[ChargingAnimation: %s %d]\n",__FUNCTION__,__LINE__);sync_anim_version();anim_init();
}
sync_anim_version()函数
sync_anim_version()函数用于设置充电动画的样式。
/mediatek/proprietary/external/charger/bootlogo.cpp
/** Read charging animation feature option, and set charging animation version** version 0: show 4 recatangle growing animation without battery number * version 1: show wave animation with battery number */
//这里注释少写一个version 2,是无线充电的样式。
void sync_anim_version()
{KPOC_LOGI("[ChargingAnimation: %s %d]\n",__FUNCTION__,__LINE__);if (is_wireless_charging()){set_anim_version(VERION_WIRELESS_CHARGING_ANIMATION); } else {
#ifdef ANIMATION_NEWset_anim_version(VERION_NEW_ANIMATION);
#elseset_anim_version(VERION_OLD_ANIMATION);KPOC_LOGI("[ChargingAnimation %s %d]not define ANIMATION_NEW:show old animation \n",__FUNCTION__,__LINE__);
#endif }
}
vendor/mediatek/proprietary/bootable/bootloader/lk/lib/libshowlogo/cust_display.h
/* The option of new charging animation */
#define ANIMATION_NEW
vendor/mediatek/proprietary/external/charger/bootlogo.cpp
#define VERION_OLD_ANIMATION 0
#define VERION_NEW_ANIMATION 1
#define VERION_WIRELESS_CHARGING_ANIMATION 2
anim_init()函数
该函数主要有4个作用:
- 通过
"ro.charge_animation.rotation"
属性获取充电动画的方向。 - 初始化充电动画的UI参数。
- 加载充电动画资源到内存。
- 初始化framebuffer。
vendor/mediatek/proprietary/external/libshowlogo/charging_animation.cpp
/** Charging animation init**/void anim_init()
{ charge_animation_rotation = getValue("ro.charge_animation.rotation", "");init_charging_animation_ui_dimension();if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]\n",__FUNCTION__,__LINE__);}anim_logo_init();if (draw_anim_mode == (DRAW_ANIM_MODE_FB)) {anim_fb_init();} else {anim_surface_init();}
}
init_charging_animation_ui_dimension()函数
根据屏幕尺寸的不同,初始化charging_anim_ui_dimension
结构体,其定义了充电动画界面的UI元素尺寸。
该结构体的定义在vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.
struct charging_anim_ui_dimension {int cap_left;int cap_top;int cap_right;int cap_bottom;int num_left;int num_top;int num_right;int num_bottom;int percent_left;int percent_top;int percent_right;int percent_bottom;int top_anim_left;int top_anim_top;int top_anim_right;int top_anim_bottom;int bar_left;int bar_top;int bar_right;int bar_bottom;int num_width_fast;int num_height_fast;int top_margin_fast;
} ;
struct charging_anim_ui_dimension charg_anim_ui_dimen ;
/** Fill resolution structure based on lcd size**/
void init_charging_animation_ui_dimension() {int lcm_width, lcm_height;struct fb_var_screeninfo vinfo;display_fd = open("/dev/graphics/fb0", O_RDONLY);if (display_fd < 0) {SLOGD("[show_animation_common: %s %d]open mtkfb fail...\n",__FUNCTION__,__LINE__);}if (ioctl(display_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {close(display_fd);SLOGD("[show_animation_common: %s %d]ioctl FBIOGET_VSCREENINFO failed\n",__FUNCTION__,__LINE__);}close(display_fd);lcm_width = vinfo.xres; //实际的横向分辨率lcm_height = vinfo.yres; //实际的纵向分辨率// int rotation = getRotation();if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]rotation = %d\n",__FUNCTION__,__LINE__, charge_animation_rotation);}if ((270 == charge_animation_rotation)|| (90 == charge_animation_rotation)){lcm_width = vinfo.yres;lcm_height = vinfo.xres;}SLOGD("[show_animation_common: %s %d] lcm_width and lcm_height= %d , %d \n",__FUNCTION__,__LINE__,lcm_width,lcm_height);if((lcm_width == 1080) && (lcm_height == 1920)) { // Special handling for FHDSLOGD("[show_animation_common: %s %d]Inside 1080*1920 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =387;charg_anim_ui_dimen.cap_right= 691;charg_anim_ui_dimen.num_left=395;charg_anim_ui_dimen.num_right=395+84;charg_anim_ui_dimen.percent_left=395+84+84;charg_anim_ui_dimen.percent_right=395+84+84+108;charg_anim_ui_dimen.top_anim_left=387;charg_anim_ui_dimen.top_anim_right=691;charg_anim_ui_dimen.bar_left=470;charg_anim_ui_dimen.bar_top=356;charg_anim_ui_dimen.bar_right=610;charg_anim_ui_dimen.bar_bottom=678;charg_anim_ui_dimen.cap_top= 802;charg_anim_ui_dimen.cap_bottom= 1292 ;charg_anim_ui_dimen.num_top=479;charg_anim_ui_dimen.num_bottom=600;charg_anim_ui_dimen.percent_top=479;charg_anim_ui_dimen.percent_bottom=600;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=152;charg_anim_ui_dimen.num_width_fast = 108;charg_anim_ui_dimen.num_height_fast = 192;charg_anim_ui_dimen.top_margin_fast = 240;}else if((lcm_width == 1080) && (lcm_height == 2160)) { // Special handling for FHD+SLOGD("[show_animation_common: %s %d]Inside 1080*2160 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =387;charg_anim_ui_dimen.cap_right= 691;charg_anim_ui_dimen.num_left=395;charg_anim_ui_dimen.num_right=395+84;charg_anim_ui_dimen.percent_left=395+84+84;charg_anim_ui_dimen.percent_right=395+84+84+108;charg_anim_ui_dimen.top_anim_left=387;charg_anim_ui_dimen.top_anim_right=691;charg_anim_ui_dimen.bar_left=470;charg_anim_ui_dimen.bar_top=356;charg_anim_ui_dimen.bar_right=610;charg_anim_ui_dimen.bar_bottom=678;charg_anim_ui_dimen.cap_top= 922;charg_anim_ui_dimen.cap_bottom= 1413 ;charg_anim_ui_dimen.num_top=599;charg_anim_ui_dimen.num_bottom=720;charg_anim_ui_dimen.percent_top=599;charg_anim_ui_dimen.percent_bottom=720;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=152;charg_anim_ui_dimen.num_width_fast = 108;charg_anim_ui_dimen.num_height_fast = 192;charg_anim_ui_dimen.top_margin_fast = 240;}else if(lcm_width==1080) {charg_anim_ui_dimen.cap_left =408;charg_anim_ui_dimen.cap_right= 671;charg_anim_ui_dimen.num_left=445;charg_anim_ui_dimen.num_right=445+45;charg_anim_ui_dimen.percent_left=445+90;charg_anim_ui_dimen.percent_right=445+90+57;charg_anim_ui_dimen.top_anim_left=408;charg_anim_ui_dimen.top_anim_right=671;charg_anim_ui_dimen.bar_left=470;charg_anim_ui_dimen.bar_top=356;charg_anim_ui_dimen.bar_right=610;charg_anim_ui_dimen.bar_bottom=678;charg_anim_ui_dimen.num_width_fast = 72;charg_anim_ui_dimen.num_height_fast = 128;charg_anim_ui_dimen.top_margin_fast = 300;if (lcm_height == 2280) {SLOGD("[show_animation_common: %s %d]Inside 1080*2280 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 992;charg_anim_ui_dimen.cap_bottom= 1473 ;charg_anim_ui_dimen.num_top=659;charg_anim_ui_dimen.num_bottom=780;charg_anim_ui_dimen.percent_top=659;charg_anim_ui_dimen.percent_bottom=780;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=147;}else if (lcm_height == 2300) {SLOGD("[show_animation_common: %s %d]Inside 1080*2300 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 1002;charg_anim_ui_dimen.cap_bottom= 1498;charg_anim_ui_dimen.num_top=669;charg_anim_ui_dimen.num_bottom=790;charg_anim_ui_dimen.percent_top=669;charg_anim_ui_dimen.percent_bottom=790;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=147;}else if (lcm_height == 2340) {SLOGD("[show_animation_common: %s %d]Inside 1080*2340 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 1012;charg_anim_ui_dimen.cap_bottom= 1503 ;charg_anim_ui_dimen.num_top=689;charg_anim_ui_dimen.num_bottom=810;charg_anim_ui_dimen.percent_top=689;charg_anim_ui_dimen.percent_bottom=810;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=147;}else if (lcm_height == 2400) {SLOGD("[show_animation_common: %s %d]Inside 1080*2340 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 1042;charg_anim_ui_dimen.cap_bottom= 1533 ;charg_anim_ui_dimen.num_top=729;charg_anim_ui_dimen.num_bottom=840;charg_anim_ui_dimen.percent_top=729;charg_anim_ui_dimen.percent_bottom=840;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=147;}else if (lcm_height == 2520) {SLOGD("[show_animation_common: %s %d]Inside 1080*2520 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 1112;charg_anim_ui_dimen.cap_bottom= 1593 ;charg_anim_ui_dimen.num_top=819;charg_anim_ui_dimen.num_bottom=819+64;charg_anim_ui_dimen.percent_top=819;charg_anim_ui_dimen.percent_bottom=819+64;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=147;}}else if(lcm_width ==720) {charg_anim_ui_dimen.cap_left =278;charg_anim_ui_dimen.cap_right= 441;charg_anim_ui_dimen.num_left=290;charg_anim_ui_dimen.num_right=335;charg_anim_ui_dimen.percent_left=380;charg_anim_ui_dimen.percent_right=437;charg_anim_ui_dimen.top_anim_left=278;charg_anim_ui_dimen.top_anim_right=441;charg_anim_ui_dimen.bar_left=313;charg_anim_ui_dimen.bar_top=238;charg_anim_ui_dimen.bar_right=406;charg_anim_ui_dimen.bar_bottom=453;charg_anim_ui_dimen.num_width_fast = 72;charg_anim_ui_dimen.num_height_fast = 128;charg_anim_ui_dimen.top_margin_fast = 180;if(lcm_height == 1280) {SLOGD("[show_animation_common: %s %d]Inside 720*1280 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 556;charg_anim_ui_dimen.cap_bottom= 817 ;charg_anim_ui_dimen.num_top=386;charg_anim_ui_dimen.num_bottom=450;charg_anim_ui_dimen.percent_top=386;charg_anim_ui_dimen.percent_bottom=450;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=129;}else if(lcm_height == 1440) {SLOGD("[show_animation_common: %s %d]Inside 720*1440 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 636;charg_anim_ui_dimen.cap_bottom= 898 ;charg_anim_ui_dimen.num_top=465;charg_anim_ui_dimen.num_bottom=529;charg_anim_ui_dimen.percent_top=465;charg_anim_ui_dimen.percent_bottom=529;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=129;}else if(lcm_height == 1500) {SLOGD("[show_animation_common: %s %d]Inside 720*1500 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 640;charg_anim_ui_dimen.cap_bottom= 955 ;charg_anim_ui_dimen.num_top=450;charg_anim_ui_dimen.num_bottom=515;charg_anim_ui_dimen.percent_top=450;charg_anim_ui_dimen.percent_bottom=515;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=129;}else if(lcm_height == 1520) {SLOGD("[show_animation_common: %s %d]Inside 720*1520 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 653;charg_anim_ui_dimen.cap_bottom= 970 ;charg_anim_ui_dimen.num_top=460;charg_anim_ui_dimen.num_bottom=535;charg_anim_ui_dimen.percent_top=460;charg_anim_ui_dimen.percent_bottom=535;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=129;}else if(lcm_height == 1560) {SLOGD("[show_animation_common: %s %d]Inside 720*1560 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 678;charg_anim_ui_dimen.cap_bottom= 1000 ;charg_anim_ui_dimen.num_top=480;charg_anim_ui_dimen.num_bottom=575;charg_anim_ui_dimen.percent_top=480;charg_anim_ui_dimen.percent_bottom=575;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=129;}else if(lcm_height == 1600) {SLOGD("[show_animation_common: %s %d]Inside 720*1600 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_top= 703;charg_anim_ui_dimen.cap_bottom= 1030 ;charg_anim_ui_dimen.num_top=500;charg_anim_ui_dimen.num_bottom=615;charg_anim_ui_dimen.percent_top=500;charg_anim_ui_dimen.percent_bottom=615;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_bottom=129;}}else if(lcm_width==1440 && lcm_height==2560) {SLOGD("[show_animation_common: %s %d]Inside 1440*2560 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =556;charg_anim_ui_dimen.cap_top= 1112;charg_anim_ui_dimen.cap_right= 882;charg_anim_ui_dimen.cap_bottom= 1630 ;charg_anim_ui_dimen.num_left=570;charg_anim_ui_dimen.num_top=770;charg_anim_ui_dimen.num_right=660;charg_anim_ui_dimen.num_bottom=898;charg_anim_ui_dimen.percent_left=750;charg_anim_ui_dimen.percent_top=770;charg_anim_ui_dimen.percent_right=864;charg_anim_ui_dimen.percent_bottom=898;charg_anim_ui_dimen.top_anim_left=556;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=882;charg_anim_ui_dimen.top_anim_bottom=158;charg_anim_ui_dimen.bar_left=443;charg_anim_ui_dimen.bar_top=337;charg_anim_ui_dimen.bar_right=574;charg_anim_ui_dimen.bar_bottom=641;}else if(lcm_width==480 && lcm_height==854) {SLOGD("[show_animation_common: %s %d]Inside 480*854 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =172;charg_anim_ui_dimen.cap_top= 357;charg_anim_ui_dimen.cap_right= 307;charg_anim_ui_dimen.cap_bottom= 573 ;charg_anim_ui_dimen.num_left=172;charg_anim_ui_dimen.num_top=213;charg_anim_ui_dimen.num_right=210;charg_anim_ui_dimen.num_bottom=267;charg_anim_ui_dimen.percent_left=248;charg_anim_ui_dimen.percent_top=213;charg_anim_ui_dimen.percent_right=296;charg_anim_ui_dimen.percent_bottom=267;charg_anim_ui_dimen.top_anim_left=172;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=307;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=184;charg_anim_ui_dimen.bar_top=227;charg_anim_ui_dimen.bar_right=294;charg_anim_ui_dimen.bar_bottom=437;}else if(lcm_width==540 && lcm_height==960) {SLOGD("[show_animation_common: %s %d]Inside 540*960 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =202;charg_anim_ui_dimen.cap_top= 410;charg_anim_ui_dimen.cap_right= 337;charg_anim_ui_dimen.cap_bottom= 626 ;charg_anim_ui_dimen.num_left=202;charg_anim_ui_dimen.num_top=266;charg_anim_ui_dimen.num_right=240;charg_anim_ui_dimen.num_bottom=320;charg_anim_ui_dimen.percent_left=278;charg_anim_ui_dimen.percent_top=266;charg_anim_ui_dimen.percent_right=326;charg_anim_ui_dimen.percent_bottom=320;charg_anim_ui_dimen.top_anim_left=202;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=337;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=235;charg_anim_ui_dimen.bar_top=179;charg_anim_ui_dimen.bar_right=305;charg_anim_ui_dimen.bar_bottom=340;}else if(lcm_width==480 && lcm_height==800) {SLOGD("[show_animation_common: %s %d]Inside 480*800 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =172;charg_anim_ui_dimen.cap_top= 330;charg_anim_ui_dimen.cap_right= 307;charg_anim_ui_dimen.cap_bottom= 546 ;charg_anim_ui_dimen.num_left=178;charg_anim_ui_dimen.num_top=190;charg_anim_ui_dimen.num_right=216;charg_anim_ui_dimen.num_bottom=244;charg_anim_ui_dimen.percent_left=254;charg_anim_ui_dimen.percent_top=190;charg_anim_ui_dimen.percent_right=302;charg_anim_ui_dimen.percent_bottom=244;charg_anim_ui_dimen.top_anim_left=172;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=307;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=209;charg_anim_ui_dimen.bar_top=149;charg_anim_ui_dimen.bar_right=271;charg_anim_ui_dimen.bar_bottom=282;}else if(lcm_width==480 && lcm_height==960) { // default wuvga 480*960SLOGD("[show_animation_common: %s %d]Inside 480*960 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =172;charg_anim_ui_dimen.cap_top= 410;charg_anim_ui_dimen.cap_right= 307;charg_anim_ui_dimen.cap_bottom= 626 ;charg_anim_ui_dimen.num_left=172;charg_anim_ui_dimen.num_top=266;charg_anim_ui_dimen.num_right=210;charg_anim_ui_dimen.num_bottom=320;charg_anim_ui_dimen.percent_left=248;charg_anim_ui_dimen.percent_top=266;charg_anim_ui_dimen.percent_right=296;charg_anim_ui_dimen.percent_bottom=320;charg_anim_ui_dimen.top_anim_left=172;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=307;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=184;charg_anim_ui_dimen.bar_top=227;charg_anim_ui_dimen.bar_right=294;charg_anim_ui_dimen.bar_bottom=437;}else if(lcm_width==320 && lcm_height==480) {SLOGD("[show_animation_common: %s %d]Inside 320*480 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =109;charg_anim_ui_dimen.cap_top= 189;charg_anim_ui_dimen.cap_right= 211;charg_anim_ui_dimen.cap_bottom= 350 ;charg_anim_ui_dimen.num_left=126;charg_anim_ui_dimen.num_top=95;charg_anim_ui_dimen.num_right=153;charg_anim_ui_dimen.num_bottom=131;charg_anim_ui_dimen.percent_left=180;charg_anim_ui_dimen.percent_top=95;charg_anim_ui_dimen.percent_right=212;charg_anim_ui_dimen.percent_bottom=131;charg_anim_ui_dimen.top_anim_left=109;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=211;charg_anim_ui_dimen.top_anim_bottom=118;charg_anim_ui_dimen.bar_left=129;charg_anim_ui_dimen.bar_top=128;charg_anim_ui_dimen.bar_right=190;charg_anim_ui_dimen.bar_bottom=245;}else if(lcm_width==240 && lcm_height==240) {SLOGD("[show_animation_common: %s %d]Inside 240*240 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =82;charg_anim_ui_dimen.cap_top= 62;charg_anim_ui_dimen.cap_right= 158;charg_anim_ui_dimen.cap_bottom= 179 ;charg_anim_ui_dimen.num_left=92;charg_anim_ui_dimen.num_top=8;charg_anim_ui_dimen.num_right=108;charg_anim_ui_dimen.num_bottom=31;charg_anim_ui_dimen.percent_left=124;charg_anim_ui_dimen.percent_top=8;charg_anim_ui_dimen.percent_right=144;charg_anim_ui_dimen.percent_bottom=31;charg_anim_ui_dimen.top_anim_left=82;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=158;charg_anim_ui_dimen.top_anim_bottom=113;charg_anim_ui_dimen.bar_left=97;charg_anim_ui_dimen.bar_top=96;charg_anim_ui_dimen.bar_right=140;charg_anim_ui_dimen.bar_bottom=184;}else if(lcm_width==600 && lcm_height==1024) {SLOGD("[show_animation_common: %s %d]Inside 600*1024 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =232;charg_anim_ui_dimen.cap_top= 442;charg_anim_ui_dimen.cap_right= 367;charg_anim_ui_dimen.cap_bottom= 658 ;charg_anim_ui_dimen.num_left=250;charg_anim_ui_dimen.num_top=300;charg_anim_ui_dimen.num_right=288;charg_anim_ui_dimen.num_bottom=354;charg_anim_ui_dimen.percent_left=326;charg_anim_ui_dimen.percent_top=300;charg_anim_ui_dimen.percent_right=374;charg_anim_ui_dimen.percent_bottom=354;charg_anim_ui_dimen.top_anim_left=232;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=367;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=260;charg_anim_ui_dimen.bar_top=190;charg_anim_ui_dimen.bar_right=338;charg_anim_ui_dimen.bar_bottom=360;}else if(lcm_width==1024 && lcm_height==600) {SLOGD("[show_animation_common: %s %d]Inside 1024*600 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =444;charg_anim_ui_dimen.cap_top= 230;charg_anim_ui_dimen.cap_right= 579;charg_anim_ui_dimen.cap_bottom= 446 ;charg_anim_ui_dimen.num_left=466;charg_anim_ui_dimen.num_top=90;charg_anim_ui_dimen.num_right=504;charg_anim_ui_dimen.num_bottom=144;charg_anim_ui_dimen.percent_left=542;charg_anim_ui_dimen.percent_top=90;charg_anim_ui_dimen.percent_right=590;charg_anim_ui_dimen.percent_bottom=144;charg_anim_ui_dimen.top_anim_left=444;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=579;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=414;charg_anim_ui_dimen.bar_top=186;charg_anim_ui_dimen.bar_right=608;charg_anim_ui_dimen.bar_bottom=477;}else if(lcm_width==1280 && lcm_height==800) {SLOGD("[show_animation_common: %s %d]Inside 1280*800 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =558;charg_anim_ui_dimen.cap_top= 265;charg_anim_ui_dimen.cap_right= 721;charg_anim_ui_dimen.cap_bottom= 525 ;charg_anim_ui_dimen.num_left=585;charg_anim_ui_dimen.num_top=95;charg_anim_ui_dimen.num_right=630;charg_anim_ui_dimen.num_bottom=159;charg_anim_ui_dimen.percent_left=675;charg_anim_ui_dimen.percent_top=95;charg_anim_ui_dimen.percent_right=732;charg_anim_ui_dimen.percent_bottom=159;charg_anim_ui_dimen.top_anim_left=558;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=721;charg_anim_ui_dimen.top_anim_bottom=129;charg_anim_ui_dimen.bar_left=525;charg_anim_ui_dimen.bar_top=250;charg_anim_ui_dimen.bar_right=755;charg_anim_ui_dimen.bar_bottom=640;}else if(lcm_width==1366 && lcm_height==768) {SLOGD("[show_animation_common: %s %d]Inside 1366*768 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =558;charg_anim_ui_dimen.cap_top= 265;charg_anim_ui_dimen.cap_right= 721;charg_anim_ui_dimen.cap_bottom= 525 ;charg_anim_ui_dimen.num_left=585;charg_anim_ui_dimen.num_top=95;charg_anim_ui_dimen.num_right=630;charg_anim_ui_dimen.num_bottom=159;charg_anim_ui_dimen.percent_left=675;charg_anim_ui_dimen.percent_top=95;charg_anim_ui_dimen.percent_right=732;charg_anim_ui_dimen.percent_bottom=159;charg_anim_ui_dimen.top_anim_left=558;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=721;charg_anim_ui_dimen.top_anim_bottom=129;charg_anim_ui_dimen.bar_left=525;charg_anim_ui_dimen.bar_top=250;charg_anim_ui_dimen.bar_right=755;charg_anim_ui_dimen.bar_bottom=640;}else if(lcm_width==800 && lcm_height==1280) {SLOGD("[show_animation_common: %s %d]Inside 800*1280 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =318;charg_anim_ui_dimen.cap_top= 556;charg_anim_ui_dimen.cap_right= 481;charg_anim_ui_dimen.cap_bottom= 815 ;charg_anim_ui_dimen.num_left=345;charg_anim_ui_dimen.num_top=385;charg_anim_ui_dimen.num_right=390;charg_anim_ui_dimen.num_bottom=449;charg_anim_ui_dimen.percent_left=435;charg_anim_ui_dimen.percent_top=385;charg_anim_ui_dimen.percent_right=492;charg_anim_ui_dimen.percent_bottom=449;charg_anim_ui_dimen.top_anim_left=318;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=481;charg_anim_ui_dimen.top_anim_bottom=129;charg_anim_ui_dimen.bar_left=348;charg_anim_ui_dimen.bar_top=238;charg_anim_ui_dimen.bar_right=453;charg_anim_ui_dimen.bar_bottom=452;}else if(lcm_width==1920 && lcm_height==1200) {SLOGD("[show_animation_common: %s %d]Inside 600*1024 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =806;charg_anim_ui_dimen.cap_top= 443;charg_anim_ui_dimen.cap_right= 1110;charg_anim_ui_dimen.cap_bottom= 929 ;charg_anim_ui_dimen.num_left=855;charg_anim_ui_dimen.num_top=124;charg_anim_ui_dimen.num_right=939;charg_anim_ui_dimen.num_bottom=245;charg_anim_ui_dimen.percent_left=1023;charg_anim_ui_dimen.percent_top=124;charg_anim_ui_dimen.percent_right=1131;charg_anim_ui_dimen.percent_bottom=245;charg_anim_ui_dimen.top_anim_left=806;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=1110;charg_anim_ui_dimen.top_anim_bottom=152;charg_anim_ui_dimen.bar_left=890;charg_anim_ui_dimen.bar_top=357;charg_anim_ui_dimen.bar_right=1030;charg_anim_ui_dimen.bar_bottom=678;}else if(lcm_width==1200 && lcm_height==1920) {SLOGD("[show_animation_common: %s %d]Inside 1200*1920 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =447;charg_anim_ui_dimen.cap_top= 803;charg_anim_ui_dimen.cap_right= 751;charg_anim_ui_dimen.cap_bottom= 1289 ;charg_anim_ui_dimen.num_left=494;charg_anim_ui_dimen.num_top=481;charg_anim_ui_dimen.num_right=578;charg_anim_ui_dimen.num_bottom=602;charg_anim_ui_dimen.percent_left=662;charg_anim_ui_dimen.percent_top=481;charg_anim_ui_dimen.percent_right=770;charg_anim_ui_dimen.percent_bottom=602;charg_anim_ui_dimen.top_anim_left=447;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=751;charg_anim_ui_dimen.top_anim_bottom=152;charg_anim_ui_dimen.bar_left=529;charg_anim_ui_dimen.bar_top=357;charg_anim_ui_dimen.bar_right=672;charg_anim_ui_dimen.bar_bottom=680;}else if(lcm_width==768 && lcm_height==1024) {SLOGD("[show_animation_common: %s %d]Inside 768*1024 \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =316;charg_anim_ui_dimen.cap_top= 442;charg_anim_ui_dimen.cap_right= 451;charg_anim_ui_dimen.cap_bottom= 658 ;charg_anim_ui_dimen.num_left=338;charg_anim_ui_dimen.num_top=300;charg_anim_ui_dimen.num_right=376;charg_anim_ui_dimen.num_bottom=354;charg_anim_ui_dimen.percent_left=414;charg_anim_ui_dimen.percent_top=300;charg_anim_ui_dimen.percent_right=462;charg_anim_ui_dimen.percent_bottom=354;charg_anim_ui_dimen.top_anim_left=316;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=451;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=334;charg_anim_ui_dimen.bar_top=243;charg_anim_ui_dimen.bar_right=434;charg_anim_ui_dimen.bar_bottom=463;}else { // default wvga 480*800SLOGD("[show_animation_common: %s %d]default case final else \n",__FUNCTION__,__LINE__);charg_anim_ui_dimen.cap_left =172;charg_anim_ui_dimen.cap_top= 330;charg_anim_ui_dimen.cap_right= 307;charg_anim_ui_dimen.cap_bottom= 546 ;charg_anim_ui_dimen.num_left=178;charg_anim_ui_dimen.num_top=190;charg_anim_ui_dimen.num_right=216;charg_anim_ui_dimen.num_bottom=244;charg_anim_ui_dimen.percent_left=254;charg_anim_ui_dimen.percent_top=290;charg_anim_ui_dimen.percent_right=302;charg_anim_ui_dimen.percent_bottom=244;charg_anim_ui_dimen.top_anim_left=172;charg_anim_ui_dimen.top_anim_top=100;charg_anim_ui_dimen.top_anim_right=307;charg_anim_ui_dimen.top_anim_bottom=124;charg_anim_ui_dimen.bar_left=209;charg_anim_ui_dimen.bar_top=149;charg_anim_ui_dimen.bar_right=271;charg_anim_ui_dimen.bar_bottom=282;}}
anim_logo_init()
加载动画资源到内存。
vendor/mediatek/proprietary/external/libshowlogo/charging_animation.cpp
/** Charging animation logo.bin related init**/
void anim_logo_init(void)
{// read and de-compress logo data hereint fd = 0;int len = 0;Fstab fstab;if (!ReadDefaultFstab(&fstab)) {if (MTK_LOG_ENABLE == 1) {SLOGE("failed to open fstab\n");}error_flag = 1;return;}auto rec = GetEntryForMountPoint(&fstab, LOGO_MNT_POINT); //获取logo挂载点if (rec == nullptr) {if (MTK_LOG_ENABLE == 1) {SLOGE("failed to get entry for %s\n", LOGO_MNT_POINT);}error_flag = 1;return;}// "rec->blk_device" is the pathfd = open(rec->blk_device.c_str(), O_RDONLY); //只读方式打开rec->blk_device.c_str()文件// get logo patition from fstab endif(fd < 0){if (MTK_LOG_ENABLE == 1) {SLOGE("[libshowlogo: %s %d]open logo partition device file fail, errno = %d \n",__FUNCTION__,__LINE__ , errno);}goto error_return;}logo_addr = (unsigned int*)malloc(LOGO_BUFFER_SIZE);if(logo_addr == NULL){if (MTK_LOG_ENABLE == 1) {SLOGE("[libshowlogo: %s %d]allocate logo buffer fail, size=0x%08x \n",__FUNCTION__,__LINE__ , LOGO_BUFFER_SIZE);}goto error_return;}// (1) skip the image headerlen = read(fd, logo_addr, 512);if (len < 0){if (MTK_LOG_ENABLE == 1) {SLOGE("[libshowlogo: %s %d]read from logo addr for 512B is failed! \n",__FUNCTION__,__LINE__);}goto error_return;}// get the imagelen = read(fd, logo_addr, LOGO_BUFFER_SIZE - 512); //获取logo数据到logo_addr指向的内存,前512字节跳过if (len < 0){if (MTK_LOG_ENABLE == 1) {SLOGE("[libshowlogo: %s %d]read from logo addr for buffer is failed! \n",__FUNCTION__,__LINE__);}goto error_return;}close(fd);if (show_animationm_ver > 0){unsigned int *pinfo = (unsigned int*)logo_addr;if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]pinfo[0]=%d, pinfo[1]=%d\n", __FUNCTION__,__LINE__, pinfo[0], pinfo[1]);}if ((show_animationm_ver == VERION_WIRELESS_CHARGING_ANIMATION) && (pinfo[0] < ANIM_V2_LOGO_NUM)){set_anim_version(VERION_NEW_ANIMATION);}if (pinfo[0] < ANIM_V1_LOGO_NUM){kernel_logo_position = ANIM_V0_LOGO_NUM - 1;set_anim_version(VERION_OLD_ANIMATION);}}if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]show_animationm_ver = :%d",__FUNCTION__,__LINE__ ,show_animationm_ver);}return;error_return:if(fd >= 0){close(fd);}free_fstab();sleep(3);error_flag = 1;if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d] error return !!!\n",__FUNCTION__,__LINE__);}// to prevent interlace operation with MD reset
}
anim_fb_init()
framebuffer初始化、设置屏幕信息等。
vendor/mediatek/proprietary/external/libshowlogo/charging_animation.cpp
/** Charging animation framebuffer related init**/
int anim_fb_init(void)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]\n",__FUNCTION__,__LINE__);}fb_fd = open(FB_NODE_PATH, O_RDWR);if(fb_fd < 0){if (MTK_LOG_ENABLE == 1) {SLOGE("[libshowlogo: %s %d]open dev file fail, errno = %d \n",__FUNCTION__,__LINE__ , errno);}close(fb_fd);error_flag = 1;return -1;}#ifndef MTK_HWC_USE_DRM_DEVICE///dual add beginmemset((void *)&fb_info, 0, sizeof(fb_info));if (ioctl(fb_fd, MTKFB_GET_DISPLAY_PATH_INFO, &fb_info) < 0)SLOGD("ioctl error %s size %d\n", strerror(errno), sizeof(struct fb_display_path_info));pathcnt = fb_info.path_cnt;SLOGD("[libshowlogo: %s %d] pathcnt = %d\n",__FUNCTION__,__LINE__, pathcnt);
#endifioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);fb_size = finfo.line_length * vinfo.yres;dec_logo_addr = (unsigned int*) malloc(fb_size);
#ifndef MTK_HWC_USE_DRM_DEVICEif (pathcnt > 1) {lk_fb_addr =(unsigned int*)mmap(0, fb_size*6, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);} else {lk_fb_addr =(unsigned int*)mmap(0, fb_size*3, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);}
#elselk_fb_addr =(unsigned int*)mmap(0, fb_size*3, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
#endifcharging_fb_addr = (unsigned int*)((unsigned int)lk_fb_addr + fb_size);kernel_fb_addr = (unsigned int*)((unsigned int)charging_fb_addr + fb_size);fb_addr = lk_fb_addr;if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]vinfo:xres = %d, yres = %d, xres_virtual =%d, bits_per_pixel = %d,red.offset = %d,blue.offset = %d\n",__FUNCTION__, __LINE__, vinfo.xres,vinfo.yres, vinfo.xres_virtual, vinfo.bits_per_pixel,vinfo.red.offset,vinfo.blue.offset);SLOGD("[libshowlogo: %s %d]fb_size =%d, fb_addr = %p,charging_fb_addr=%p\n",__FUNCTION__, __LINE__, fb_size,fb_addr, charging_fb_addr);}if(fb_addr == NULL || charging_fb_addr == NULL){if (MTK_LOG_ENABLE == 1) {SLOGE("ChargingAnimation mmap fail\n");}
#ifndef MTK_HWC_USE_DRM_DEVICEif (pathcnt > 1) {munmap(lk_fb_addr, fb_size*6);} else {munmap(lk_fb_addr, fb_size*2);}
#elsemunmap(lk_fb_addr, fb_size*2);
#endifclose(fb_fd);error_flag = 1;return -1;}phical_screen.bits_per_pixel = vinfo.bits_per_pixel;phical_screen.fill_dst_bits = vinfo.bits_per_pixel;phical_screen.red_offset = vinfo.red.offset;phical_screen.blue_offset = vinfo.blue.offset;phical_screen.width = vinfo.xres;phical_screen.height = vinfo.yres;phical_screen.allignWidth = finfo.line_length/(vinfo.bits_per_pixel/8);phical_screen.needAllign = 1;phical_screen.need180Adjust = 1;phical_screen.fb_size = fb_size;if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]MTK_LCM_PHYSICAL_ROTATION = %s\n",__FUNCTION__,__LINE__, MTK_LCM_PHYSICAL_ROTATION);}if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]charge_animation_rotation = %d\n",__FUNCTION__,__LINE__, charge_animation_rotation);}if(270 == charge_animation_rotation){//270phical_screen.rotation = 270;} else if(90 == charge_animation_rotation){//90phical_screen.rotation = 90;} else if((180 == charge_animation_rotation) && (phical_screen.need180Adjust == 1)){//180phical_screen.rotation = 180;} else {phical_screen.rotation = 0;}#ifndef MTK_HWC_USE_DRM_DEVICEif (pathcnt > 1) {for(unsigned int i = 0; i < pathcnt; i++){phical_screenArr[i].width = fb_info.xres[i];phical_screenArr[i].height = fb_info.yres[i];phical_screenArr[i].needAllign = 1;phical_screenArr[i].need180Adjust = 1;fb_addrArr[i] = (unsigned int*)((unsigned int)kernel_fb_addr + fb_size * i);phical_screenArr[i].bits_per_pixel = vinfo.bits_per_pixel;phical_screenArr[i].fill_dst_bits = vinfo.bits_per_pixel;phical_screenArr[i].red_offset = vinfo.red.offset;phical_screenArr[i].blue_offset = vinfo.blue.offset;phical_screenArr[i].allignWidth = fb_info.line_length[i]/(vinfo.bits_per_pixel/8);phical_screenArr[i].fb_size = fb_info.line_length[i] * fb_info.yres[i];dec_logo_addrArr[i] = (unsigned int*) malloc(phical_screenArr[i].fb_size);SLOGD("[libshowlogo: %s %d] x = %d, y= %d , fb_info.line_length=%d , fb_size=%d addr 0x%p\n",__FUNCTION__,__LINE__,fb_info.xres[i], fb_info.yres[i], fb_info.line_length[i], phical_screenArr[i].fb_size, fb_addrArr[i]);if(ORIENTATION_270 == charge_animation_rotation){phical_screenArr[i].rotation = 270;} else if(ORIENTATION_90 == charge_animation_rotation){phical_screenArr[i].rotation = 90;} else if((ORIENTATION_180 == charge_animation_rotation) && (phical_screen.need180Adjust == 1)){//180phical_screenArr[i].rotation = 180;} else {phical_screenArr[i].rotation = 0;}}}
#endifif (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo]phical_screen: width= %d,height= %d,bits_per_pixel =%d,needAllign = %d,allignWidth=%d rotation =%d ,need180Adjust = %d\n",phical_screen.width, phical_screen.height,phical_screen.bits_per_pixel, phical_screen.needAllign,phical_screen.allignWidth, phical_screen.rotation, phical_screen.need180Adjust);SLOGD("[libshowlogo: %s %d]show old animtion= 1, running show_animationm_ver %d\n",__FUNCTION__,__LINE__, show_animationm_ver);SLOGD("[libshowlogo: %s %d]draw_anim_mode = 1, running mode %d\n",__FUNCTION__,__LINE__, draw_anim_mode);}return 0;
}
charging_control()函数
充电指示灯及充电动画显示的控制。
/mediatek/proprietary/external/charger/charging_control.cpp
void charging_control()
{int ret = 0;pthread_attr_t attr, attrd, attrl;pthread_t uevent_thread, draw_thread;//charging led controlif (!is_charging_source_available()) { //return (usb_online || ac_online || wireless_online || vchr >= 2500);lights_exit();}pthread_mutex_init(&mutexlstate, NULL);pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_attr_init(&attr);pthread_attr_init(&attrd);pthread_attr_init(&attrl);inDraw = 0;ret = pthread_create(&uevent_thread, &attr, uevent_thread_routine, NULL); //创建处理充电事件的线程if (ret != 0){KPOC_LOGI("create uevt pthread failed.\n");exit_charger(EXIT_ERROR_SHUTDOWN);}firstTime = 1;ret = pthread_create(&draw_thread, &attrd, draw_thread_routine, NULL); //创建处理充电动画绘制的线程if (ret != 0){KPOC_LOGI("create draw pthread failed.\n");exit_charger(EXIT_ERROR_SHUTDOWN);}
}
uevent_thread_routine()函数
监听系统事件,当事件为电池状态变化时,根据当前充电状态和电池电量调整充电指示灯的状态。
static void* uevent_thread_routine(__attribute__((unused))void *arg)
{char buf[1024];int len;if (!uevent_init()){KPOC_LOGI("uevent_init failed.\n");return 0;}while (1){len = uevent_next_event(buf, sizeof(buf) - 1);if (len > 0) {if (!on_uevent(buf, len))break;}}pthread_exit(NULL);return NULL;
}static int on_uevent(const char *buf, __attribute__((unused))int len_buf)
{
#ifdef VERBOSE_OUTPUTKPOC_LOGI("on_uevent, %s\n", buf);
#endifif (!strcasestr(buf, UEVENT_BATTERY_CHANGE))return 1;//if ac or usb onlineif (is_charging_source_available()){bc = get_capacity();if (bc >= 90) {lights_full();} else {if (nCurrentState != LIGHTS_STATE_CHGON)set_light_state(LIGHTS_CHGON);lights_on();}}elseexit_charger(EXIT_CHARGING_MODE);return 1;
}
draw_thread_routine()函数
vendor/mediatek/proprietary/external/charger/charging_control.cpp
static void* draw_thread_routine(__attribute__((unused))void *arg)
{int bc;int fd_fb, err =0;char filename[32] = {0};do { //死循环KPOC_LOGI("draw thread working2...\n");// move here to avoid suspend when syncing with surfaceflingerif(firstTime){// make sure charging source online when in KPOC mode// add 2s toleranceif(wait_until(is_charging_source_available,charging_source_waiting_duration_ms,charging_source_waiting_interval_ms)){KPOC_LOGI("wait until charging source available\n");}else{KPOC_LOGI("charging source not available for %d ms at KPOC starup\n",charging_source_waiting_duration_ms);}firstTime = 0;}inDraw = 1;// check the bc offest valuebc = get_capacity(); //获取电池电量draw_with_interval(bootlogo_show_charging, bc, nChgAnimDuration_msec, nCbInterval_msec); //nChgAnimDuration_msec = 6000; nCbInterval_msec = 200;stop_backlight(); //关闭背光// @@@ draw fb again to refresh ddpbootlogo_show_charging(bc, 1);/* make fb blank */err = snprintf(filename, sizeof(filename), "/dev/graphics/fb0");if (err < 0) {KPOC_LOGI("Failed at snprintf: %s\n", strerror(errno));break;}fd_fb = open(filename, O_RDWR);if (fd_fb < 0) {KPOC_LOGI("Failed to open fb0 device: %s", strerror(errno));break;}err = ioctl(fd_fb, FBIOBLANK, FB_BLANK_POWERDOWN);if (err < 0) {KPOC_LOGI("Failed to blank fb0 device: %s", strerror(errno));}if (fd_fb >= 0)close(fd_fb);request_suspend(true);inDraw = 0;pthread_mutex_lock(&mutex);pthread_cond_wait(&cond, &mutex);pthread_mutex_unlock(&mutex);} while(1);pthread_exit(NULL);return NULL;
}
draw_with_interval()函数
控制动画绘制的时长和间隔。total_time_msec = 6000; interval_msec = 200;
// total_time : ms
// interval : ms
static void draw_with_interval(void (*func)(int, int), int bc, int total_time_msec, int interval_msec)
{struct timeval start;int resume_started = 0, backlight_started = 0, cnt = 0;int fd_fb, err = 0;char filename[32] = {0};gettimeofday(&start, NULL); //Get the current time of day, putting it into *TV.while(!time_exceed(start, total_time_msec) && !key_trigger_suspend) //只要不超时就循环绘制{// check if need to draw animation before performing drawingif (!is_charging_source_available())return;if (!resume_started) {resume_started = 1;request_suspend(false);/* make fb unblank */err = snprintf(filename, sizeof(filename), "/dev/graphics/fb0");if (err < 0) {KPOC_LOGI("Failed at snprintf: %s\n", strerror(errno));return;}fd_fb = open(filename, O_RDWR);if (fd_fb < 0) {KPOC_LOGI("Failed to open fb0 device: %s", strerror(errno));}err = ioctl(fd_fb, FBIOBLANK, FB_BLANK_UNBLANK);if (err < 0) {KPOC_LOGI("Failed to unblank fb0 device: %s", strerror(errno));}if (fd_fb >= 0)close(fd_fb);}func(bc, ++cnt);if (!backlight_started) {backlight_started = 1;usleep(1000);start_backlight();}KPOC_LOGI("draw_with_interval... key_trigger_suspend = %d\n",key_trigger_suspend);usleep(interval_msec*1000);}
}
bool time_exceed(struct timeval start, int duration_msec)
{struct timeval now;gettimeofday(&now, NULL);if((now.tv_sec - start.tv_sec)*1000000 + now.tv_usec - start.tv_usec > duration_msec*1000) //单位转换后再比较return true;elsereturn false;
}
timeval结构体
/* A time value that is accurate to the nearestmicrosecond but also has a range of years. */
struct timeval
{
#ifdef __USE_TIME_BITS64__time64_t tv_sec; /* Seconds. */__suseconds64_t tv_usec; /* Microseconds. */
#else__time_t tv_sec; /* Seconds. */__suseconds_t tv_usec; /* Microseconds. */
#endif
};
bootlogo_show_charging()函数
绘制充电动画的入口函数。
vendor/mediatek/proprietary/external/charger/bootlogo.cpp
/** Show charging animation with battery capacity**/
void bootlogo_show_charging(int capacity, int cnt)
{KPOC_LOGI("[ChargingAnimation: %s %d]%d, %d\n",__FUNCTION__,__LINE__, capacity, cnt);if (get_battnotify_status()){KPOC_LOGI("[ChargingAnimation: %s %d] show_charger_error_logo, get_battnotify_status()= %d \n",__FUNCTION__,__LINE__, get_battnotify_status());show_charger_ov_logo();return;}if (showLowBattLogo){KPOC_LOGI("[ChargingAnimation: %s %d] show_low_battery , showLowBattLogo = %d \n",__FUNCTION__,__LINE__,showLowBattLogo);show_low_battery();return;}show_battery_capacity(capacity);
}
static const char *bat_notify_path[] = {"/sys/devices/platform/charger/BatteryNotify","/sys/devices/platform/mt-battery/BatteryNotify",
};/** return value:* 1: abnormal status* 0: normal status* If path is not found, return 0*/
int get_battnotify_status()
{int i = 0;int bat_status = 0;/* Find path for battery status */for (i = 0; i < ARRAY_SIZE(bat_notify_path); i++) {bat_status = get_int_value(bat_notify_path[i]);if (bat_status != -1)break;}KPOC_LOGI("charger battStatus=%d, idx=%d\n", bat_status, i);if (bat_status > 0)return 1;return 0;
}
show_battery_capacity()函数
vendor/mediatek/proprietary/external/libshowlogo/charging_animation.cpp
/** Show charging animation with battery capacity**/
void show_battery_capacity(unsigned int capacity)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]capacity =%d\n",__FUNCTION__,__LINE__, capacity);}if (draw_anim_mode == (DRAW_ANIM_MODE_FB)) {anim_fb_addr_switch(); //切换缓冲区
#if defined(MSSI_MTK_PUMP_EXPRESS_SUPPORT) || defined(MSSI_MTK_PUMP_EXPRESS_PLUS_SUPPORT) || defined(MSSI_MTK_PUMP_EXPRESS_PLUS_20_SUPPORT) //快充相关if (2 != show_animationm_ver && get_fast_charging_state()) {fill_animation_battery_fast_charging(capacity, (void *)fb_addr, dec_logo_addr, logo_addr, phical_screen, draw_anim_mode);} else {fill_animation_battery_by_ver(capacity, (void *)fb_addr, dec_logo_addr, logo_addr, phical_screen, show_animationm_ver);}
#elsefill_animation_battery_by_ver(capacity, (void *)fb_addr, dec_logo_addr, logo_addr, phical_screen, show_animationm_ver);
#endifanim_fb_disp_update(); //更新缓冲区} else {ARect tmpRect;tmpRect.left = 0;tmpRect.top = 0;tmpRect.right = phical_screen.width;tmpRect.bottom = phical_screen.height;status_t lockResult = surface->lock(&outBuffer, &tmpRect);if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]outBuffer.bits = %d, surface->lock return = 0x%08x,\n",__FUNCTION__,__LINE__, (int)outBuffer.bits,lockResult);}if (0 == lockResult){
#if defined(MSSI_MTK_PUMP_EXPRESS_SUPPORT) || defined(MSSI_MTK_PUMP_EXPRESS_PLUS_SUPPORT) || defined(MSSI_MTK_PUMP_EXPRESS_PLUS_20_SUPPORT)if (2 != show_animationm_ver && get_fast_charging_state()) {fill_animation_battery_fast_charging(capacity, (void *)outBuffer.bits, dec_logo_addr, logo_addr, phical_screen, draw_anim_mode);} else {fill_animation_battery_by_ver(capacity, (void *)outBuffer.bits, dec_logo_addr, logo_addr, phical_screen, show_animationm_ver);}
#elsefill_animation_battery_by_ver(capacity, (void *)outBuffer.bits, dec_logo_addr, logo_addr, phical_screen, show_animationm_ver);
#endifsurface->unlockAndPost();}}
}
切换缓冲区的主要目的是在显示动画时实现平滑的画面刷新。
在双缓冲模式下,通常会使用两块帧缓冲区,一块用于显示当前画面,另一块用于准备下一帧的画面。当当前帧显示完成时,就可以立即切换到另一块缓冲区继续显示,而不必等待下一帧数据准备完毕。这样可以避免出现画面撕裂或者闪烁的现象,提高了显示的流畅度和质量。
static unsigned int *charging_fb_addr = NULL;
static unsigned int *kernel_fb_addr = NULL;
static unsigned int use_double_addr = 0;/** Charging animation framebuffer switch buffer**/
void anim_fb_addr_switch(void)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]use_double_addr =%d \n",__FUNCTION__,__LINE__,use_double_addr);}if(use_double_addr == 0) {use_double_addr++;fb_addr = kernel_fb_addr;} else {use_double_addr = 0;fb_addr = charging_fb_addr;}if (MTK_LOG_ENABLE == 1) {SLOGD("[libshowlogo: %s %d]fb_addr =%d \n",__FUNCTION__,__LINE__, (int)fb_addr);}
}
fill_animation_battery_by_ver()函数
通过传入的show_animationm_ver
参数选择不同的绘制样式。
VERION_OLD_ANIMATION
: show 4 recatangle growing animation without battery number
VERION_NEW_ANIMATION
: show wave animation with battery number
VERION_WIRELESS_CHARGING_ANIMATION
: show wireless charging animation
这里show_animationm_ver = VERION_NEW_ANIMATION
vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
/** Show charging animation by version**/
void fill_animation_battery_by_ver(int capacity, void *fill_addr, void * dec_logo_addr, void * logo_addr,LCM_SCREEN_T phical_screen, int version)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]version : %d\n",__FUNCTION__,__LINE__, version);}switch (version){case VERION_OLD_ANIMATION:fill_animation_battery_old(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);break;case VERION_NEW_ANIMATION:fill_animation_battery_new(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);break;case VERION_WIRELESS_CHARGING_ANIMATION:fill_animation_battery_wireless_charging(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);break;default:fill_animation_battery_old(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);break;}
}
fill_animation_battery_new()函数
通过大量fill_animation_xxx()
函数,绘制了不同的UI元素。大同小异,拿fill_animation_logo(FULL_BATTERY_INDEX, fill_addr, dec_logo_addr, logo_addr,phical_screen)
举例:
index
:logo的索引值。
fill_addr
:填充屏幕的位置。
dec_logo_addr
:解压后的logo地址。
logo_addr
:原始logo地址。
phical_screen
:LCM屏幕参数。
/** Show new charging animation**/
void fill_animation_battery_new(int capacity, void *fill_addr, void * dec_logo_addr, void * logo_addr, LCM_SCREEN_T phical_screen)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]capacity : %d\n",__FUNCTION__,__LINE__, capacity);}//图片分配地址并初始化if (percent_pic_addr==NULL) {percent_pic_addr=(unsigned short*)malloc(((charg_anim_ui_dimen.percent_right - charg_anim_ui_dimen.percent_left)*(charg_anim_ui_dimen.percent_bottom - charg_anim_ui_dimen.percent_top)*4)*sizeof(unsigned short));memset(percent_pic_addr,0,(((charg_anim_ui_dimen.percent_right - charg_anim_ui_dimen.percent_left)*(charg_anim_ui_dimen.percent_bottom - charg_anim_ui_dimen.percent_top)*4)*sizeof(unsigned short)));}if (top_animation_addr==NULL) {top_animation_addr=(unsigned short*)malloc(((charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*(charg_anim_ui_dimen.top_anim_bottom - charg_anim_ui_dimen.top_anim_top)*4)*sizeof(unsigned short));memset(top_animation_addr,0,(((charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*(charg_anim_ui_dimen.top_anim_bottom - charg_anim_ui_dimen.top_anim_top)*4)*sizeof(unsigned short)));}RECT_REGION_T percent_location_rect = {charg_anim_ui_dimen.percent_left,charg_anim_ui_dimen.percent_top,charg_anim_ui_dimen.percent_right,charg_anim_ui_dimen.percent_bottom};if (capacity >= 100) {//show_logo(37); // battery 100fill_animation_logo(FULL_BATTERY_INDEX, fill_addr, dec_logo_addr, logo_addr,phical_screen); //显示满电时的logo,满电logo是一个单独的图片} else if (capacity < 10) { //显示低电时logo,低电logo由橙色波浪的电量图片、单个电量数字和百分号组成if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]charging_low_index = %d\n",__FUNCTION__,__LINE__, charging_low_index);}charging_low_index ++ ;fill_animation_logo(LOW_BAT_ANIM_START_0 + charging_low_index, fill_addr, dec_logo_addr, logo_addr,phical_screen);fill_animation_number(NUMBER_PIC_START_0 + capacity, 1, fill_addr, logo_addr, phical_screen);fill_animation_dynamic(NUMBER_PIC_PERCENT, percent_location_rect, fill_addr, percent_pic_addr, logo_addr, phical_screen);if (charging_low_index >= 9) charging_low_index = 0;} else { //显示非低电时logo,非低电logo由电池背景,蓝色线条、两个电量数字和百分号组成unsigned int capacity_grids = 0;//static RECT_REGION_T battery_rect = {CAPACITY_LEFT,CAPACITY_TOP,CAPACITY_RIGHT,CAPACITY_BOTTOM};capacity_grids = charg_anim_ui_dimen.cap_bottom - (charg_anim_ui_dimen.cap_bottom - charg_anim_ui_dimen.cap_top) * (capacity - 10) / 90; //电量格数if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]capacity_grids : %d,charging_animation_index = %d\n",__FUNCTION__,__LINE__, capacity_grids,charging_animation_index);}//backgroundfill_animation_logo(ANIM_V1_BACKGROUND_INDEX, fill_addr, dec_logo_addr, logo_addr,phical_screen);fill_animation_line(ANIM_LINE_INDEX, capacity_grids, fill_addr, logo_addr, phical_screen);fill_animation_number(NUMBER_PIC_START_0 + (capacity/10), 0, fill_addr, logo_addr, phical_screen);fill_animation_number(NUMBER_PIC_START_0 + (capacity%10), 1, fill_addr, logo_addr, phical_screen);fill_animation_dynamic(NUMBER_PIC_PERCENT, percent_location_rect, fill_addr, percent_pic_addr, logo_addr, phical_screen);if (capacity <= 90){RECT_REGION_T top_animation_rect = {charg_anim_ui_dimen.top_anim_left, capacity_grids - (charg_anim_ui_dimen.top_anim_bottom - charg_anim_ui_dimen.top_anim_top), charg_anim_ui_dimen.top_anim_right, capacity_grids};//top_animation_rect.bottom = capacity_grids;//top_animation_rect.top = capacity_grids - top_animation_height;charging_animation_index++;//show_animation_dynamic(15 + charging_animation_index, top_animation_rect, top_animation_addr);//播放蓝色的充电波浪fill_animation_dynamic(BAT_ANIM_START_0 + charging_animation_index, top_animation_rect, fill_addr,top_animation_addr, logo_addr, phical_screen);if (charging_animation_index >= 9) charging_animation_index = 0;}}}
fill_animation_logo()函数
从屏幕左上角零点处绘制图像。
/** Fill a screen size buffer with logo content**/
void fill_animation_logo(int index, void *fill_addr, void * dec_logo_addr, void * logo_addr, LCM_SCREEN_T phical_screen)
{LOGO_PARA_T logo_info;int logo_width;int logo_height;int raw_data_size;int logo_index = index;int logo_offset = -1;g_dec_logo_addr = dec_logo_addr;logo_offset = calculate_logo_offset(index, dec_logo_addr, logo_addr, phical_screen);if(logo_offset == -1){SLOGD("[calculate_logo_offset: %s %d]Resolution not supported\n",__FUNCTION__,__LINE__);return;}logo_index = logo_index + logo_offset;//检查logo索引的有效性if(check_logo_index_valid(logo_index, logo_addr, &logo_info) != CHECK_LOGO_BIN_OK)return;//资源文件大小raw_data_size = decompress_logo((void*)logo_info.inaddr, dec_logo_addr, logo_info.logolen, phical_screen.fb_size);if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]raw_data_size = %d\n",__FUNCTION__,__LINE__, raw_data_size);}//RECT_REGION_T rect = {0, 0, phical_screen.width, phical_screen.height};logo_width =phical_screen.width;logo_height = phical_screen.height;if (phical_screen.rotation == 270 || phical_screen.rotation == 90) {logo_width = phical_screen.height;logo_height = phical_screen.width;}//单个像素点的大小(32位)if (0 == bits) {if (raw_data_size == logo_width*logo_height*4) {bits = 32;} else if (raw_data_size == logo_width*logo_height*2) {bits = 16;} else {if (MTK_LOG_ENABLE == 1) {SLOGE("[show_animation_common: %s %d]Logo data error\n",__FUNCTION__,__LINE__);}return;}if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]bits = %d\n",__FUNCTION__,__LINE__, bits);}}RECT_REGION_T rect = {0, 0, logo_width, logo_height};fill_rect_with_content(fill_addr, rect, dec_logo_addr, phical_screen, bits);
}
fill_animation_number()函数
绘制电量百分数的图像。多位数会根据number_position的不同,绘制在不同的地方。
/** Fill a rectangle with number logo content** number_position: 0~1st number, 1~2nd number*/
void fill_animation_number(int index, unsigned int number_position, void *fill_addr, void * logo_addr, LCM_SCREEN_T phical_screen)
{int logo_index = index;int logo_offset = -1;logo_offset = calculate_logo_offset(index, g_dec_logo_addr, logo_addr, phical_screen);if(logo_offset == -1){SLOGD("[calculate_logo_offset: %s %d]Resolution not supported\n",__FUNCTION__,__LINE__);return;}logo_index = logo_index + logo_offset;if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]index= %d, number_position = %d\n",__FUNCTION__,__LINE__, index, number_position);}//为数字图片分配内存并初始化if(number_pic_addr==NULL) {number_pic_addr= (unsigned short*)malloc(((charg_anim_ui_dimen.num_right - charg_anim_ui_dimen.num_left)*(charg_anim_ui_dimen.num_bottom - charg_anim_ui_dimen.num_top)*4)*sizeof(unsigned short));memset(number_pic_addr,0,(((charg_anim_ui_dimen.num_right - charg_anim_ui_dimen.num_left)*(charg_anim_ui_dimen.num_bottom - charg_anim_ui_dimen.num_top)*4)*sizeof(unsigned short)));}LOGO_PARA_T logo_info;int raw_data_size;//检查logo索引的有效性if(check_logo_index_valid(logo_index, logo_addr, &logo_info) != CHECK_LOGO_BIN_OK)return;number_pic_size = (charg_anim_ui_dimen.num_right-charg_anim_ui_dimen.num_left)*(charg_anim_ui_dimen.num_bottom-charg_anim_ui_dimen.num_top)*4;// draw default number rect,raw_data_size = decompress_logo((void*)logo_info.inaddr, (void*)number_pic_addr, logo_info.logolen, number_pic_size);if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]raw_data_size = %d\n",__FUNCTION__,__LINE__, raw_data_size);}//static RECT_REGION_T number_location_rect = {NUMBER_LEFT,NUMBER_TOP,NUMBER_RIGHT,NUMBER_BOTTOM};//数字可能有两个,所以要通过number_position控制个位和十位数字的位置RECT_REGION_T battery_number_rect = {charg_anim_ui_dimen.num_left + (charg_anim_ui_dimen.num_right - charg_anim_ui_dimen.num_left)*number_position,charg_anim_ui_dimen.num_top,charg_anim_ui_dimen.num_right + (charg_anim_ui_dimen.num_right - charg_anim_ui_dimen.num_left)*number_position,charg_anim_ui_dimen.num_bottom};if (0 == bits) {if (raw_data_size == (charg_anim_ui_dimen.num_right - charg_anim_ui_dimen.num_left)*(charg_anim_ui_dimen.num_bottom - charg_anim_ui_dimen.num_top)*4) {bits = 32;} else if (raw_data_size == (charg_anim_ui_dimen.num_right - charg_anim_ui_dimen.num_left)*(charg_anim_ui_dimen.num_bottom - charg_anim_ui_dimen.num_top)*2) {bits = 16;} else {if (MTK_LOG_ENABLE == 1) {SLOGE("[show_animation_common: %s %d]Logo data error\n",__FUNCTION__,__LINE__);}return;}if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]bits = %d\n",__FUNCTION__,__LINE__, bits);}}if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]bits = %d\n",__FUNCTION__,__LINE__, bits);}fill_rect_with_content(fill_addr, battery_number_rect, number_pic_addr,phical_screen, bits);
}
fill_animation_dynamic()函数
在特定位置绘制特定图像。
/** Fill a rectangle with logo content**/
void fill_animation_dynamic(int index, RECT_REGION_T rect, void *fill_addr, void * dec_logo_addr, void * logo_addr, LCM_SCREEN_T phical_screen)
{LOGO_PARA_T logo_info;int raw_data_size;int logo_index = index;int logo_offset = -1;g_dec_logo_addr = dec_logo_addr;logo_offset = calculate_logo_offset(index, dec_logo_addr, logo_addr, phical_screen);if(logo_offset == -1){SLOGD("[calculate_logo_offset: %s %d]Resolution not supported\n",__FUNCTION__,__LINE__);return;}logo_index = logo_index + logo_offset;//检查logo索引的有效性if(check_logo_index_valid(logo_index, logo_addr, &logo_info) != CHECK_LOGO_BIN_OK)return;raw_data_size = decompress_logo((void*)logo_info.inaddr, (void*)dec_logo_addr, logo_info.logolen, (rect.right-rect.left)*(rect.bottom-rect.top)*4);if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]raw_data_size = %d\n",__FUNCTION__,__LINE__, raw_data_size);}if (0 == bits) {if (raw_data_size == (rect.right-rect.left)*(rect.bottom-rect.top)*4) {bits = 32;} else if (raw_data_size == (rect.right-rect.left)*(rect.bottom-rect.top)*2) {bits = 16;} else {if (MTK_LOG_ENABLE == 1) {SLOGE("[show_animation_common: %s %d]Logo data error\n",__FUNCTION__,__LINE__);}return;}if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]bits = %d\n",__FUNCTION__,__LINE__, bits);}}if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]bits = %d\n",__FUNCTION__,__LINE__, bits);}fill_rect_with_content(fill_addr, rect, dec_logo_addr, phical_screen, bits);
}
fill_animation_line()函数
/** Fill a line with special color**/
void fill_animation_line(int index, unsigned int capacity_grids, void *fill_addr, void * logo_addr, LCM_SCREEN_T phical_screen)
{int logo_index = index;int logo_offset = -1;logo_offset = calculate_logo_offset(index, g_dec_logo_addr, logo_addr, phical_screen);if(logo_offset == -1){SLOGD("[calculate_logo_offset: %s %d]Resolution not supported\n",__FUNCTION__,__LINE__);return;}logo_index = logo_index + logo_offset;LOGO_PARA_T logo_info;int raw_data_size;if(line_pic_addr==NULL) {line_pic_addr=(unsigned short*)malloc(((charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*4)*sizeof(unsigned short));memset(line_pic_addr,0,(((charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*4)*sizeof(unsigned short)));}if(check_logo_index_valid(logo_index, logo_addr, &logo_info) != CHECK_LOGO_BIN_OK)return;line_pic_size= (charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*4;raw_data_size = decompress_logo((void*)logo_info.inaddr, (void*)line_pic_addr, logo_info.logolen, line_pic_size);if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]raw_data_size = %d\n",__FUNCTION__,__LINE__, raw_data_size);}if (0 == bits) {if (raw_data_size == (charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*4) {bits = 32;} else if (raw_data_size == (charg_anim_ui_dimen.top_anim_right - charg_anim_ui_dimen.top_anim_left)*2) {bits = 16;} else {if (MTK_LOG_ENABLE == 1) {SLOGE("[show_animation_common: %s %d]Logo data error\n",__FUNCTION__,__LINE__);}return;}if (MTK_LOG_ENABLE == 1) {SLOGD("[show_animation_common: %s %d]bits = %d\n",__FUNCTION__,__LINE__, bits);}}RECT_REGION_T rect = {charg_anim_ui_dimen.cap_left, charg_anim_ui_dimen.cap_top, charg_anim_ui_dimen.cap_right, charg_anim_ui_dimen.cap_bottom};int i = capacity_grids;for(; i < charg_anim_ui_dimen.cap_bottom; i++){rect.top = i;rect.bottom = i+1;fill_rect_with_content(fill_addr, rect, line_pic_addr, phical_screen, bits);}
}
fill_rect_with_content()函数
指定的矩形区域内填充具有logo内容的像素数据。
/** Draw a rectangle region with logo content****/void fill_rect_with_content(void *fill_addr, RECT_REGION_T rect, void *src_addr, LCM_SCREEN_T phical_screen, unsigned int bits)
{if (MTK_LOG_ENABLE == 1) {SLOGD("[show_logo_common: %s %d]\n",__FUNCTION__,__LINE__);}if (check_rect_valid(rect) != CHECK_RECT_OK)return;if (bits == 32) {if (phical_screen.fill_dst_bits == 16) {fill_rect_with_content_by_16bit_argb8888((unsigned short *)fill_addr, rect, (unsigned int *)src_addr, phical_screen);} else if (phical_screen.fill_dst_bits == 32){fill_rect_with_content_by_32bit_argb8888((unsigned int *)fill_addr, rect, (unsigned int *)src_addr, phical_screen, bits);} else {if (MTK_LOG_ENABLE == 1) {SLOGD("[show_logo_common %s %d]unsupported phical_screen.fill_dst_bits =%d\n",__FUNCTION__,__LINE__, phical_screen.fill_dst_bits );}}} else {if (phical_screen.fill_dst_bits == 16) {fill_rect_with_content_by_16bit_rgb565((unsigned short *)fill_addr, rect, (unsigned short *)src_addr, phical_screen);} else if (phical_screen.fill_dst_bits == 32){fill_rect_with_content_by_32bit_rgb565((unsigned int *)fill_addr, rect, (unsigned short *)src_addr, phical_screen, bits);} else {if (MTK_LOG_ENABLE == 1) {SLOGD("[show_logo_common %s %d]unsupported phical_screen.fill_dst_bits =%d\n",__FUNCTION__,__LINE__, phical_screen.fill_dst_bits );}}}
}
fill_rect_with_content_by_32bit_argb8888()函数
在一个指定的矩形区域内填充具有logo内容的32位色彩的像素数据。
/** Draw a rectangle region (32 bits perpixel) with logo content****/
void fill_rect_with_content_by_32bit_argb8888(unsigned int *fill_addr, RECT_REGION_T rect, unsigned int *src_addr, LCM_SCREEN_T phical_screen, unsigned int bits)
{LOG_ANIM("[show_logo_common: %s %d]\n",__FUNCTION__,__LINE__);int virtual_width = phical_screen.needAllign == 0? phical_screen.width:phical_screen.allignWidth;int virtual_height = phical_screen.height;int i = 0;int j = 0;unsigned int * dst_addr = fill_addr;unsigned int * color_addr = src_addr;for(i = rect.top; i < rect.bottom; i++){for(j = rect.left; j < rect.right; j++){color_addr = (unsigned int *)src_addr;src_addr++;switch (phical_screen.rotation){case 90:dst_addr = fill_addr + (virtual_width * j + virtual_width - i - 1);break;case 270:dst_addr = fill_addr + ((virtual_width * (virtual_height - j - 1)+ i));break;case 180:// adjust fill in addressdst_addr = fill_addr + virtual_width * (virtual_height - i)- j-1-(virtual_width-phical_screen.width);break;default:dst_addr = fill_addr + virtual_width * i + j;}fill_point_buffer(dst_addr, *color_addr, phical_screen, bits);if((i == rect.top && j == rect.left) || (i == rect.bottom - 1 && j == rect.left) ||(i == rect.top && j == rect.right - 1) || (i == rect.bottom - 1 && j == rect.right - 1)){LOG_ANIM("[show_logo_common]dst_addr= 0x%08x, color_addr= 0x%08x, i= %d, j=%d\n", *dst_addr, *color_addr, i , j);}}}
}
fill_point_buffer()函数
填充屏幕单个像素点。
/** Fill one point address with source color and color pixel bits** @parameter**/
void fill_point_buffer(unsigned int *fill_addr, unsigned int src_color, LCM_SCREEN_T phical_screen, unsigned int bits)
{if (32 == phical_screen.bits_per_pixel) {if (32 == bits) {if(16 == phical_screen.blue_offset) {*fill_addr = ARGB8888_TO_ABGR8888(src_color);} else {*fill_addr = src_color;}} else {if(16 == phical_screen.blue_offset) {*fill_addr = RGB565_TO_ARGB8888(src_color);} else {*fill_addr = RGB565_TO_ABGR8888(src_color);}}} else {LOG_ANIM("[show_logo_common %s %d]not support bits_per_pixel = %d \n",__FUNCTION__,__LINE__,(int)phical_screen.bits_per_pixel);}
}
客户需求定制
关机充电时,在电量小于等于5%时,显示"30分钟充电后打开电源"(韩文)
- 预制提示语资源
制作一张带客户需求字样的bmp图片,并以“wxganl”(视项目而定)开头命名,放入对应的目录中。
vendor\mediatek\proprietary\bootable\bootloader\lk\dev\logo\wxganl\
将处理后生成的raw文件添加进RESOURCE_OBJ_LIST
列表(建议放在列表末尾)。
diff --git a/vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/rules.mk b/vendor/mediatek/proprietary/bootable/bo
otloader/lk/dev/logo/rules.mk
index ab8bb064524..837e8268b27 100644
--- a/vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/rules.mk
+++ b/vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/rules.mk
@@ -95,7 +95,8 @@ RESOURCE_OBJ_LIST += \$(BOOT_LOGO_DIR)/$(1)/$(1)_kernel.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery01.raw \$(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery02.raw \
- $(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery_remind.raw
+ $(BOOT_LOGO_DIR)/$(1)/$(1)_low_battery_remind.raw \
+ $(BOOT_LOGO_DIR)/$(1)/$(1)_bat_custom.rawendifendif
- 定义自定义图片索引值
根据raw文件在RESOURCE_OBJ_LIST
列表中的位置,定义对应的索引值。
diff --git a/vendor/mediatek/proprietary/external/libshowlogo/cust_display.h b/vendor/mediatek/proprietary/external/libshow
logo/cust_display.h
index bf26861ac45..8f8b8830a9a 100644
--- a/vendor/mediatek/proprietary/external/libshowlogo/cust_display.h
+++ b/vendor/mediatek/proprietary/external/libshowlogo/cust_display.h
@@ -140,6 +140,9 @@#define LOGOS_COUNT_FAST_CHARGING 18#define LOGOS_COUNT_WIRELESS 29-
+//added by menghui.huang start
+// custom picture index
+#define CUSTOM_PIC_INDEX 42
+//added by menghui.huang end
- 描述绘制位置
屏幕坐标系是以横屏状态下(视项目而定)左上角为零点,右侧为x轴正方向,下侧为y轴正方向。
利用Windows自带的画图工具定位图片位置。本例中,(440, 640)是一个较好的位置。
查看图片属性确定下边界和右边界。
下边界 = 起始位置纵坐标 + 图片本身高度;本例中 下边界 = 640 + 39 = 679
右边界 = 起始位置横坐标 + 图片本身宽度; 本例中 右边界 = 440 + 404 = 844
在代码中定义对应的位置信息。
diff --git a/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.h b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.h
index c9e2ac924bb..e09e514b730 100755
--- a/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.h
+++ b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.h
@@ -69,6 +69,14 @@ typedef struct {// version_0 animation#define ANIM_V0_REGIONS 4#define ANIM_V0_SPACE_AFTER_REGION 4
+
+//added by menghui.huang start
+#define CUSTOM_PIC_LEFT 440
+#define CUSTOM_PIC_TOP 640
+#define CUSTOM_PIC_RIGHT 844
+#define CUSTOM_PIC_BOTTOM 679
+//added by menghui.huang end
+
定义矩形参数
// define the rectangle parameters
typedef struct {int left, top, right, bottom;
} RECT_REGION_T;
diff --git a/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_
common.c
index a57a5cafede..9c0ad346569 100755
--- a/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
+++ b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.cRECT_REGION_T percent_location_rect = {charg_anim_ui_dimen.percent_left,charg_anim_ui_dimen.percent_top,charg_anim_ui_dimen.percent_right,charg_anim_ui_dimen.percent_bottom};
+ RECT_REGION_T custom_location_rect = {CUSTOM_PIC_LEFT, CUSTOM_PIC_TOP, CUSTOM_PIC_RIGHT, CUSTOM_PIC_BOTTOM};
- 为自定义图片分配内存并初始化
diff --git a/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
index a57a5cafede..9c0ad346569 100755
--- a/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
+++ b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
@@ -103,6 +103,7 @@ int getValue(char* key, char* defValue);
+++ b/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
@@ -103,6 +103,7 @@ int getValue(char* key, char* defValue);static unsigned short *number_pic_addr;static unsigned short *line_pic_addr;static unsigned short *percent_pic_addr;
+static unsigned short *custom_pic_addr;static unsigned short *top_animation_addr;static int number_pic_size; //size
@@ -1141,11 +1142,18 @@ void fill_animation_battery_new(int capacity, void *fill_addr, void * dec_logo_apercent_pic_addr=(unsigned short*)malloc(((charg_anim_ui_dimen.percent_right - charg_anim_ui_dimen.percent_left)*(charg_anim_ui_dimen.percent_bottom - charg_anim_ui_dimen
.percent_top)*4)*sizeof(unsigned short));memset(percent_pic_addr,0,(((charg_anim_ui_dimen.percent_right - charg_anim_ui_dimen.percent_left)*(charg_anim_ui_dimen.percent_bottom - charg_anim_ui_dimen.percent_top)*
4)*sizeof(unsigned short)));}
+ added by menghui.huang start
+ if (custom_pic_addr==NULL) {
+ custom_pic_addr=(unsigned short*)malloc(((CUSTOM_PIC_RIGHT - CUSTOM_PIC_LEFT)*(CUSTOM_PIC_BOTTOM - CUSTOM_PIC_TOP)*4)*sizeof(unsigned short));
+ memset(custom_pic_addr,0,(((CUSTOM_PIC_RIGHT - CUSTOM_PIC_LEFT)*(CUSTOM_PIC_BOTTOM - CUSTOM_PIC_TOP)*4)*sizeof(unsigned short)));
+ }
+ //added by menghui.huang end
- 在电量<=5%时,为指定内存区域填充图像数据
@@ -1160,6 +1168,12 @@ void fill_animation_battery_new(int capacity, void *fill_addr, void * dec_logo_afill_animation_logo(LOW_BAT_ANIM_START_0 + charging_low_index, fill_addr, dec_logo_addr, logo_addr,phical_screen);fill_animation_number(NUMBER_PIC_START_0 + capacity, 1, fill_addr, logo_addr, phical_screen);fill_animation_dynamic(NUMBER_PIC_PERCENT, percent_location_rect, fill_addr, percent_pic_addr, logo_addr, phical_screen);
+ //added by menghui.huang start
+ if (capacity <= 5)
+ {
+ fill_animation_dynamic(CUSTOM_PIC_INDEX, custom_location_rect, fill_addr, custom_pic_addr, logo_addr, phical_screen);
+ }
+ //added by menghui.huang end
- 效果