关机充电动画:流程与定制
基于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=wvga
ifeq ($(strip $(BOOT_LOGO)),)
BOOT_LOGO = fwvga
endif
ifeq ($(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.cfg
EMPTY :=
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
else
ifeq ($(strip $(MTK_PUMP_EXPRESS_PLUS_SUPPORT)), yes)
SUPPORT_PUMP_EXPRESS = yes
endif
endif
# 打包后的文件
BOOT_LOGO_RESOURCE := $(BUILDDIR)/$(BOOT_LOGO_DIR)/boot_logo.raw
# 产物名
LOGO_IMAGE := $(BUILDDIR)/logo.bin
define generate_logo_executable
ifneq ($(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
endif
endef
$(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_NEW
set_anim_version(VERION_NEW_ANIMATION);
#else
set_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 FHD
SLOGD("[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*960
SLOGD("[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*800
SLOGD("[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 here
int 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 path
fd = open(rec->blk_device.c_str(), O_RDONLY); //只读方式打开rec->blk_device.c_str()文件
// get logo patition from fstab end
if(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 header
len = 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 image
len = 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 begin
memset((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);
#endif
ioctl(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_DEVICE
if (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);
}
#else
lk_fb_addr =(unsigned int*)mmap(0, fb_size*3, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
#endif
charging_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_DEVICE
if (pathcnt > 1) {
munmap(lk_fb_addr, fb_size*6);
} else {
munmap(lk_fb_addr, fb_size*2);
}
#else
munmap(lk_fb_addr, fb_size*2);
#endif
close(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){//270
phical_screen.rotation = 270;
} else if(90 == charge_animation_rotation){//90
phical_screen.rotation = 90;
} else if((180 == charge_animation_rotation) && (phical_screen.need180Adjust == 1)){//180
phical_screen.rotation = 180;
} else {
phical_screen.rotation = 0;
}
#ifndef MTK_HWC_USE_DRM_DEVICE
if (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)){//180
phical_screenArr[i].rotation = 180;
} else {
phical_screenArr[i].rotation = 0;
}
}
}
#endif
if (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 control
if (!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_OUTPUT
KPOC_LOGI("on_uevent, %s\n", buf);
#endif
if (!strcasestr(buf, UEVENT_BATTERY_CHANGE))
return 1;
//if ac or usb online
if (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();
}
}
else
exit_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 surfaceflinger
if(firstTime){
// make sure charging source online when in KPOC mode
// add 2s tolerance
if(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 value
bc = 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 ddp
bootlogo_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 drawing
if (!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;
else
return false;
}
timeval结构体
/* A time value that is accurate to the nearest
microsecond 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);
}
#else
fill_animation_battery_by_ver(capacity, (void *)fb_addr, dec_logo_addr, logo_addr, phical_screen, show_animationm_ver);
#endif
anim_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);
}
#else
fill_animation_battery_by_ver(capacity, (void *)outBuffer.bits, dec_logo_addr, logo_addr, phical_screen, show_animationm_ver);
#endif
surface->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 100
fill_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);
}
//background
fill_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 address
dst_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.raw
endif
endif
- 定义自定义图片索引值
根据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.c
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};
+ 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_a
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)));
}
+ 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_a
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);
+ //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
- 效果