先看healthd,healthd直接查看设备节点中各类电池属性,而后调用BatteryService的update函数,下来先看healthd的代码。app
- 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函数。less
- 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函数,代码以下:oop
- 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分析。this