Android电池管理系统框架整理

本文详细探讨了Android系统中的电池服务、Healthd组件以及底层驱动如何协作监控和管理电池。从电池事件监听、数据上报、框架交互到驱动实现,揭示了电池电量信息从内核到用户界面的完整流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Android 电池服务

Android电池服务,用来监听内核上报的电池事件,并将最新的电池数据上报给系统,系统收到新数据后会去更新电池显示状态、剩余电量等信息。如果收到过温报警和低电报警,系统会自动触发关机流程,保护电池和机器不受到危害。

Android电池服务的启动和运行流程:

97edeae4f016bc4fd7808396ea057009.png Android电池服务的源码结构

Framework\base\services\java\com\android\server

├── SystemServer.java

创建BatteryServices、PowerManagerService、ActivityManagerService

├── BatterySevices.java

监听底层上报的battery事件,广播电池发生改变的消息

Framework\base\services\java\com\android\server\am

├── ActivityManagerService.java

创建BatteryStatsService

├── BatteryStatsService.java

统计和记录电池参数的信息

Framework\base\services\java\com\android\server\power

├── PowerManagerService.java

监听电池发生变化的广播消息,并调节系统的电源状态,例如亮屏

Framework\base\core\java\com\internal\os\

├── BatteryStatsImpl.java

统计和记录电池参数的信息,并通知其他模块

System\core\healthd

├── healthd.cpp

创建uevent socket,监听内核上报的内核事件

├── BatteryMonitor.cpp

初始化本地电池数据结构,将power_supply路径下属性节点路径填充进去,

├── BatteryMonitor.h

├── BatteryPropertiesRegistrar.cpp

创建电池属性监听器,并将其注册到Android的系统服务中

├── BatteryPropertiesRegistrar.h

二、Healthd

该模型向下监听来自底层的电池事件,向上传递电池数据信息给Framework层的BatteryService用来计算电池电量相关信息,

BatteryService通过传递来的数据来计算电池电量等信息,因此healthd在电池管理系统中起着承上启下的作用。

c20e4bf98f6376c9b827c7e1be8e7d89.png

healthd的具体调用流程深入分析android5.1 healthd这篇文章讲得很清楚。

三、驱动

Android电源管理底层用的是Linux power_supply框架,内核提供给电池驱动的接口是结构体power_supply结构体。

/*文件:kernel/drivers/power*/
struct power_supply {
const char *name;

enum power_supply_type type;

enum power_supply_property *properties;

size_t num_properties;

char **supplied_to;

size_t num_supplicants;

int (*get_property)(struct power_supply *psy,

enum power_supply_property psp,

union power_supply_propval *val);

int (*set_property)(struct power_supply *psy,

enum power_supply_property psp,

const union power_supply_propval *val);

int (*property_is_writeable)(struct power_supply *psy,

enum power_supply_property psp);

void (*external_power_changed)(struct power_supply *psy);

void (*set_charged)(struct power_supply *psy);

/* For APM emulation, think legacy userspace. */

int use_for_apm;

/* Driver private data */

void *drv_data;//add by bhj

/* private */

struct device *dev;

struct work_struct changed_work;

spinlock_t changed_lock;

bool changed;

struct wake_lock work_wake_lock;

struct delayed_work deferred_register_work;

#ifdef CONFIG_LEDS_TRIGGERS

struct led_trigger *charging_full_trig;

char *charging_full_trig_name;

struct led_trigger *charging_trig;

char *charging_trig_name;

struct led_trigger *full_trig;

char *full_trig_name;

struct led_trigger *online_trig;

char *online_trig_name;

struct led_trigger *charging_blink_full_solid_trig;

char *charging_blink_full_solid_trig_name;

#endif

};

内核主要通过get_property这个函数指针来获得驱动中的有关电池的信息,而这个函数在内核中只给出了声明,我们在写驱动的时候要自己实现这个函数,即将自己写的函数赋值给这个函数指针,当内核需要驱动中电源信息的时候就回调这个get_property函数。另外,我们写驱动程序的时候又要给用户提供接口,内核中提供给用户的接口就是sysfs,通过读取sysfs文件系统中文件内容,就可以得到电源的信息。内核主要通过两个文件 power_supply_class.c 和 power_supply_core.c,我们调用其中的函数就可以把电源(电池,USB或AC)的信息展现给用户,有关电源的属性写在 /sys/class/powersupply 文件夹下(此文件夹为程序运行后所生成的)。

ac和usb只创建了一个online属性,上层通过判断ac和usb的online状态(1表示设备接入,0表示设备拔出)便可知道当前系统是由什么设备在充电了;而battery则创建了如status、health、present、capacity、batt_vol等等和电池相关的诸多属性,上层通过这些电池属性uevent便可监控电池的当前工作状态了。下面举例是battery,ac和usb同理。
 

  	955 	static int rk818_battery_get_property(struct power_supply *psy,
    956                                       enum power_supply_property psp,
    957                                       union power_supply_propval *val)
    958 	{
    959         struct rk818_battery *di = power_supply_get_drvdata(psy);
    960
    961         switch (psp) {
    962         case POWER_SUPPLY_PROP_CURRENT_NOW:
    963                 val->intval = di->current_avg * 1000;/*uA*/ //获取电池电流
    964                 if (di->pdata->bat_mode == MODE_VIRTUAL)
    965                         val->intval = VIRTUAL_CURRENT * 1000;
    966                 break;
    967         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
    968                 val->intval = di->voltage_avg * 1000;/*uV*/ //获取电池电压
    969                 if (di->pdata->bat_mode == MODE_VIRTUAL)
    970                         val->intval = VIRTUAL_VOLTAGE * 1000;
    971                 break;
    972         case POWER_SUPPLY_PROP_PRESENT:
    973                 val->intval = is_rk818_bat_exist(di);
    974                 if (di->pdata->bat_mode == MODE_VIRTUAL)
    975                         val->intval = VIRTUAL_PRESET;
    976                 break;
    977         case POWER_SUPPLY_PROP_CAPACITY:
    978                 val->intval = di->dsoc; //获取电池电量
    979                 if (di->pdata->bat_mode == MODE_VIRTUAL)
    980                         val->intval = VIRTUAL_SOC;
    981                 DBG("<%s>. report dsoc: %d\n", __func__, val->intval);
    982                 break;
    983         case POWER_SUPPLY_PROP_HEALTH:
    984                 val->intval = POWER_SUPPLY_HEALTH_GOOD;
    985                 break;
    986         case POWER_SUPPLY_PROP_TEMP:
    987                 val->intval = di->temperature;
    988                 if (di->pdata->bat_mode == MODE_VIRTUAL)
    989                         val->intval = VIRTUAL_TEMPERATURE;
    990                 break;

各能源设备属性概况如下(adb工具cat可以查看):

	/sys/class/power_supply/ac/online AC 电源连接状态

	/sys/class/power_supply/usb/online USB电源连接状态

	/sys/class/power_supply/battery/status 充电状态

	/sys/class/power_supply/battery/health 电池状态

	/sys/class/power_supply/battery/present 使用状态

	/sys/class/power_supply/battery/capacity 电池 level

	/sys/class/power_supply/battery/batt_vol 电池电压

	/sys/class/power_supply/battery/batt_temp 电池温度

	/sys/class/power_supply/battery/technology 电池技术

当供电设备的状态或者电量发生变化后,会调用power_supply_changed(&battery_data->battery)更新这些文件;

	//Send uevent.
	power_supply_changed(&battery_data->battery);

电池系统从底层向Framework层上报数据的流程:

415d9d0e77e4d66852b472bdea54ec8a.png

备注:(Uevent机制)
Uevent是内核通知android有状态变化的一种方法,比如USB线插入、拔出,电池电量变化等等。其本质是内核发送(可以通过socket)一个字符串,应用层(android)接收并解释该字符串,获取相应信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值