Android 4.2充电画面关键代码分析

http://blog.csdn.net/xnwyd/article/details/42915465


系统进入充电模式时,显示 充电画面,充电画面的代码在/system/core/charger/charger.c,下面对其关键代码进行分析


1)结构体

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /*power_supply信息*/  
  2. struct power_supply {  
  3.     /*链表节点*/  
  4.     struct listnode list;  
  5.     /*power_supply名称,如rk-ac/rk-usb/rk-bat*/  
  6.     char name[256];  
  7.     //power_supply类型,如Mains/USB/Battery  
  8.     char type[32];  
  9.     //状态,判断ac,battery或usb的 in/out  
  10.     bool online;  
  11.     bool valid;  
  12.     char cap_path[PATH_MAX];  
  13. };  
  14.   
  15. /*charger信息*/  
  16. struct charger {  
  17.     int64_t next_screen_transition;  
  18.     int64_t next_key_check;  
  19.     int64_t next_pwr_check;  
  20.     //按键状态  
  21.     struct key_state keys[KEY_MAX + 1];  
  22.     //uevent fd,通过此fd读取kernel的power_supply信息  
  23.     int uevent_fd;  
  24.     //power_supply链表,存储各个power_supply信息  
  25.     struct listnode supplies;  
  26.     //供电源的数量  
  27.     int num_supplies;  
  28.     //充电源的数量  
  29.     int num_supplies_online;  
  30.   
  31.     struct animation *batt_anim;  
  32.     gr_surface surf_unknown;  
  33.     //电池信息  
  34.     struct power_supply *battery;  
  35.     bool state;//the state of screen  
  36. };  


2)main函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int main(int argc, char **argv)  
  2. {  
  3.     int ret;  
  4.     struct charger *charger = &charger_state;  
  5.     int64_t now = curr_time_ms() - 1;  
  6.     int fd;  
  7.     int i;  
  8.     //初始化power_supply链表  
  9.     list_init(&charger->supplies);  
  10.   
  11.     klog_init();  
  12.     klog_set_level(CHARGER_KLOG_LEVEL);  
  13.   
  14.     //dump_last_kmsg();  
  15.   
  16.     LOGI("--------------- STARTING CHARGER MODE ---------------\n");  
  17.     acquire_wake_lock(PARTIAL_WAKE_LOCK,"PowerManagerService");  
  18.       
  19.     gr_init();  
  20.     gr_font_size(&char_width, &char_height);  
  21.     //遍历/dev/input目录下的设备,将EV_REL和EV_KEY设备的信息保存到ev_fds[]等结构体中  
  22.     ev_init(input_callback, charger);//参见下文3)  
  23.     //创建一个socket用于接收kernel的uevent  
  24.     fd = uevent_open_socket(64*1024, true);  
  25.     if (fd >= 0) {  
  26.         fcntl(fd, F_SETFL, O_NONBLOCK);  
  27.         ev_add_fd(fd, uevent_callback, charger);//参见下文6)  
  28.     }  
  29.     charger->uevent_fd = fd;  
  30.     coldboot(charger, "/sys/class/power_supply""add");  
  31.   
  32.     ret = res_create_surface("charger/battery_fail", &charger->surf_unknown);  
  33.     if (ret < 0) {  
  34.         LOGE("Cannot load image\n");  
  35.         charger->surf_unknown = NULL;  
  36.     }  
  37.   
  38.     for (i = 0; i < charger->batt_anim->num_frames; i++) {  
  39.         struct frame *frame = &charger->batt_anim->frames[i];  
  40.   
  41.         ret = res_create_surface(frame->name, &frame->surface);  
  42.         if (ret < 0) {  
  43.             LOGE("Cannot load image %s\n", frame->name);  
  44.             /* TODO: free the already allocated surfaces... */  
  45.             charger->batt_anim->num_frames = 0;  
  46.             charger->batt_anim->num_cycles = 1;  
  47.             break;  
  48.         }  
  49.     }  
  50.   
  51.     ev_sync_key_state(set_key_callback, charger);  
  52.   
  53. #ifndef CHARGER_DISABLE_INIT_BLANK  
  54.     gr_fb_blank(true);  
  55. #endif  
  56.   
  57.     charger->next_screen_transition = now - 1;  
  58.     charger->next_key_check = -1;  
  59.     charger->next_pwr_check = -1;  
  60.     reset_animation(charger->batt_anim);  
  61.     kick_animation(charger->batt_anim);  
  62.     //主循环函数  
  63.     event_loop(charger);  
  64.   
  65.     return 0;  
  66. }  

3)ev_init, input_callback函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <pre name="code" class="cpp">//bootable/recovery/minui/events.c  
  2. int ev_init(ev_callback input_cb, void *data)  
  3. {  
  4.     DIR *dir;  
  5.     struct dirent *de;  
  6.     int fd;  
  7.   
  8.     dir = opendir("/dev/input");  
  9.     if(dir != 0) {  
  10.         while((de = readdir(dir))) {  
  11.             unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];  
  12.   
  13. //            fprintf(stderr,"/dev/input/%s\n", de->d_name);  
  14.             if(strncmp(de->d_name,"event",5)) continue;  
  15.             fd = openat(dirfd(dir), de->d_name, O_RDONLY);  
  16.             if(fd < 0) continue;  
  17.   
  18.             /* read the evbits of the input device */  
  19.             if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) < 0) {  
  20.                 close(fd);  
  21.                 continue;  
  22.             }  
  23.   
  24.             /* TODO: add ability to specify event masks. For now, just assume 
  25.              * that only EV_KEY and EV_REL event types are ever needed. */  
  26.             if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits)) {  
  27.                 close(fd);  
  28.                 continue;  
  29.             }  
  30.   
  31.             ev_fds[ev_count].fd = fd;  
  32.             ev_fds[ev_count].events = POLLIN;  
  33.             ev_fdinfo[ev_count].cb = input_cb;  
  34.             ev_fdinfo[ev_count].data = data;  
  35.             ev_count++;  
  36.             ev_dev_count++;  
  37.             if(ev_dev_count == MAX_DEVICES) break;  
  38.         }  
  39.     }  
  40.   
  41.     return 0;  
  42. }  
  43.   
  44. static int input_callback(int fd, short revents, void *data)  
  45. {  
  46.     struct charger *charger = data;  
  47.     struct input_event ev;  
  48.     int ret;  
  49.     //读取input_event信息  
  50.     ret = ev_get_input(fd, revents, &ev);  
  51.     if (ret)  
  52.         return -1;  
  53.     update_input_state(charger, &ev);  
  54.     return 0;  
  55. }  
  56.   
  57.   
  58. static void update_input_state(struct charger *charger,  
  59.                                struct input_event *ev)  
  60. {  
  61.     if (ev->type != EV_KEY)  
  62.         return;  
  63.     //按键code,按键value  
  64.     set_key_callback(ev->code, ev->value, charger);  
  65. }  
  66.   
  67. static int set_key_callback(int code, int value, void *data)  
  68. {  
  69.     struct charger *charger = data;  
  70.     int64_t now = curr_time_ms();  
  71.     int down = !!value;  
  72.   
  73.     if (code > KEY_MAX)  
  74.         return -1;  
  75.   
  76.     /* ignore events that don't modify our state */  
  77.     //按键值未发生改变  
  78.     if (charger->keys[code].down == down)  
  79.         return 0;  
  80.   
  81.     /* only record the down even timestamp, as the amount 
  82.      * of time the key spent not being pressed is not useful */  
  83.     //按键按下时,记录按下的时刻,等待按键被松开  
  84.     if (down)  
  85.         charger->keys[code].timestamp = now;  
  86.     charger->keys[code].down = down;  
  87.     charger->keys[code].pending = true;  
  88.     if (down) {  
  89.         LOGV("[%lld] key[%d] down\n", now, code);  
  90.     } else {  
  91.     //按键松开时,计算按键的按住时间  
  92.         int64_t duration = now - charger->keys[code].timestamp;  
  93.         int64_t secs = duration / 1000;  
  94.         int64_t msecs = duration - secs * 1000;  
  95.         LOGV("[%lld] key[%d] up (was down for %lld.%lldsec)\n", now,  
  96.             code, secs, msecs);  
  97.     }  
  98.   
  99.     return 0;  
  100. }  


 

4)event_loop函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static void event_loop(struct charger *charger)  
  2. {  
  3.     int ret;  
  4.   
  5.     while (true) {  
  6.         int64_t now = curr_time_ms();  
  7.   
  8.         LOGV("[%lld] event_loop()\n", now);  
  9.         //处理按键事件  
  10.         handle_input_state(charger, now);//参见下文5)  
  11.         //处理充电事件  
  12.         handle_power_supply_state(charger, now);//参见下文7)  
  13.   
  14.         /* do screen update last in case any of the above want to start 
  15.          * screen transitions (animations, etc) 
  16.          */  
  17.         update_screen_state(charger, now);  
  18.   
  19.         wait_next_event(charger, now);  
  20.     }  
  21. }  

5)handle_input_state函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static void handle_input_state(struct charger *charger, int64_t now)  
  2. {  
  3.     process_key(charger, KEY_POWER, now);  
  4.   
  5.     if (charger->next_key_check != -1 && now > charger->next_key_check)  
  6.         charger->next_key_check = -1;  
  7. }  
  8.   
  9. static void process_key(struct charger *charger, int code, int64_t now)  
  10. {  
  11.     struct key_state *key = &charger->keys[code];  
  12.     int64_t next_key_check;  
  13.   
  14.     if (code == KEY_POWER) {  
  15.         if (key->down) {  
  16.             int64_t reboot_timeout = key->timestamp + POWER_ON_KEY_TIME;  
  17.             //重启系统  
  18.             if (now >= reboot_timeout) {  
  19.                 LOGI("[%lld] rebooting\n", now);  
  20.                 android_reboot(ANDROID_RB_RESTART, 0, 0);  
  21.             } else {  
  22.                 /* if the key is pressed but timeout hasn't expired, 
  23.                  * make sure we wake up at the right-ish time to check 
  24.                  */  
  25.                 set_next_key_check(charger, key, POWER_ON_KEY_TIME);  
  26.             }  
  27.         } else {  
  28.             /* if the power key got released, force screen state cycle */  
  29.             if (key->pending) {  
  30.                 request_suspend(false);  
  31.                 if(charger->state)  
  32.                 {  
  33.                     charger->state = false;  
  34.                     reset_animation(charger->batt_anim);  
  35.                     set_screen_state(SUSPEND);  
  36.                     //read_file(NEW_PATHS[0],lock_name,sizeof(lock_name));  
  37.                 }  
  38.                 else  
  39.                 {  
  40.                     charger->state = true;  
  41.                     charger->next_pwr_check = -1;  
  42.                     charger->next_screen_transition = -1;  
  43.                     kick_animation(charger->batt_anim);  
  44.                       
  45.                     set_screen_state(ON);  
  46.                       
  47.                 }  
  48.     //   kick_animation(charger->batt_anim);  
  49.   
  50.             }  
  51.         }  
  52.     }  
  53.   
  54.     key->pending = false;  
  55. }  


6)uevent_callback函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int uevent_callback(int fd, short revents, void *data)  
  2. {  
  3.     struct charger *charger = data;  
  4.   
  5.     if (!(revents & POLLIN))  
  6.         return -1;  
  7.     //调用handle_uevent_fd  
  8.     return handle_uevent_fd(charger, fd);  
  9. }  
  10.   
  11.   
  12. static int handle_uevent_fd(struct charger *charger, int fd)  
  13. {  
  14.     char msg[UEVENT_MSG_LEN+2];  
  15.     int n;  
  16.   
  17.     if (fd < 0)  
  18.         return -1;  
  19.   
  20.     while (true) {  
  21.         struct uevent uevent;  
  22.   
  23.         n = uevent_kernel_multicast_recv(fd, msg, UEVENT_MSG_LEN);  
  24.         if (n <= 0)  
  25.             break;  
  26.         if (n >= UEVENT_MSG_LEN)   /* overflow -- discard */  
  27.             continue;  
  28.   
  29.         msg[n] = '\0';  
  30.         msg[n+1] = '\0';  
  31.         //解析msg到uevent  
  32.         parse_uevent(msg, &uevent);  
  33.         //处理uevent,更新charger状态  
  34.         process_uevent(charger, &uevent);  
  35.     }  
  36.   
  37.     return 0;  
  38. }  
  39.   
  40.   
  41. //解析消息到uevent  
  42. static void parse_uevent(const char *msg, struct uevent *uevent)  
  43. {  
  44.   
  45.   
  46. /************************************************************* 
  47. 消息示例 
  48. msg-消息 
  49. event-uevent 
  50. power supply-charger信息 
  51.  
  52. msg=add@/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-bat 
  53. event { 'add', '/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-bat', 'power_supply', 'rk-bat', '', '' } 
  54. power supply rk-bat (Battery)  (action=add num_online=0 num_supplies=1) 
  55.  
  56. msg=add@/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-ac 
  57. event { 'add', '/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-ac', 'power_supply', 'rk-ac', '', '1' } 
  58. power supply rk-ac (Mains) online (action=add num_online=1 num_supplies=2) 
  59.  
  60. msg=add@/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-usb 
  61. event { 'add', '/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-usb', 'power_supply', 'rk-usb', '', '0' } 
  62. power supply rk-usb (USB) offline (action=add num_online=1 num_supplies=3) 
  63.  
  64. * 
  65. */  
  66.     //action = add / change /remove  
  67.     uevent->action = "";  
  68.     //path = /devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/  
  69.     uevent->path = "";  
  70.     //subsystem = power_supply  
  71.     uevent->subsystem = "";  
  72.     //ps_name = rk-ac / rk-battery /rk-usb  
  73.     uevent->ps_name = "";  
  74.     //ps_online = 0 / 1  
  75.     uevent->ps_online = "";  
  76.     //ps_type = ''  
  77.     uevent->ps_type = "";  
  78.   
  79.     /* currently ignoring SEQNUM */  
  80.     while (*msg) {  
  81. #ifdef DEBUG_UEVENTS  
  82.         LOGV("uevent str: %s\n", msg);  
  83. #endif  
  84.         if (!strncmp(msg, "ACTION=", 7)) {  
  85.             msg += 7;  
  86.             uevent->action = msg;  
  87.         } else if (!strncmp(msg, "DEVPATH=", 8)) {  
  88.             msg += 8;  
  89.             uevent->path = msg;  
  90.         } else if (!strncmp(msg, "SUBSYSTEM=", 10)) {  
  91.             msg += 10;  
  92.             uevent->subsystem = msg;  
  93.         } else if (!strncmp(msg, "POWER_SUPPLY_NAME=", 18)) {  
  94.             msg += 18;  
  95.             uevent->ps_name = msg;  
  96.         } else if (!strncmp(msg, "POWER_SUPPLY_ONLINE=", 20)) {  
  97.             msg += 20;  
  98.             uevent->ps_online = msg;  
  99.         } else if (!strncmp(msg, "POWER_SUPPLY_TYPE=", 18)) {  
  100.             msg += 18;  
  101.             uevent->ps_type = msg;  
  102.         }  
  103.   
  104.         /* advance to after the next \0 */  
  105.         while (*msg++)  
  106.             ;  
  107.     }  
  108.   
  109.     //LOGV  
  110.     LOGI("event { '%s', '%s', '%s', '%s', '%s', '%s' }\n",  
  111.          uevent->action, uevent->path, uevent->subsystem,  
  112.          uevent->ps_name, uevent->ps_type, uevent->ps_online);  
  113. }  
  114.   
  115.   
  116. //处理uevent信息,更新charger的power_supply状态  
  117. static void process_ps_uevent(struct charger *charger, struct uevent *uevent)  
  118. {  
  119.     int online;  
  120.     char ps_type[32];  
  121.     struct power_supply *supply = NULL;  
  122.     int i;  
  123.     bool was_online = false;  
  124.     bool battery = false;  
  125.     bool usb = false;  
  126.     //如果ps_type为空,则重新从驱动路径中获取ps_type  
  127.     if (uevent->ps_type[0] == '\0') {  
  128.         char *path;  
  129.         int ret;  
  130.   
  131.         if (uevent->path[0] == '\0')  
  132.             return;  
  133.     /* 
  134.     /sys/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-ac 
  135.     /sys/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-bat 
  136.     /sys/devices/platform/rk30_i2c.0/i2c-0/0-0062/power_supply/rk-usb 
  137.     */  
  138.     //生成路径  
  139.         ret = asprintf(&path, "/sys/%s/type", uevent->path);  
  140.         if (ret <= 0)  
  141.             return;  
  142.     /* 
  143.     type = Mains / Battery /USB 
  144.     */  
  145.     //读取type  
  146.         ret = read_file(path, ps_type, sizeof(ps_type));  
  147.         free(path);  
  148.         if (ret < 0)  
  149.             return;  
  150.     } else {  
  151.         strlcpy(ps_type, uevent->ps_type, sizeof(ps_type));  
  152.     }  
  153.   
  154.    //type == Battery  
  155.     if (!strncmp(ps_type, "Battery", 7)){  
  156.         battery = true;  
  157.     }  
  158.       
  159.     //读取uevent的online值  
  160.     online = atoi(uevent->ps_online);  
  161.     //从charger的list查找name为ps_name的power_supply  
  162.     supply = find_supply(charger, uevent->ps_name);  
  163.     if (supply) {//list包含该power_supply  
  164.         was_online = supply->online;  
  165.     //更新charger的online状态  
  166.         supply->online = online;  
  167.     }  
  168.   
  169.     if (!strcmp(uevent->action, "add")) {  
  170.         //该supply不在list中  
  171.         if (!supply) {  
  172.         //新建supply,拷贝uevent的信息到supply,然后添加到charger的list  
  173.         //同时更新charger的num_supplies++  
  174.   
  175.             supply = add_supply(charger, uevent->ps_name, ps_type, uevent->path,  
  176.                                 online);  
  177.             if (!supply) {  
  178.                 LOGE("cannot add supply '%s' (%s %d)\n", uevent->ps_name,  
  179.                      uevent->ps_type, online);  
  180.                 return;  
  181.             }  
  182.             /* only pick up the first battery for now */  
  183.             if (battery && !charger->battery)  
  184.                 charger->battery = supply;  
  185.     //该supply已在list中  
  186.         } else {  
  187.             LOGE("supply '%s' already exists..\n", uevent->ps_name);  
  188.         }  
  189.     } else if (!strcmp(uevent->action, "remove")) {  
  190.         if (supply) {  
  191.             if (charger->battery == supply)  
  192.                 charger->battery = NULL;  
  193.         //从list中移除该supply,并更新charger->num_supplies--  
  194.             remove_supply(charger, supply);  
  195.             supply = NULL;  
  196.         }  
  197.     //前面已更新了charger的online状态,此处不做任何动作  
  198.     } else if (!strcmp(uevent->action, "change")) {  
  199.         if (!supply) {  
  200.             LOGE("power supply '%s' not found ('%s' %d)\n",  
  201.                  uevent->ps_name, ps_type, online);  
  202.             return;  
  203.         }  
  204.     } else {  
  205.         return;  
  206.     }  
  207.   
  208.     /* allow battery to be managed in the supply list but make it not 
  209.      * contribute to online power supplies. */  
  210.     if (!battery) {  
  211.     //online : 1 -> 0  
  212.         if (was_online && !online)  
  213.             charger->num_supplies_online--;  
  214.     //online: 0 -> 1  
  215.         else if (supply && !was_online && online)  
  216.             charger->num_supplies_online++;  
  217.     }  
  218.   
  219.     if(usb && !online){  
  220.         charger->num_supplies_online = 0;  
  221.     }  
  222.   
  223.     LOGI("power supply %s (%s) %s (action=%s num_online=%d num_supplies=%d)\n",  
  224.          uevent->ps_name, ps_type, battery ? "" : online ? "online" : "offline",  
  225.          uevent->action, charger->num_supplies_online, charger->num_supplies);  
  226. }  


7)handle_power_supply_state函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static void handle_power_supply_state(struct charger *charger, int64_t now)  
  2. {  
  3.     //充电源数量为0  
  4.     if (charger->num_supplies_online == 0) {  
  5.         request_suspend(false);  
  6.         //准备关机  
  7.         if (charger->next_pwr_check == -1) {  
  8.             charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME;  
  9.             LOGI("[%lld] device unplugged: shutting down in %lld (@ %lld)\n",  
  10.                  now, UNPLUGGED_SHUTDOWN_TIME, charger->next_pwr_check);  
  11.         //关机  
  12.         } else if (now >= charger->next_pwr_check) {  
  13.             LOGI("[%lld] shutting down\n", now);  
  14.             android_reboot(ANDROID_RB_POWEROFF, 0, 0);  
  15.         } else {  
  16.             /* otherwise we already have a shutdown timer scheduled */  
  17.         }  
  18.     } else {  
  19.         /* online supply present, reset shutdown timer if set */  
  20.         if (charger->next_pwr_check != -1) {  
  21.             LOGI("[%lld] device plugged in: shutdown cancelled\n", now);  
  22.             kick_animation(charger->batt_anim);  
  23.         }  
  24.         charger->next_pwr_check = -1;  
  25.     }  
  26. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值