系统进入充电模式时,显示 充电画面,充电画面的代码在/system/core/charger/charger.c,下面对其关键代码进行分析
1)结构体
/*power_supply信息*/
struct power_supply {
/*链表节点*/
struct listnode list;
/*power_supply名称,如rk-ac/rk-usb/rk-bat*/
char name[256];
//power_supply类型,如Mains/USB/Battery
char type[32];
//状态,判断ac,battery或usb的 in/out
bool online;
bool valid;
char cap_path[PATH_MAX];
};
/*charger信息*/
struct charger {
int64_t next_screen_transition;
int64_t next_key_check;
int64_t next_pwr_check;
//按键状态
struct key_state keys[KEY_MAX + 1];
//uevent fd,通过此fd读取kernel的power_supply信息
int uevent_fd;
//power_supply链表,存储各个power_supply信息
struct listnode supplies;
//供电源的数量
int num_supplies;
//充电源的数量
int num_supplies_online;
struct animation *batt_anim;
gr_surface surf_unknown;
//电池信息
struct power_supply *battery;
bool state;//the state of screen
};
2)main函数
int main(int argc, char **argv)
{
int ret;
struct charger *charger = &charger_state;
int64_t now = curr_time_ms() - 1;
int fd;
int i;
//初始化power_supply链表
list_init(&charger->supplies);
klog_init();
klog_set_level(CHARGER_KLOG_LEVEL);
//dump_last_kmsg();
LOGI("--------------- STARTING CHARGER MODE ---------------\n");
acquire_wake_lock(PARTIAL_WAKE_LOCK,"PowerManagerService");
gr_init();
gr_font_size(&char_width, &char_height);
//遍历/dev/input目录下的设备,将EV_REL和EV_KEY设备的信息保存到ev_fds[]等结构体中
ev_init(input_callback, charger);//参见下文3)
//创建一个socket用于接收kernel的uevent
fd = uevent_open_socket(64*1024, true);
if (fd >= 0) {
fcntl(fd, F_SETFL, O_NONBLOCK);
ev_add_fd(fd, uevent_callback, charger);//参见下文6)
}
charger->uevent_fd = fd;
coldboot(charger, "/sys/class/power_supply", "add");
ret = res_create_surface("charger/battery_fail", &charger->surf_unknown);
if (ret < 0) {
LOGE("Cannot load image\n");
charger->surf_unknown = NULL;
}
for (i = 0; i < charger->batt_anim->num_frames; i++) {
struct frame *frame = &charger->batt_anim->frames[i];
ret = res_create_surface(frame->name, &frame->surface);
if (ret < 0) {
LOGE("Cannot load image %s\n", frame->name);
/* TODO: free the already allocated surfaces... */
charger->batt_anim->num_frames = 0;
charger->batt_anim->num_cycles = 1;
break;
}
}
ev_sync_key_state(set_key_callback, charger);
#ifndef CHARGER_DISABLE_INIT_BLANK
gr_fb_blank(true);
#endif
charger->next_screen_transition = now - 1;
charger->next_key_check = -1;
charger->next_pwr_check = -1;
reset_animation(charger->batt_anim);
kick_animation(charger->batt_anim);
//主循环函数
event_loop(charger);
return 0;
}
3)ev_init, input_callback函数
<pre name="code" class="cpp">//bootable/recovery/minui/events.c
int ev_init(ev_callback input_cb, void *data)
{
DIR *dir;
struct dirent *de;
int fd;
dir = opendir("/de