Android:充电模式启动简要流程

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 产品上,公司加入了 Type-C 的充电接口,需要在充电模式下,显示充电动画,而芯片厂家的原生 SDK 不支持,因此需要了解如何进入充电启动模式、以及充电模式启动流程,然后添加需要的修改。

posted @ 2025-04-08 09:01  JiMoKuangXiangQu  阅读(20)  评论(0)    收藏  举报