adb shell进入到/sys/class/power_supply目录,我们可以看到power_supply驱动创建的一些运行时文件(我的设备是Nuxus 7, Android 4.4.2, kernel 3.4.0):
输出如下:
看文件名称就能知道其含义,但是问题是这里一下子列出了4种电源类型,Android系统究竟是怎么判断当前使用的是那一种呢?要回答这个问题,我们不妨进入其中任一个文件夹,看看里面记录的是些什么。
输出如下:
查看online文件,发现里面的值为1,这是因为我的设备正在使用USB电源,此时如果查看ac或者wireless文件夹中的online文件,你会发现其值为0;
再查看type文件,发现里面的值为USB,这个文件记录了对于的名称。
所以Android系统对当前电源类型的判别逻辑是这样的:
- 遍历所有系统支持的电源方式
- 查看online的值,值为1即是当前电源方式
-
回到代码,我们看看是不是真的这样做的呢。
查看 system/core/healthd/BatteryMonitor.cpp,关注下面的片段:其中POWER_SUPPLY_SYSFS_PATH的定义为:
上面的代码很容易理解,当遍历所有支持的电源类型(存储在mChargerNames),当发现其中online文件记录的值不为0的时候,再通过其type文件读取其类型名,并把props结构体中对应的字段设置成true。
注意这个props变量很关键,它的类型为BatteryProperties,它记录并传递关于电源的许多信息。
BatteryProperties的定义在frameworks/native/include/batteryservice/BatteryService.h,下回就看看这个文件。
-
回到代码,我们看看是不是真的这样做的呢。
- 本人补充:epoll 于Healthd使用:
epollfd = epoll_create(MAX_EPOLL_EVENTS);
if (epollfd == -1) {
KLOG_ERROR(LOG_TAG,
"epoll_create failed; errno=%d\n",
errno);
return -1;
}
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;
}