1. 前言
限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。
2. 背景
本文分析基于 Android 6.0.1,仅供参考。
3. 充电模式启动简要流程
/*
* 首先,在 u-boot 里面传递 androidboot.mode=charger 给内核命令行。
* 我们这里没有内核代码的描述,因为这不是我们的重点。
*/
u-boot 启动 kernel
kernel 启动 init 程序
main() /* system/core/init/init.cpp */
/* 解析kernel传递过来的command line(/proc/cmdline) */
process_kernel_cmdline()
import_kernel_cmdline(false, import_kernel_nv) /* /proc/cmdline */
...
import_kernel_nv()
...
/* 设定启动模式属性为 charger */
property_set("ro.boot.mode", "charger")
/* 设定kernel boot模式属性: ro.bootmode = charger */
export_kernel_boot_props()
...
/*
* charger boot 模式不需要启动更多的程序, charger 即可.
*
* on charger
* class_start charger
*
* service charger /charger # 这里的 /charger 程序是 healthd 的符号链接
* class charger
* seclabel u:r:healthd:s0
*/
if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) {
action_for_each_trigger("charger", action_add_queue_tail);
...
/*
* 触发 healthd 程序入口 main():
* 看后面 healthd 程序流程。
*/
} else {
...
}
healthd 程序流程:
main() @ system/core/healthd/healthd.cpp
static struct healthd_mode_ops charger_ops = {
.init = healthd_mode_charger_init,
.preparetowait = healthd_mode_charger_preparetowait,
.heartbeat = healthd_mode_charger_heartbeat,
.battery_update = healthd_mode_charger_battery_update,
};
/* 按情况设定回调函数簇: 用来处理电池的状态更新 */
healthd_mode_ops = &android_ops / &charger_ops / &recovery_ops
/* 初始化 */
healthd_init()
epollfd = epoll_create(MAX_EPOLL_EVENTS)
healthd_mode_ops->init(&healthd_config)
healthd_mode_charger_init() /* system/core/healthd/healthd_mode_charger.cpp */
wakealarm_init()
uevent_init()
gBatteryMonitor = new BatteryMonitor()
gBatteryMonitor->init(&healthd_config)
/* 事件状态更新循环 */
healthd_mainloop()
while (1) {
mode_timeout = healthd_mode_ops->preparetowait()
healthd_mode_charger_preparetowait()
/* 读取事件 */
nevents = epoll_wait(epollfd, events, eventct, timeout)
/* 处理事件 */
for (int n = 0; n < nevents; ++n) {
/* 事件处理回调 */
}
/* 电池状态画面更新 */
healthd_mode_ops->heartbeat()
healthd_mode_charger_heartbeat()
}
4. 后记
之所以研究了Android充电模式启动流程,是源于实际项目需求。在一款VR产品上,公司加入了TypeC的充电接口,需要在充电模式下,显示充电动画,而芯片厂家的原生SDK不支持,因此需要了解如何进入充电启动模式、以及充电模式启动流程,然后添加需要的修改。