最近RK3026的项目需要修改开机充电,才分析了android原生态的充电过程。

充电的代码和图标在system/core/charger中,会编译成名字为charger的可执行文件,打包进ramdisk中,在init.rc中脚本启动:

on charger    setprop ro.boot.charger.emmc 0    export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin    export LD_LIBRARY_PATH /vendor/lib:/system/lib    setprop sys.usb.config adb service charger /charger                                                                                                                                           disabled

on charger会触发该服务执行,所以现在要分析的就是on charger是如被何触发的。

在system/core/init/init.c中:

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”,所以继续跟踪代码:

    struct {        const char *src_prop;        const char *dest_prop;        const char *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));    /* save a copy for init's usage during boot */    property_get("ro.bootmode", tmp);    strlcpy(bootmode, tmp, sizeof(bootmode));

读取“ro.bootmode”得到的,但是“ro.bootmode”的属性又是通过"ro.boot.mode"来设置的。

而这个属性是读取/proc/cmdline参数,最终在import_kernel_nv函数中设置的:

    if (!strcmp(name,"qemu")) {        strlcpy(qemu, value, sizeof(qemu));    } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {        const char *boot_prop_name = name + 12;        char prop[PROP_NAME_MAX];        int cnt;        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文件中:

static void add_bootmode_charger_to_cmdline(void)                                                                                                              {    char *pmode=" androidboot.mode=charger";    //int off = 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);    //int off = strlen(boot_command_line);    //strcpy(boot_command_line+off,pmode);    printk("Kernel command line: %s\n", saved_command_line);}

终于看到了,就是在这里设置了androidboot.mode=charger属性。

继续跟进什么条件下才设置该属性,发现关机充电情况下,设置该属性,机子运行charger执行文件;这时候如果电源键按下超过两秒,charger执行文件重启机子,把标记设置为BOOT_MODE_CHARGE;重启后在驱动中,判断电量如果小于5%(可以修改该值),继续进入charger模式;否则不再设置androidboot.mode=charger属性,系统不会再执行charger文件,系统进入正常启动。













更多相关文章

  1. Android(安卓)Studio开发界面自定义,更有利于开发
  2. Android中TabLayout切换选项背景和修改字体大小
  3. Android获取服务器后台数据
  4. Android(第三种动画)属性动画完全解析(上),初识属性动画的基本用法
  5. 【Android(安卓)开发】:UI控件之 ProgressBar 进度条的使用
  6. Android(安卓)复习巩固------ Animation 动画 (简介)
  7. Android(安卓)focus search returned a view that wasn't able t
  8. android中selector改变界面状态用法小结
  9. android TextView 改变边框

随机推荐

  1. Android(安卓)第八天_重置版_服务_注意事
  2. Android开发学习 之 一、开发环境的搭建
  3. Dojo mobile TweetView 系列教程之五 —
  4. Android(安卓)Webview 开发详解
  5. Android该系统提供的服务--Vibrator(振子
  6. Android(安卓)开关机动画显示源码分析
  7. 两个星期的Android开发
  8. AndroidStudio导入新项目一直卡在Buildin
  9. Android软件开发之获取通讯录联系人信息
  10. Android 调用系统Camera