android4.4 healthd深入分析

先看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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值