安卓系统定制:android的充电图标的制作和显示
http://blog.csdn.net/lushengchu_luis/article/details/20382775 最近RK3026的项目需要修改开机充电,才分析了Android原生态的充电过程。 充电的代码和图标在system/core/charger中,会编译成名字为charger的可执行文件,打包进ramdisk中,在init.rc中脚本启动: [java] view plain copy oncharger setpropro.boot.charger.emmc0 exportPATH/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin exportLD_LIBRARY_PATH/vendor/lib:/system/lib setpropsys.usb.configadb servicecharger/charger disabled on charger会触发该服务执行,所以现在要分析的就是on charger是如被何触发的。 在system/core/init/init.c中: [java] view plain copy is_charger=!strcmp(bootmode,"charger"); 。。。。。。 if(is_charger){ action_for_each_trigger("charger",action_add_queue_tail); }else{ action_for_each_trigger("early-boot",action_add_queue_tail); action_for_each_trigger("boot",action_add_queue_tail); } 可见,要触发charger, is_charger为真即可,即bootmode为“charger”,所以继续跟踪代码: [java] view plain copy struct{ constchar*src_prop; constchar*dest_prop; constchar*def_val; }prop_map[]={ //{"ro.boot.serialno","ro.serialno","",}, {"ro.boot.mode","ro.bootmode","unknown",}, {"ro.boot.baseband","ro.baseband","unknown",}, {"ro.boot.bootloader","ro.bootloader","unknown",}, }; for(i=0;i<ARRAY_SIZE(prop_map);i++){ ret=property_get(prop_map[i].src_prop,tmp); if(ret>0) property_set(prop_map[i].dest_prop,tmp); else property_set(prop_map[i].dest_prop,prop_map[i].def_val); } ret=property_get("ro.boot.console",tmp); if(ret) strlcpy(console,tmp,sizeof(console)); /*saveacopyforinit'susageduringboot*/ property_get("ro.bootmode",tmp); strlcpy(bootmode,tmp,sizeof(bootmode)); 读取“ro.bootmode”得到的,但是“ro.bootmode”的属性又是通过"ro.boot.mode"来设置的。 而这个属性是读取/proc/cmdline参数,最终在import_kernel_nv函数中设置的: [java] view plain copy if(!strcmp(name,"qemu")){ strlcpy(qemu,value,sizeof(qemu)); }elseif(!strncmp(name,"androidboot.",12)&&name_len>12){ constchar*boot_prop_name=name+12; charprop[PROP_NAME_MAX]; intcnt; cnt=snprintf(prop,sizeof(prop),"ro.boot.%s",boot_prop_name); if(cnt<PROP_NAME_MAX) property_set(prop,value); } } 命令行是kernel传进来的,所以要进入驱动中去了。 在kernel/drivers/power/rk29_charger_display.c文件中: [java] view plain copy staticvoidadd_bootmode_charger_to_cmdline(void) { char*pmode="androidboot.mode=charger"; //intoff=strlen(saved_command_line); char*new_command_line=kzalloc(strlen(saved_command_line)+strlen(pmode)+1,GFP_KERNEL); sprintf(new_command_line,"%s%s",saved_command_line,pmode); saved_command_line=new_command_line; //strcpy(saved_command_line+off,pmode); //intoff=strlen(boot_command_line); //strcpy(boot_command_line+off,pmode); printk("Kernelcommandline:%s\n",saved_command_line); } 终于看到了,就是在这里设置了androidboot.mode=charger属性。 继续跟进什么条件下才设置该属性,发现关机充电情况下,设置该属性,机子运行charger执行文件;这时候如果电源键按下超过两秒,charger执行文件重启机子,把标记设置为BOOT_MODE_CHARGE;重启后在驱动中,判断电量如果小于5%(可以修改该值),继续进入charger模式;否则不再设置androidboot.mode=charger属性,系统不会再执行charger文件,系统进入正常启动。