转自:http://blog.csdn.net/kc58236582/article/details/47300413 healthd主要是读取电池节点的信息,传给BatteryService。或者在关机充电等使用。注意healthd中使用的是kernel的log。
下面先从main函数分析
- int main(int argc, char **argv) {
- int ch;
- int ret;
-
- klog_set_level(KLOG_LEVEL);
- healthd_mode_ops = &android_ops;
-
- if (!strcmp(basename(argv[0]), "charger")) {//解析输入参数如果是charger的使用charger_ops,这里就不做介绍
- healthd_mode_ops = &charger_ops;
- } else {
- while ((ch = getopt(argc, argv, "cr")) != -1) {//分析输入命令,各个命令对应不同的charger_ops
- switch (ch) {
- case 'c':
- healthd_mode_ops = &charger_ops;
- break;
- case 'r':
- healthd_mode_ops = &recovery_ops;
- break;
- case '?':
- default:
- KLOG_ERROR(LOG_TAG, "Unrecognized healthd option: %c\n",
- optopt);
- exit(1);
- }
- }
- }
-
- ret = healthd_init();//healthd做初始化
- if (ret) {
- KLOG_ERROR("Initialization failed, exiting\n");
- exit(2);
- }
-
- healthd_mainloop();//主函数
- KLOG_ERROR("Main loop terminated, exiting\n");
- return 3;
- }
如果是正常开机,不走关机充电等,healthd_mode_ops = &android_ops;而这里面具体的函数在后面进行详细的介绍。
- static struct healthd_mode_ops android_ops = {
- .init = healthd_mode_android_init,
- .preparetowait = healthd_mode_android_preparetowait,
- .heartbeat = healthd_mode_nop_heartbeat,
- .battery_update = healthd_mode_android_battery_update,
- };
下面分析下healthd_init函数,heathd使用了epoll进行IO复用。
- 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;
- }
-
- healthd_board_init(&healthd_config);
- healthd_mode_ops->init(&healthd_config);
- wakealarm_init();
- uevent_init();
- gBatteryMonitor = new BatteryMonitor();
- gBatteryMonitor->init(&healthd_config);
- return 0;
- }
这里的healthd_mode_ops->init的函数是android_ops 的healthd_mode_android_init函数,这里主要是将binder通信的fd也加入epoll,而不像普通binder进程最后使用IPCThreadState::self()->joinThreadPool。这样所有的fd全在epoll管理,只用了一个线程
- int healthd_mode_android_preparetowait(void) {
- IPCThreadState::self()->flushCommands();
- return -1;
- }
-
- static void binder_event(uint32_t /*epevents*/) {
- IPCThreadState::self()->handlePolledCommands();
- }
-
- void healthd_mode_android_init(struct healthd_config* /*config*/) {
- ProcessState::self()->setThreadPoolMaxThreadCount(0);
- IPCThreadState::self()->disableBackgroundScheduling(true);
- IPCThreadState::self()->setupPolling(&gBinderFd);
-
- if (gBinderFd >= 0) {
- if (healthd_register_event(gBinderFd, binder_event))
- KLOG_ERROR(LOG_TAG,
- "Register for binder events failed\n");
- }
-
- gBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar();
- gBatteryPropertiesRegistrar->publish();
- }
gBatteryPropertiesRegistrar->publish将"batteryproperties"这个Service加入到ServiceManager中
- void BatteryPropertiesRegistrar::publish() {
- defaultServiceManager()->addService(String16("batteryproperties"), this);
- }
接下来再来看下wakealarm_init
- static void wakealarm_init(void) {
- wakealarm_fd = timerfd_create(CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK);
- if (wakealarm_fd == -1) {
- KLOG_ERROR(LOG_TAG, "wakealarm_init: timerfd_create failed\n");
- return;
- }
-
- if (healthd_register_event(wakealarm_fd, wakealarm_event))
- KLOG_ERROR(LOG_TAG,
- "Registration of wakealarm event failed\n");
-
- wakealarm_set_interval(healthd_config.periodic_chores_interval_fast);
- }
wakealarm_init设置alarm唤醒的interval,再来看下时间处理函数
- static void wakealarm_event(uint32_t /*epevents*/) {
- unsigned long long wakeups;
-
- if (read(wakealarm_fd, &wakeups, sizeof(wakeups)) == -1) {//出错结束
- KLOG_ERROR(LOG_TAG, "wakealarm_event: read wakealarm fd failed\n");
- return;
- }
- KLOG_ERROR(LOG_TAG, "wakealarm_event\n");
- periodic_chores();
- }
- static void periodic_chores() {
- healthd_battery_update();
- }
- void healthd_battery_update(void) {
- // Fast wake interval when on charger (watch for overheat);
- // slow wake interval when on battery (watch for drained battery).
- KLOG_ERROR(LOG_TAG, "healthd_battery_update enter\n");
- int new_wake_interval = gBatteryMonitor->update() ?//调用主要的update函数,根据返回值,如果当前在充电返回true
- healthd_config.periodic_chores_interval_fast ://时间设置1分钟
- healthd_config.periodic_chores_interval_slow;
- KLOG_ERROR(LOG_TAG, "kangchen healthd_battery_update after\n");
- 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 ?//当前时间是一分钟,epoll为永远阻塞,否则为1分钟
- -1 : healthd_config.periodic_chores_interval_fast * 1000;
- }
接下来再来看看uEvent的,
- static void uevent_init(void) {
- uevent_fd = uevent_open_socket(64*1024, true);
-
- if (uevent_fd < 0) {
- KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
- return;
- }
-
- fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
- if (healthd_register_event(uevent_fd, uevent_event))
- KLOG_ERROR(LOG_TAG,
- "register for uevent events failed\n");
- }
看看uevent_event的处理函数,获取uevent后主要判断是否是电源系统的,如果是调用healthd_battery_update函数
- static void uevent_event(uint32_t /*epevents*/) {
- char msg[UEVENT_MSG_LEN+2];
- char *cp;
- int n;
-
- n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN);
- if (n <= 0)
- return;
- if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
- return;
-
- msg[n] = '\0';
- msg[n+1] = '\0';
- cp = msg;
- KLOG_ERROR(LOG_TAG, "uevent_event\n");
- while (*cp) {
- if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) {//是这个子系统的调用healthd_battery_update函数
- healthd_battery_update();
- break;
- }
-
- /* advance to after the next \0 */
- while (*cp++)
- ;
- }
- }
下面分析下healthd_mainloop这个主函数,主函数主要是epoll函数监听3个fd,有事件就处理。
- static void healthd_mainloop(void) {
- while (1) {
- struct epoll_event events[eventct];
- int nevents;
- int timeout = awake_poll_interval;
- int mode_timeout;
-
- mode_timeout = healthd_mode_ops->preparetowait();
- if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout))
- timeout = mode_timeout;
- nevents = epoll_wait(epollfd, events, eventct, timeout);//epoll_wait等待各个fd的事件,timeout为超时时间
- KLOG_ERROR(LOG_TAG, "kangchen healthd_mainloop epoll_wait\n");
- if (nevents == -1) {
- if (errno == EINTR)
- continue;
- KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n");
- break;
- }
-
- for (int n = 0; n < nevents; ++n) {
- if (events[n].data.ptr)//遍历各个fd的事件上来,每个处理函数处理
- (*(void (*)(int))events[n].data.ptr)(events[n].events);
- }
-
- if (!nevents)//当什么事件没有的时候,是因为epoll超时设置走下来的,这时候也要update下
- periodic_chores();
-
- healthd_mode_ops->heartbeat();
- }
-
- return;
- }
init函数主要将healthd_config 对象传入,并且将里面的成员的一些地址信息去初始化保存起来。主要是保存一些地址信息,以及充电方式。
- void BatteryMonitor::init(struct healthd_config *hc) {
- String8 path;
- char pval[PROPERTY_VALUE_MAX];
-
- mHealthdConfig = hc;//将外面传进来的heathdconfig的指针赋给成员变量
- DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);//打开地址 /sys/class/power_supply
- 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);
- switch(readPowerSupplyType(path)) {//读取各个目录下type的值,比如/sys/class/power_supply/battery 下type的值为Battery,在readPowerSupplyType读取并且转化为ANDROID_POWER_SUPPLY_TYPE_BATTERY
- 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));//chargername 就是当前目录名字:ac
- break;
-
- case ANDROID_POWER_SUPPLY_TYPE_USB://usb 类似ac
- 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://battery
- mBatteryDevicePresent = true;
-
- 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 (mHealthdConfig->batteryCapacityPath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
- name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryCapacityPath = path;
- }
-
- if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/voltage_now",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0) {
- mHealthdConfig->batteryVoltagePath = path;
- } else {
- path.clear();
- path.appendFormat("%s/%s/batt_vol",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryVoltagePath = path;
- }
- }
-
- if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/current_now",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryCurrentNowPath = path;
- }
-
- if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/current_avg",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryCurrentAvgPath = path;
- }
-
- if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/charge_counter",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryChargeCounterPath = path;
- }
-
- if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
- name);
- if (access(path, R_OK) == 0) {
- mHealthdConfig->batteryTemperaturePath = path;
- } else {
- path.clear();
- path.appendFormat("%s/%s/batt_temp",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryTemperaturePath = path;
- }
- }
-
- if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
- path.clear();
- path.appendFormat("%s/%s/technology",
- POWER_SUPPLY_SYSFS_PATH, name);
- if (access(path, R_OK) == 0)
- mHealthdConfig->batteryTechnologyPath = path;
- }
-
- break;
-
- case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
- break;
- }
- }
- closedir(dir);
- }
-
- if (!mChargerNames.size())
- KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
- if (!mBatteryDevicePresent) {//主要由battery该成员变量就为true
- KLOG_WARNING(LOG_TAG, "No battery devices found\n");
- hc->periodic_chores_interval_fast = -1;
- hc->periodic_chores_interval_slow = -1;
- } else {
- if (mHealthdConfig->batteryStatusPath.isEmpty())
- KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
- 。。。。。。。。。。。。。//这里都是一些警告
- }
-
- if (property_get("ro.boot.fake_battery", pval, NULL) > 0
- && strtol(pval, NULL, 10) != 0) {
- mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
- mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
- }
- }
下面就是update函数,将数据封装在BatteryProperties 中,并且通过healthd_mode_ops->battery_update把BatteryProperties 发给上层。
- bool BatteryMonitor::update(void) {
- bool logthis;
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- props.chargerWirelessOnline = false;
- props.batteryStatus = BATTERY_STATUS_UNKNOWN;
- props.batteryHealth = BATTERY_HEALTH_UNKNOWN;
- //都是从之前配置的mHealthd中取地址,读取节点信息,保存到props成员变量中
- if (!mHealthdConfig->batteryPresentPath.isEmpty())
- props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
- else
- props.batteryPresent = mBatteryDevicePresent;
-
- props.batteryLevel = mBatteryFixedCapacity ?
- mBatteryFixedCapacity :
- getIntField(mHealthdConfig->batteryCapacityPath);
- props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
-
- props.batteryTemperature = mBatteryFixedTemperature ?
- mBatteryFixedTemperature :
- 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;
-
- for (i = 0; i < mChargerNames.size(); i++) {//遍历之前保存的各个充电方式
- String8 path;
- path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
- mChargerNames[i].string());//路径就是每个目录下的online字段,比如/sys/class/power_supply/usb 下的online
-
- if (readFromFile(path, buf, SIZE) > 0) {
- if (buf[0] != '0') {//读取online里面的内容,如果当前在usb线上充电,那么usb下online里面的内容为1
- path.clear();
- path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
- mChargerNames[i].string());//这里看看是哪个type的
- switch(readPowerSupplyType(path)) {
- case ANDROID_POWER_SUPPLY_TYPE_AC:
- props.chargerAcOnline = true;
- break;
- case ANDROID_POWER_SUPPLY_TYPE_USB://将其值赋成true
- 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];
-
- if (props.batteryPresent) {
- 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()) {
- int c = getIntField(mHealthdConfig->batteryCurrentNowPath);
- char b[20];
-
- snprintf(b, sizeof(b), " c=%d", c / 1000);
- strlcat(dmesgline, b, sizeof(dmesgline));
- }
- } else {
- snprintf(dmesgline, sizeof(dmesgline),
- "battery none");
- }
-
- KLOG_WARNING(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
- props.chargerAcOnline ? "a" : "",
- props.chargerUsbOnline ? "u" : "",
- props.chargerWirelessOnline ? "w" : "");
- }
-
- healthd_mode_ops->battery_update(&props);//将数据传到上层的BatteryService
- return props.chargerAcOnline | props.chargerUsbOnline |//返回当前是否属于充电
- props.chargerWirelessOnline;
- }
接下来看看healthd_mode_ops->battery_update是怎么把数据传到上层的
- void healthd_mode_android_battery_update(
- struct android::BatteryProperties *props) {
- if (gBatteryPropertiesRegistrar != NULL)
- gBatteryPropertiesRegistrar->notifyListeners(*props);
-
- return;
- }
上层会通过binder通信,注册一个回调到BatteryPropertiesRegistrar
- void BatteryPropertiesRegistrar::registerListener(const sp<IBatteryPropertiesListener>& listener) {
- {
- if (listener == NULL)
- return;
- Mutex::Autolock _l(mRegistrationLock);
- // check whether this is a duplicate
- for (size_t i = 0; i < mListeners.size(); i++) {
- if (mListeners[i]->asBinder() == listener->asBinder()) {
- return;
- }
- }
-
- mListeners.add(listener);
- listener->asBinder()->linkToDeath(this);
- }
- healthd_battery_update();
- }
而update函数就是调用了notifyListeners遍历各个listener传到上层BatteryService
- void BatteryPropertiesRegistrar::notifyListeners(struct BatteryProperties props) {
- Mutex::Autolock _l(mRegistrationLock);
- for (size_t i = 0; i < mListeners.size(); i++) {
- mListeners[i]->batteryPropertiesChanged(props);
- }
- }
再来看看BatteryService中,在onStart中通过ServiceManager,和batteryproperties这个Service通信,将BatteryListener这个listenter注册到batteryproperties中去
- @Override
- public void onStart() {
- IBinder b = ServiceManager.getService("batteryproperties");
- final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
- IBatteryPropertiesRegistrar.Stub.asInterface(b);
- try {
- batteryPropertiesRegistrar.registerListener(new BatteryListener());
- } catch (RemoteException e) {
- // Should never happen.
- }
-
- publishBinderService("battery", new BinderService());
- publishLocalService(BatteryManagerInternal.class, new LocalService());
- }
再来看看BatteryListener 的batteryPropertiesChanged接口,当下面调这个接口,就会调用BatteryService的update函数,然后就是BatteryService的一些主要流程就不分析了。
- private final class BatteryListener extends IBatteryPropertiesListener.Stub {
- @Override
- public void batteryPropertiesChanged(BatteryProperties props) {
- final long identity = Binder.clearCallingIdentity();
- try {
- BatteryService.this.update(props);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
BatteryService接受healthd的数据都是被动的,healthd穿过来的。有没有主动去healthd查询的。
在BatteryManager中就有主动去healthd查询的,代码如下
- private long queryProperty(int id) {
- long ret;
-
- if (mBatteryPropertiesRegistrar == null) {
- IBinder b = ServiceManager.getService("batteryproperties");//获取batteryproperties Service
- mBatteryPropertiesRegistrar =
- IBatteryPropertiesRegistrar.Stub.asInterface(b);//接口转化下
-
- if (mBatteryPropertiesRegistrar == null)
- return Long.MIN_VALUE;
- }
-
- try {
- BatteryProperty prop = new BatteryProperty();
-
- if (mBatteryPropertiesRegistrar.getProperty(id, prop) == 0)//prop是输出
- ret = prop.getLong();
- else
- ret = Long.MIN_VALUE;
- } catch (RemoteException e) {
- ret = Long.MIN_VALUE;
- }
-
- return ret;
- }
再到healthd看看对应的接口
- status_t BatteryPropertiesRegistrar::getProperty(int id, struct BatteryProperty *val) {
- return healthd_get_property(id, val);
- }
- status_t healthd_get_property(int id, struct BatteryProperty *val) {
- return gBatteryMonitor->getProperty(id, val);
- }
java的BatteryProperty对象对应到这边是指针
- status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
- status_t ret = BAD_VALUE;
-
- val->valueInt64 = LONG_MIN;
-
- switch(id) {
- case BATTERY_PROP_CHARGE_COUNTER://根据不同ID,返回不同值
- if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
- val->valueInt64 =
- getIntField(mHealthdConfig->batteryChargeCounterPath);
- ret = NO_ERROR;
- } else {
- ret = NAME_NOT_FOUND;
- }
- break;
-
- case BATTERY_PROP_CURRENT_NOW:
- if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
- val->valueInt64 =
- getIntField(mHealthdConfig->batteryCurrentNowPath);
- ret = NO_ERROR;
- } else {
- ret = NAME_NOT_FOUND;
- }
- break;
-
- case BATTERY_PROP_CURRENT_AVG:
- if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
- val->valueInt64 =
- getIntField(mHealthdConfig->batteryCurrentAvgPath);
- ret = NO_ERROR;
- } else {
- ret = NAME_NOT_FOUND;
- }
- break;
-
- case BATTERY_PROP_CAPACITY:
- if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
- val->valueInt64 =
- getIntField(mHealthdConfig->batteryCapacityPath);
- ret = NO_ERROR;
- } else {
- ret = NAME_NOT_FOUND;
- }
- break;
-
- case BATTERY_PROP_ENERGY_COUNTER:
- if (mHealthdConfig->energyCounter) {
- ret = mHealthdConfig->energyCounter(&val->valueInt64);
- } else {
- ret = NAME_NOT_FOUND;
- }
- break;
-
- default:
- break;
- }
-
- return ret;
- }
|