Android电源管理-Healthd (2)

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

1 adb root
2 adb shell
3 cd/sys/class/power_supply
4 ll

输出如下:

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

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

1 cdusb
2 ls

输出如下:

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

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

  • 遍历所有系统支持的电源方式
  • 查看online的值,值为1即是当前电源方式
    • 回到代码,我们看看是不是真的这样做的呢。
      查看 system/core/healthd/BatteryMonitor.cpp,关注下面的片段:

      1 for(i = 0; i < mChargerNames.size(); i++) {
      2     String8 path;
      3     path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
      4                       mChargerNames[i].string());
      5  
      6     if(readFromFile(path, buf, SIZE) > 0) {
      7         if(buf[0] != '0') {
      8             path.clear();
      9             path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
      10                               mChargerNames[i].string());
      11             switch(readPowerSupplyType(path)) {
      12             caseANDROID_POWER_SUPPLY_TYPE_AC:
      13                 props.chargerAcOnline = true;
      14                 break;
      15             caseANDROID_POWER_SUPPLY_TYPE_USB:
      16                 props.chargerUsbOnline = true;
      17                 break;
      18             caseANDROID_POWER_SUPPLY_TYPE_WIRELESS:
      19                 props.chargerWirelessOnline = true;
      20                 break;
      21             default:
      22                 KLOG_WARNING(LOG_TAG,"%s: Unknown power supply type\n",
      23                              mChargerNames[i].string());
      24             }
      25         }
      26     }
      27 }

      其中POWER_SUPPLY_SYSFS_PATH的定义为:

      1 #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,下回就看看这个文件。

  • 本人补充:epoll 于Healthd使用:
static int healthd_init() {
    epollfd = epoll_create(MAX_EPOLL_EVENTS);
    if (epollfd == -1) {
        KLOG_ERROR(LOG_TAG,
                   "epoll_create failed; errno=%d\n",
                   errno);
        return -1;
    }

    .......
 }

int healthd_register_event(int fd, void (*handler)(uint32_t)) {
    struct epoll_event ev;


    ev.events = EPOLLIN | EPOLLWAKEUP;
    ev.data.ptr = (void *)handler;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        KLOG_ERROR(LOG_TAG,
                   "epoll_ctl failed; errno=%d\n", errno);
        return -1;
    }

static void healthd_mainloop(void) {
    while (1) {
        struct epoll_event events[eventct];
        int nevents;
        int timeout = awake_poll_interval;
        int mode_timeout;
         .......
        nevents = epoll_wait(epollfd, events, eventct, timeout);
        .......
        for (int n = 0; n < nevents; ++n) {
            if (events[n].data.ptr)
                (*(void (*)(int))events[n].data.ptr)(events[n].events);
        }
    eventct++;
    return 0;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值