关机充电服务
最近公司在预研Android P的项目,在第一轮测试后有一个关机充电背光未关闭的问题,在这之前从未接触过充电和背光部分,开启漫漫源码之路。
关机充电启动
路径:vendor/mediatek/proprietary/external/charger/kpoc_charger.rc
如下所示,在此.rc文件里面,会去开启kpoc_charger服务,若想手动的运行此服务,可通过adb命令./system/bin/kpoc_charger执行
on charger
start kpoc_charger
service kpoc_charger /system/bin/kpoc_charger
class charger
关机充电main函数
在路径vendor/mediatek/proprietary/external/charger/下可以看到很多文件,服务相关的代码基本上都在这个目录下了,从main.cpp切入:
int main(__attribute__((unused))int argc, __attribute__((unused))char *argv[])
{
//设置充电动画的绘制模式
set_draw_anim_mode(1);
pthread_mutex_init(&lights_mutex, NULL);
setpriority(PRIO_PROCESS, 0, -20);
FILE *oom_adj = fopen("/proc/self/oom_score_adj", "w");
if (oom_adj) {
fputs("-17", oom_adj);
fclose(oom_adj);
}
//stop_backlight();
bootlogo_init(); //充电动画相关的的初始化工作
alarm_control();
charging_control(); //控制充电时led灯和动画效果(重要!)
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;
}
控制充电时背光和动画效果
charging_control定义在charging_control.cpp中,在此函数中会去初始化led灯,然后开启两个线程,第一个线程这里没研究,看网上有说法是操作led灯的,第二个线程控制充电动画效果和LCD背光;
void charging_control()
{
int ret = 0;
pthread_attr_t attr, attrd, attrl;
pthread_t uevent_thread, draw_thread, light_thread;
//charging led control
if (!is_charging_source_available()) {
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);
}
}
draw_thread_routine函数的代码如下:
bc = get_capacity(); //获取电量的百分比;
draw_with_interval();//设置播放充电动画时长和动画图片间时间间隔的;
stop_backlight(); //关闭背光(重点!);
request_suspend(); //唤醒early_suspend机制;
static void* draw_thread_routine(__attribute__((unused))void *arg)
{
int bc;
int fd_fb = -1, 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