先看healthd,healthd直接查看设备节点中各种电池属性,然后调用BatteryService的update函数,下来先看healthd的代码。
int main(int argc, char **argv) {
int ch;
klog_set_level(KLOG_LEVEL);
while ((ch = getopt(argc, argv, "n")) != -1) {
switch (ch) {
case 'n':
nosvcmgr = true;
break;
case '?':
default:
KLOG_WARNING(LOG_TAG, "Unrecognized healthd option: %c\n", ch);
}
}
healthd_board_init(&healthd_config);
wakealarm_init();
uevent_init();
binder_init();
//建BatteryMonitor对象,及初始化
gBatteryMonitor = new BatteryMonitor();
gBatteryMonitor->init(&healthd_config, nosvcmgr);
//主函数、用epoll不断循环看有没有事件,有事件直接到battery_update
healthd_mainloop();
return 0;
}
直接调用battery_update函数,主要设置了电池状态检查的时间,以及调用BatteryMonitor的update函数。
static void battery_update(void) {
// Fast wake interval when on charger (watch for overheat);
// slow wake interval when on battery (watch for drained battery).
//直接调用BatteryMonitor的update函数,如果在充电就将循环监控的时间设短,没在充电就长些
int new_wake_interval = gBatteryMonitor->update() ?
healthd_config.periodic_chores_interval_fast :
healthd_config.periodic_chores_interval_slow;
if (new_wake_interval != wakealarm_wake_interval)
wakealarm_set_interval(new_wake_interval);
// During awake periods poll at fast rate. If wake alarm is set at fast
// rate then just use the alarm; if wake alarm is set at slow rate then
// poll at fast rate while awake and let alarm wake up at slow rate when
// asleep.
if (healthd_config.periodic_chores_interval_fast == -1)
awake_poll_interval = -1;
else
awake_poll_interval =
new_wake_interval == healthd_config.periodic_chores_interval_fast ?
-1 : healthd_config.periodic_chores_interval_fast * 1000;
}
init函数主要是保存一些地址信息,以及充电方式。
void BatteryMonitor::init(struct healthd_config *hc, bool nosvcmgr) {
String8 path;
mHealthdConfig = hc;
DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
if (dir == NULL) {
KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
} else {
struct dirent* entry;
while ((entry = readdir(dir))) {
const char* name = entry->d_name;
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
char buf[20];
// Look for "type" file in each subdirectory
path.clear();
path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
//先根据sys/power/../type 来看是属于两个类型的
switch(readPowerSupplyType(path)) {
case ANDROID_POWER_SUPPLY_TYPE_AC:
//保存地址
if (mHealthdConfig->acChargeHeathPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->acChargeHeathPath = path;
}
path.clear();
path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path.string(), R_OK) == 0)
//充电方式都保存起来
mChargerNames.add(String8(name));
break;
case ANDROID_POWER_SUPPLY_TYPE_USB:
if (mHealthdConfig->usbChargeHeathPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->usbChargeHeathPath = path;
}
path.clear();
path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path.string(), R_OK) == 0)
mChargerNames.add(String8(name));
break;
case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
path.clear();
path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path.string(), R_OK) == 0)
mChargerNames.add(String8(name));
break;
case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
//电池状态的各个信息保存起来
if (mHealthdConfig->batteryStatusPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryStatusPath = path;
}
if (mHealthdConfig->batteryHealthPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryHealthPath = path;
}
if (mHealthdConfig->batteryPresentPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryPresentPath = path;
}
。。。
if (nosvcmgr == false) {
\\这里其实封装了binder,用于和batterservice通信
mBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar(this);
mBatteryPropertiesRegistrar->publish();
}
接下来调用update函数,代码如下:
bool BatteryMonitor::update(void) {
struct BatteryProperties props;
bool logthis;
props.chargerAcOnline = false;
props.chargerUsbOnline = false;
props.chargerWirelessOnline = false;
props.batteryStatus = BATTERY_STATUS_UNKNOWN;
props.batteryHealth = BATTERY_HEALTH_UNKNOWN;
props.batteryCurrentNow = INT_MIN;
props.batteryChargeCounter = INT_MIN;
//用前面init中获取到的地址保存各种电池状态信息
if (!mHealthdConfig->batteryPresentPath.isEmpty())
props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
else
props.batteryPresent = true;
props.batteryLevel = getIntField(mHealthdConfig->batteryCapacityPath);
props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
props.batteryCurrentNow = getIntField(mHealthdConfig->batteryCurrentNowPath);
if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);
props.batteryTemperature = getIntField(mHealthdConfig->batteryTemperaturePath);
const int SIZE = 128;
char buf[SIZE];
String8 btech;
if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0)
props.batteryStatus = getBatteryStatus(buf);
if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0)
props.batteryHealth = getBatteryHealth(buf);
if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0)
props.batteryTechnology = String8(buf);
if (readFromFile(mHealthdConfig->acChargeHeathPath, buf, SIZE) > 0)
props.acChargeHeath= String8(buf);
if (readFromFile(mHealthdConfig->usbChargeHeathPath, buf, SIZE) > 0)
props.usbChargeHeath= String8(buf);
unsigned int i;
//利用init中保存的各个充电方式,看是哪个在充电
for (i = 0; i < mChargerNames.size(); i++) {
String8 path;
path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
mChargerNames[i].string());
if (readFromFile(path, buf, SIZE) > 0) {
if (buf[0] != '0') {
path.clear();
path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
mChargerNames[i].string());
switch(readPowerSupplyType(path)) {
case ANDROID_POWER_SUPPLY_TYPE_AC:
props.chargerAcOnline = true;
break;
case ANDROID_POWER_SUPPLY_TYPE_USB:
props.chargerUsbOnline = true;
break;
case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
props.chargerWirelessOnline = true;
break;
default:
KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
mChargerNames[i].string());
}
}
}
}
logthis = !healthd_board_battery_update(&props);
if (logthis) {
char dmesgline[256];
snprintf(dmesgline, sizeof(dmesgline),
"battery l=%d v=%d t=%s%d.%d h=%d st=%d",
props.batteryLevel, props.batteryVoltage,
props.batteryTemperature < 0 ? "-" : "",
abs(props.batteryTemperature / 10),
abs(props.batteryTemperature % 10), props.batteryHealth,
props.batteryStatus);
if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
char b[20];
snprintf(b, sizeof(b), " c=%d", props.batteryCurrentNow / 1000);
strlcat(dmesgline, b, sizeof(dmesgline));
}
KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
props.chargerAcOnline ? "a" : "",
props.chargerUsbOnline ? "u" : "",
props.chargerWirelessOnline ? "w" : "");
}
if (mBatteryPropertiesRegistrar != NULL)
//利用binder封装,传数据到BatteryService
mBatteryPropertiesRegistrar->notifyListeners(props);
//返回是否在充电,用来电池循环检查的时间间隔设置
return props.chargerAcOnline | props.chargerUsbOnline |
props.chargerWirelessOnline;
}
如此healthd差不多分析完了,接下来看BatteryService分析。
————————————————
版权声明:本文为CSDN博主「kc专栏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kc58236582/article/details/45563139