Android 电源管理-Healthd(2)

接上文 「Android电源管理-Healthd (1)」

adb shell进入到/sys/class/power_supply目录,我们可以看到power_supply驱动创建的一些运行时文件(我的设备是Nuxus 7, Android 4.4.2, kernel 3.4.0):

adb root
adb shell
cd /sys/class/power_supply
ll

输出如下:

lrwxrwxrwx root  root  2014-09-19 14:30 ac -> ../../devices/i2c-0/0-0055/power_supply/ac
lrwxrwxrwx root  root  2014-09-19 14:30 battery -> ../../devices/i2c-0/0-0055/power_supply/battery
lrwxrwxrwx root  root  2014-09-19 14:30 usb -> ../../devices/i2c-0/0-0055/power_supply/usb
lrwxrwxrwx root  root  2014-09-19 14:30 wireless -> ../../devices/i2c-0/0-0055/power_supply/wireless

看文件名称就能知道其含义,但是问题是这里一下子列出了4种电源类型,Android系统究竟是怎么判断当前使用的是那一种呢?要回答这个问题,我们不妨进入其中任一个文件夹,看看里面记录的是些什么。

cd usb
ls

输出如下:

lrwxrwxrwx root root        2014-09-20 22:03 device -> ../../../0-0055
-r--r--r-- root root   4096 2014-09-19 14:30 online
drwxr-xr-x root root        2014-09-20 22:03 power
lrwxrwxrwx root root        2014-09-20 22:03 subsystem -> ../../../../../class/power_supply
-r--r--r-- root root   4096 2014-09-19 18:24 type
-rw-r--r-- root root    4096 2014-09-20 22:03 uevent

查看online文件,发现里面的值为1,这是因为我的设备正在使用USB电源,此时如果查看ac或者wireless文件夹中的online文件,你会发现其值为0; 再查看type文件,发现里面的值为USB,这个文件记录了对于的名称。 所以Android系统对当前电源类型的判别逻辑是这样的:

回到代码,我们看看是不是真的这样做的呢 查看system/core/healthd/BatteryMonitor.cpp关注下面的片段:

        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());
                    }
                }
            }
        }

其中POWER_SUPPLY_SYSFS_PATH的定义为:

#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM

上面的代码很容易理解,当遍历所有支持的电源类型(存储在mChargerNames),当发现其中online文件记录的值不为0的时候,再通过其type文件读取其类型名,并把props结构体中对应的字段设置成true。 注意这个props变量很关键,它的类型为BatteryProperties,它记录并传递关于电源的许多信息。 BatteryProperties的定义在frameworks/native/include/batteryservice/BatteryService.h,下回就看看这个文件。