06.MTK关机充电动画显示

关机充电的第一张logo:
/vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/rules.mk
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 \
           ... ...
/vendor/mediatek/proprietary/bootable/bootloader/lk/lib/libshowlogo/cust_display.h
#define LOW_BATTERY_INDEX   2
/vendor/mediatek/proprietary/bootable/bootloader/lk/target/tb8321p3_bsp/include/target/board.h
//Project specific header file
#define CFG_DISPLAY_WIDTH       (DISP_GetScreenWidth())
    return primary_display_get_width();
     if (pgc->plcm == NULL)
      pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED);
     if (pgc->plcm->params)
      return pgc->plcm->params->width;
#define CFG_DISPLAY_HEIGHT      (DISP_GetScreenHeight())
    return primary_display_get_height();
     if (pgc->plcm == NULL)
      pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED); 
     if (pgc->plcm->params)
      return pgc->plcm->params->height; 
#define CFG_DISPLAY_BPP         (DISP_GetScreenBpp())
/vendor/mediatek/proprietary/bootable/bootloader/lk/kernel/main.c
kmain  //main.c
 platform_early_init();  //lk/platform/mt6580/platform.c
 thread_t *thread_bs2 = thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
 if (thread_bs2)
  thread_resume(thread_bs2);
static int bootstrap2(void *arg)  //lk/kernel/main.c
 platform_init         //lk/platform/mt6580/platform.c
  mt65xx_bat_init();    //mt_battery.c
   if (kernel_charging_boot() == 1)  //如果是关机充电
    //mt_disp_show_low_battery();  //公版是直接显示一张低电logo  //mt_logo.c
     init_fb_screen();
     fill_animation_logo(LOW_BATTERY_INDEX, mt_get_fb_buf(), (void *)mt_get_tempfb_addr(), logo_addr, phical_screen);
     mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);
    int boot_capacity = get_battery_capacity();  //我们可以改成下面这种根据不同capacity显示不同电量
    mt_disp_show_battery_capacity(boot_capacity)  //void mt_disp_show_battery_capacity(UINT32capacity) //lk/platform/mt6580/mt_logo.c
     init_fb_screen();
     fill_animation_battery_by_ver(capacity, mt_get_fb_buf(), (void *)mt_get_tempfb_addr(), logo_addr, phical_screen, show_animationm_ver); //lk/lib/libshowlogo/show_animation_common.c
      switch (version)
       case VERION_OLD_ANIMATION:
        fill_animation_battery_old(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);
       case VERION_NEW_ANIMATION:
        fill_animation_battery_new(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen); //lk/lib/libshowlogo/show_animation_common.c
       case VERION_WIRELESS_CHARGING_ANIMATION:
        fill_animation_battery_wireless_charging(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);
     mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); 
vendor\mediatek\proprietary\bootable\bootloader\lk\target\tb8167p5_64_bsp\include\target\cust_battery.h
/************Isaac add start***************/
typedef struct _BATTERY_PROFILE_STRUCT {
        signed int percentage;
        signed int voltage;
} BATTERY_PROFILE_STRUCT, *BATTERY_PROFILE_STRUCT_P;
BATTERY_PROFILE_STRUCT battery_profile_t2[] = {
{        0        ,        4182        },
{        1        ,        4170        },
{        2        ,        4159        },
... ...
{        99        ,        3576        },
{        100        ,        3516        },
};
// add by xuce for charging animation start Isaac
int get_battery_capacity()
{
        int vol;
        int t2_size;
        BATTERY_PROFILE_STRUCT *temp = battery_profile_t2;
        int capacity = 0;
        int i;
        #if defined(SWCHR_POWER_PATH)
                vol = get_i_sense_volt(1);
        #else
                vol = get_bat_sense_volt(1);
        #endif
        if( vol > temp[0].voltage){
                //printf("%s capacity = 100\n", __FUNCTION__);
                return 100;
        }else if( vol < BATTERY_LOWVOL_THRESOLD ){
                return 0;
        }else{
                t2_size = sizeof(battery_profile_t2) / sizeof(BATTERY_PROFILE_STRUCT);
                //printf("%s size=%d", __FUNCTION__, t2_size);
                for(i=0; i<t2_size-1; i++){              
                        //printf("%s voltage=%d voltage[i]=%d  voltage[i+1]=%d \n", __FUNCTION__, vol, temp[i].voltage, temp[i+1].voltage);
                        if(vol >= temp[i+1].voltage && vol <= temp[i].voltage){
                                //printf("%s return capacity=%d\n", __FUNCTION__, temp[i].percentage);
                                capacity = 100 - temp[i].percentage;
                                if(capacity < 0){
                                        capacity = 0;
                                }
                        }
                }
        }
        return capacity;
}
// add by xuce for charging animation end
/*************Isaac add end**************/
=========================================================================
关机充电的动画阶段:
/vendor/mediatek/proprietary/external/libshowlogo/Android.mk
LOCAL_SRC_FILES  := show_logo_common.c\
                  decompress_common.c\
                  show_animation_common.c\
                  charging_animation.cpp\
                  utils.cpp
LOCAL_MODULE := libshowlogo
/vendor/mediatek/proprietary/external/charger/kpoc_charger.rc
on charger
    start kpoc_charger
service kpoc_charger /system/bin/kpoc_charger
    class charger
    group system wakelock
    capabilities BLOCK_SUSPEND SYS_ADMIN SYS_BOOT
/vendor/mediatek/proprietary/external/charger/Android.mk
LOCAL_SRC_FILES:= \
    common.cpp \
    lights.cpp \
    bootlogo.cpp \
    main.cpp \
    key_control.cpp \
    charging_control.cpp
LOCAL_MODULE:= kpoc_charger
# Move to system partition for Android O migration
#LOCAL_PROPRIETARY_MODULE := true
#LOCAL_MODULE_OWNER := mtk
LOCAL_INIT_RC := kpoc_charger.rc
LOCAL_SHARED_LIBRARIES := \
  libshowlogo \
  android.hardware.health@2.0 \
  ... ...
/vendor/mediatek/proprietary/external/libshowlogo/cust_display.h
#define CHARGER_OV_INDEX   3
/* The option of new charging animation */
#define ANIMATION_NEW
/vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.h
#define MAX_SUPPORT_ANIM_VER  2
#define VERION_OLD_ANIMATION 0
#define VERION_NEW_ANIMATION 1
#define VERION_WIRELESS_CHARGING_ANIMATION  2
// Use health HAL
#include <android/hardware/health/2.0/IHealth.h>
#include <healthhalutils/HealthHalUtils.h>
/vendor/mediatek/proprietary/external/charger/main.h
using ::android::binder::Status;
using ::android::hardware::light::BrightnessMode;
using ::android::hardware::light::FlashMode;
using ::android::hardware::light::HwLight;
using ::android::hardware::light::HwLightState;
using ::android::hardware::light::ILights;
using ::android::hardware::light::LightType;
using ::android::hardware::health::V2_0::get_health_service;
using ::android::hardware::health::V2_0::HealthInfo;
using ::android::hardware::health::V2_0::IHealth;
using ::android::hardware::health::V2_0::Result;
using ::android::sp;
/vendor/mediatek/proprietary/external/charger/main.cpp
int main(__attribute__((unused))int argc, __attribute__((unused))char *argv[])
 set_draw_anim_mode(1); //void set_draw_anim_mode(int running_mode) //charger/bootlogo.cpp
  if(running_mode == 1) {
   draw_anim_mode = DRAW_ANIM_MODE_FB;
  else
   draw_anim_mode = DRAW_ANIM_MODE_SURFACE;
  set_draw_mode(draw_anim_mode);  //libshowlogo/charging_animation.cpp //void set_draw_mode(int 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;  //DRAW_ANIM_MODE_FB
 bootlogo_init      //charger/bootlogo.cpp
  sync_anim_version();
   #ifdef ANIMATION_NEW
    set_anim_version(VERION_NEW_ANIMATION);  //libshowlogo/charging_animation.cpp //void set_anim_version(int version)
     show_animationm_ver = version;
   #else
    set_anim_version(VERION_OLD_ANIMATION);
    KPOC_LOGI("[ChargingAnimation %s %d]not define ANIMATION_NEW:show old animation \n",__FUNCTION__,__LINE__);
   #endif
  anim_init()      //libshowlogo/charging_animation.cpp
   ->init_charging_animation_ui_dimension();  //libshowlogo/show_animation_common.c
     lcm_width = vinfo.xres;    //假横屏电量百分比错位,需要修改这里调换xres和yres
     lcm_height = vinfo.yres;
     int rotation = getRotation(); 
   ->anim_logo_init();
   ->if (draw_anim_mode == (DRAW_ANIM_MODE_FB))
    anim_fb_init();    //libshowlogo/charging_animation.cpp
        if(ORIENTATION_270 == rotation){//270    //充电动画方向
            phical_screen.rotation = 270;
        } else if(ORIENTATION_90 == rotation){//90
            phical_screen.rotation = 90;
        } else if((ORIENTATION_180 == rotation) && (phical_screen.need180Adjust == 1)){//180
            phical_screen.rotation = 180;
        } else {
            phical_screen.rotation = 0;
        }
   ->else
    anim_surface_init(); 
 charging_control()    //charger/charging_control.cpp
  pthread_cond_t cond;
  pthread_cond_init(&cond, NULL);
  pthread_create(&uevent_thread, &attr, uevent_thread_routine, NULL);
  pthread_create(&draw_thread, &attrd, draw_thread_routine, NULL);
   do {
    inDraw = 1; //表明正在画充电动画
    bootlogo_show_charging(bc, 1);  // @@@ draw fb again to refresh ddp //charger/bootlogo.cpp
     if (get_battnotify_status()) //其实就是读取kernel创建的BatteryNotify节点
      show_charger_ov_logo();  //libshowlogo/charging_animation.cpp
       anim_show_logo(CHARGER_OV_INDEX);
      return;  //如果高温,这里直接return,不跑下面的show_battery_capacity
     if (showLowBattLogo)  //由external/charger/key_control.cpp  key_thread_routine()线程里赋值
      show_low_battery();
      return;
     show_battery_capacity(capacity);  //libshowlogo/charging_animation.cpp  //显示电量百分比、充电动画
      int has_fast_charging = getValue("ro.vendor.mtk_pump_express_plus_support" , "0" );
      if (draw_anim_mode == (DRAW_ANIM_MODE_FB)) {
       if( has_fast_charging == 1) {
        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 {                                      /libshowlogo/show_animation_common.c
        fill_animation_battery_by_ver(capacity, (void *)fb_addr, dec_logo_addr, logo_addr, phical_screen,show_animationm_ver);
         switch (version)
         case VERION_OLD_ANIMATION:
          fill_animation_battery_old(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);
         case VERION_NEW_ANIMATION:
          fill_animation_battery_new(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);  //最终显示电量百分比、充电动画的函数
         case VERION_WIRELESS_CHARGING_ANIMATION:
          fill_animation_battery_wireless_charging(capacity, fill_addr, dec_logo_addr, logo_addr, phical_screen);
       }
      }
    inDraw = 0;  //充电动画画图结束
    pthread_cond_wait(&cond, &mutex);
   } while(1);
 key_control(pwrkeys, ARRAY_SIZE(pwrkeys)); //will loop inside  //charger/key_control.cpp
  static int longPressDuration = LONG_PRESS_DEFAULT_DURATION; //#define LONG_PRESS_DEFAULT_DURATION500 //设置powerKey超时时间为500ms
  long_press_control();
   ->pthread_t pwrkey_thread;
   ->pthread_cond_init(&keycond, NULL);
   ->ret = pthread_create(&pwrkey_thread, &attr, key_thread_routine, NULL); //开了一个线程等待powerkey按下发来的等待队列keycond
    pthread_cond_t keycond;
    static bool bootingUp = false; //默认为false
    while (!bootingUp) {  //如果系统不是正在启动
    {
     pthread_cond_wait(&keycond, &mutex); //应该类似于等待队列
     gettimeofday(&start, NULL);  //start 为powerKey按下的启动时间
     while(powerKeyPressed)  //如果powerKey一直按着,那么powerKeyPressed就保持为true
     {
      usleep(1000*100); //200ms  //每200ms检测一次按键时长是否达到要求
      long_press = time_exceed(start, longPressDuration);  //charger/common.cpp
       struct timeval now;
       gettimeofday(&now, NULL); //获取当前时间
       if((now.tv_sec - start.tv_sec)*1000000 + now.tv_usec - start.tv_usec > duration_msec*1000) //判断now - start > longPressDuration ?
        return true;  //如果满足时长要求,则返回true
       else
        return false;
      if(long_press)
      {
       KPOC_LOGI("pwr key reaches boot condition\n");
       if(get_voltage() > VBAT_POWER_ON) //int VBAT_POWER_ON = VBAT_POWER_ON_DEFAULT; #define VBAT_POWER_ON_DEFAULT  3450000
       { // ready to boot up.
        inotify_rm_watch(ufds[0].fd, wd);
        if (keyDownPressed || keyUpPressed)  //这两个变量默认为false,并没看到任何赋值,所以这里条件不成立
         exit_charger(EXIT_REBOOT_UBOOT);  //charger/main.cpp
          reboot(RB_AUTOBOOT);
        else
         exit_charger(EXIT_POWER_UP);  //正常来说,跑这里,机器重启,进入正常开机!
          reboot(RB_POWER_OFF);
        bootingUp = true;
       }else {
        showLowBattLogo = 1; //如果低电,那么会在线程draw_thread_routine()show一张log,猜测后面应该是关机了,然后检测到充电器存在,再次进入关机充电
        KPOC_LOGI("VBAT <= %d\n", VBAT_POWER_ON);
       }
      }
     }
    }
    if (!long_press)  //如果powerKey是短按
     showLowBattLogo = 0; //设置标志位,不显示低电logo,而是显示充电动画
    if(!bootingUp)  //如果机器机器是短按,或者长按但是低电
    {
     start_charging_anim(TRIGGER_ANIM_KEY); //显示充电动画  //charging_control.cpp
     {
      KPOC_LOGI("%s: inDraw:%d, reason:%d\n",__FUNCTION__, inDraw, reason);
      trigger_anim();
       if(inDraw) {  //如果处于动画画图当中
        key_trigger_suspend = 1;
        return;}
       if (!is_charging_source_available()) {
         HealthInfo info = {};
         get_health_info(&info);  //获取hal层信息
         usb_online = info.legacy.chargerUsbOnline;
         ac_online = info.legacy.chargerAcOnline;
         wireless_online = info.legacy.chargerWirelessOnline;
         for (i = 0; i < ARRAY_SIZE(chg_volt_path); i++) {  /* Find path for charger voltage */
           vchr = get_int_value(chg_volt_path[i]);
         return (usb_online || ac_online || wireless_online || vchr >= 2500);
        KPOC_LOGI("no charging source, skip drawing anim\n");
        return;
       }  //如果电池信息能获取到,那么继续往下跑
       key_trigger_suspend = 0;
       pthread_cond_signal(&cond);  //唤醒draw_thread_routine线程
     }
    } 
    KPOC_LOGI("pwr key long press check end\n");
   ->if (ret != 0)  //如果key_thread_routine线程创建失败,那么直接关机
    KPOC_LOGI("create key pthread failed.\n");
    exit_charger(EXIT_ERROR_SHUTDOWN);
  while (1) {      //判断powerKey是否按下
   ufds = (struct pollfd*)calloc(1, sizeof(ufds[0])); //static struct pollfd *ufds;
   pollres = poll(ufds, num_fds, -1);
   if (ufds[0].revents & POLLIN) {
    read_notify(INPUT_DEVICE_PATHufds[0].fd);  //#define INPUT_DEVICE_PATH "/dev/input"
   for (i = 1; i < num_fds; i++) {
    ... ...
    if (EV_KEY == event.type) {
     for (j = 0; j < pwrkeys_num; j++) {
      if (event.code == pwrkeys[j]) {
       if (1 == event.value) {
        powerKeyPressed = true;
        pthread_cond_signal(&keycond);
       } else
        powerKeyPressed = false;
        break;
       }
      }
     }
    }
   }
/vendor/mediatek/proprietary/external/charger/charging_control.cpp
/kernel-4.19-lc/drivers/power/supply/mediatek/battery_common.c
/* / */
/* // Create File For EM : ADC_Charger_Voltage */
/* / */
static ssize_t show_ADC_Charger_Voltage(struct device *dev, struct device_attribute *attr, char *buf)
{
	battery_log(BAT_LOG_CRTI, "[EM] show_ADC_Charger_Voltage : %d\n", BMT_status.charger_vol);
	return sprintf(buf, "%d\n", BMT_status.charger_vol);
}
static ssize_t store_ADC_Charger_Voltage(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
	battery_log(BAT_LOG_CRTI, "[EM] Not Support Write Function\n");
	return size;
}
static DEVICE_ATTR(ADC_Charger_Voltage, 0664, show_ADC_Charger_Voltage, store_ADC_Charger_Voltage);
/vendor/mediatek/proprietary/external/charger/common.cpp
int get_int_value(const char * path)
{
    int size = 32;
    char buf[size];
    if(!read_from_file(path, buf, size))
        return -1;
    return atoi(buf);
}
/*
 * 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;
}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值