BatteryMonitor.cpp revision 020369d8724eff2b87350e54e157a609846166e4
1752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor/*
2752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * Copyright (C) 2013 The Android Open Source Project
3752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor *
4752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * Licensed under the Apache License, Version 2.0 (the "License");
5752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * you may not use this file except in compliance with the License.
6752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * You may obtain a copy of the License at
7752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor *
8752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor *      http://www.apache.org/licenses/LICENSE-2.0
9752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor *
10752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * Unless required by applicable law or agreed to in writing, software
11752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * distributed under the License is distributed on an "AS IS" BASIS,
12752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * See the License for the specific language governing permissions and
14752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * limitations under the License.
15752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor */
16752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
17752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define LOG_TAG "healthd"
18752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
1910b235e7436256da9adc827125645f141bd8fac9Todd Poynor#include "healthd.h"
20752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include "BatteryMonitor.h"
21752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
22752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <dirent.h>
23752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <errno.h>
24752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <fcntl.h>
25752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <stdio.h>
26752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <stdlib.h>
27752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <unistd.h>
28752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <batteryservice/BatteryService.h>
29752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <cutils/klog.h>
30c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor#include <utils/Errors.h>
31752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/String8.h>
32752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/Vector.h>
33752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
34752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SUBSYSTEM "power_supply"
35752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
36752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
37752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynornamespace android {
38752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
39752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstruct sysfsStringEnumMap {
40752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char* s;
41752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int val;
42752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor};
43752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
44752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstatic int mapSysfsString(const char* str,
45752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                          struct sysfsStringEnumMap map[]) {
46752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    for (int i = 0; map[i].s; i++)
47752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (!strcmp(str, map[i].s))
48752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            return map[i].val;
49752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
50752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return -1;
51752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
52752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
53752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryStatus(const char* status) {
54752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int ret;
55752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap batteryStatusMap[] = {
56752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unknown", BATTERY_STATUS_UNKNOWN },
57752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Charging", BATTERY_STATUS_CHARGING },
58752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Discharging", BATTERY_STATUS_DISCHARGING },
59752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Not charging", BATTERY_STATUS_NOT_CHARGING },
60752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Full", BATTERY_STATUS_FULL },
61752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { NULL, 0 },
62752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
63752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
64752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = mapSysfsString(status, batteryStatusMap);
65752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0) {
66752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
67752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = BATTERY_STATUS_UNKNOWN;
68752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
69752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
70752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
71752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
72752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
73752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryHealth(const char* status) {
74752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int ret;
75752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap batteryHealthMap[] = {
76752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unknown", BATTERY_HEALTH_UNKNOWN },
77752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Good", BATTERY_HEALTH_GOOD },
78752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Overheat", BATTERY_HEALTH_OVERHEAT },
79752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Dead", BATTERY_HEALTH_DEAD },
80752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE },
81752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE },
82752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Cold", BATTERY_HEALTH_COLD },
83752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { NULL, 0 },
84752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
85752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
86752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = mapSysfsString(status, batteryHealthMap);
87752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0) {
88752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
89752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = BATTERY_HEALTH_UNKNOWN;
90752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
91752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
92752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
93752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
94752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
95752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::readFromFile(const String8& path, char* buf, size_t size) {
96752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char *cp = NULL;
97752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
98752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (path.isEmpty())
99752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return -1;
100752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int fd = open(path.string(), O_RDONLY, 0);
101752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (fd == -1) {
102752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "Could not open '%s'\n", path.string());
103752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return -1;
104752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
105752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
106752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ssize_t count = TEMP_FAILURE_RETRY(read(fd, buf, size));
107752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (count > 0)
108752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            cp = (char *)memrchr(buf, '\n', count);
109752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
110752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (cp)
111752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        *cp = '\0';
112752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    else
113752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        buf[0] = '\0';
114752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
115752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    close(fd);
116752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return count;
117752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
118752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
119752faf2c18407fd79127fb3f3773910b4ddf669dTodd PoynorBatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) {
120752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
121752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
122752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int length = readFromFile(path, buf, SIZE);
123752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    BatteryMonitor::PowerSupplyType ret;
124752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap supplyTypeMap[] = {
125752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN },
126752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY },
127752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "UPS", ANDROID_POWER_SUPPLY_TYPE_AC },
128752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Mains", ANDROID_POWER_SUPPLY_TYPE_AC },
129752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB", ANDROID_POWER_SUPPLY_TYPE_USB },
130752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC },
131752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC },
132752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC },
133752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS },
134752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { NULL, 0 },
135752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
136752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
137752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (length <= 0)
138752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
139752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
140752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap);
141752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0)
142752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
143752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
144752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
145752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
146752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
147752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::getBooleanField(const String8& path) {
148752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 16;
149752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
150752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
151752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    bool value = false;
152752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (readFromFile(path, buf, SIZE) > 0) {
153752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (buf[0] != '0') {
154752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            value = true;
155752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
156752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
157752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
158752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return value;
159752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
160752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
161752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getIntField(const String8& path) {
162752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
163752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
164752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
165752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int value = 0;
166752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (readFromFile(path, buf, SIZE) > 0) {
167752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        value = strtol(buf, NULL, 0);
168752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
169752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return value;
170752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
171752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
172752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::update(void) {
1732e227fbc5ad735856ce016714440e377e85fb839Todd Poynor    struct BatteryExtraProperties extraProps;
17410b235e7436256da9adc827125645f141bd8fac9Todd Poynor    bool logthis;
175752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
176752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.chargerAcOnline = false;
177752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.chargerUsbOnline = false;
178752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.chargerWirelessOnline = false;
179752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.batteryStatus = BATTERY_STATUS_UNKNOWN;
180752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.batteryHealth = BATTERY_HEALTH_UNKNOWN;
1812e227fbc5ad735856ce016714440e377e85fb839Todd Poynor    extraProps.batteryCurrentNow = INT_MIN;
1822e227fbc5ad735856ce016714440e377e85fb839Todd Poynor    extraProps.batteryChargeCounter = INT_MIN;
183752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
184f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (!mHealthdConfig->batteryPresentPath.isEmpty())
185f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor        props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
186752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    else
1876dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        props.batteryPresent = mBatteryDevicePresent;
188752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
189f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    props.batteryLevel = getIntField(mHealthdConfig->batteryCapacityPath);
190f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
191b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
192f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
1932e227fbc5ad735856ce016714440e377e85fb839Todd Poynor        extraProps.batteryCurrentNow = getIntField(mHealthdConfig->batteryCurrentNowPath);
194b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
1952e227fbc5ad735856ce016714440e377e85fb839Todd Poynor    /* temporary while dumpsys being reworked */
196f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
1972e227fbc5ad735856ce016714440e377e85fb839Todd Poynor        extraProps.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);
198b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
199f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    props.batteryTemperature = getIntField(mHealthdConfig->batteryTemperaturePath);
200752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
201752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
202752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
203752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    String8 btech;
204752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
205f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0)
206752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryStatus = getBatteryStatus(buf);
207752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
208f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0)
209752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryHealth = getBatteryHealth(buf);
210752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
211f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0)
212752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryTechnology = String8(buf);
213752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
214752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    unsigned int i;
215752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
216752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    for (i = 0; i < mChargerNames.size(); i++) {
217752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        String8 path;
218752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
219752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                          mChargerNames[i].string());
220752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
221752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (readFromFile(path, buf, SIZE) > 0) {
222752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            if (buf[0] != '0') {
223752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.clear();
224752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
225752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                                  mChargerNames[i].string());
226752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                switch(readPowerSupplyType(path)) {
227752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_AC:
228752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerAcOnline = true;
229752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
230752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_USB:
231752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerUsbOnline = true;
232752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
233752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
234752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerWirelessOnline = true;
235752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
236752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                default:
237752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
238752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                                 mChargerNames[i].string());
239752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
240752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            }
241752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
242752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
243752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
24410b235e7436256da9adc827125645f141bd8fac9Todd Poynor    logthis = !healthd_board_battery_update(&props);
245b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
24610b235e7436256da9adc827125645f141bd8fac9Todd Poynor    if (logthis) {
24710b235e7436256da9adc827125645f141bd8fac9Todd Poynor        char dmesgline[256];
2486dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor
2496dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (props.batteryPresent)
2506dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            snprintf(dmesgline, sizeof(dmesgline),
25110b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
25210b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryLevel, props.batteryVoltage,
25310b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryTemperature < 0 ? "-" : "",
25410b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 abs(props.batteryTemperature / 10),
25510b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 abs(props.batteryTemperature % 10), props.batteryHealth,
25610b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryStatus);
2576dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        else
2586dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            snprintf(dmesgline, sizeof(dmesgline),
2596dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor                 "battery none");
260b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
261f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
26210b235e7436256da9adc827125645f141bd8fac9Todd Poynor            char b[20];
26310b235e7436256da9adc827125645f141bd8fac9Todd Poynor
2642e227fbc5ad735856ce016714440e377e85fb839Todd Poynor            snprintf(b, sizeof(b), " c=%d", extraProps.batteryCurrentNow / 1000);
26510b235e7436256da9adc827125645f141bd8fac9Todd Poynor            strlcat(dmesgline, b, sizeof(dmesgline));
26610b235e7436256da9adc827125645f141bd8fac9Todd Poynor        }
267b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
26810b235e7436256da9adc827125645f141bd8fac9Todd Poynor        KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
26910b235e7436256da9adc827125645f141bd8fac9Todd Poynor                  props.chargerAcOnline ? "a" : "",
27010b235e7436256da9adc827125645f141bd8fac9Todd Poynor                  props.chargerUsbOnline ? "u" : "",
27110b235e7436256da9adc827125645f141bd8fac9Todd Poynor                  props.chargerWirelessOnline ? "w" : "");
27210b235e7436256da9adc827125645f141bd8fac9Todd Poynor    }
273752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
274c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynor    healthd_mode_ops->battery_update(&props);
275752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return props.chargerAcOnline | props.chargerUsbOnline |
276752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            props.chargerWirelessOnline;
277752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
278752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
279c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynorstatus_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
280c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    status_t ret = BAD_VALUE;
281c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
282c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    switch(id) {
283c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    case BATTERY_PROP_CHARGE_COUNTER:
284c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
285c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            val->valueInt =
286c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor                getIntField(mHealthdConfig->batteryChargeCounterPath);
287c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NO_ERROR;
288c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        } else {
289c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NAME_NOT_FOUND;
290c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        }
291c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
292c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
293c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    case BATTERY_PROP_CURRENT_NOW:
294c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
295c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            val->valueInt =
296c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor                getIntField(mHealthdConfig->batteryCurrentNowPath);
297c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NO_ERROR;
298c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        } else {
299c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NAME_NOT_FOUND;
300c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        }
301c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
302c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
303bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor    case BATTERY_PROP_CURRENT_AVG:
304bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
305bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            val->valueInt =
306bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                getIntField(mHealthdConfig->batteryCurrentAvgPath);
307bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            ret = NO_ERROR;
308bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        } else {
309bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            ret = NAME_NOT_FOUND;
310bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        }
311bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        break;
312bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor
313c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    default:
314c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
315c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    }
316c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
317c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    if (ret != NO_ERROR)
318c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        val->valueInt = INT_MIN;
319c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
320c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    return ret;
321c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor}
322c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
323020369d8724eff2b87350e54e157a609846166e4Todd Poynorvoid BatteryMonitor::dumpState(int fd) {
324020369d8724eff2b87350e54e157a609846166e4Todd Poynor    int v;
325020369d8724eff2b87350e54e157a609846166e4Todd Poynor    char vs[128];
326020369d8724eff2b87350e54e157a609846166e4Todd Poynor
327020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d\n",
328020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.chargerAcOnline, props.chargerUsbOnline,
329020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.chargerWirelessOnline);
330020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
331020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
332020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryStatus, props.batteryHealth, props.batteryPresent);
333020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
334020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n",
335020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryLevel, props.batteryVoltage,
336020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryTemperature);
337020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
338020369d8724eff2b87350e54e157a609846166e4Todd Poynor
339020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
340020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryCurrentNowPath);
341020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "current now: %d\n", v);
342020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
343020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
344020369d8724eff2b87350e54e157a609846166e4Todd Poynor
345020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
346020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
347020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "current avg: %d\n", v);
348020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
349020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
350020369d8724eff2b87350e54e157a609846166e4Todd Poynor
351020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
352020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryChargeCounterPath);
353020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
354020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
355020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
356020369d8724eff2b87350e54e157a609846166e4Todd Poynor}
357020369d8724eff2b87350e54e157a609846166e4Todd Poynor
358c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynorvoid BatteryMonitor::init(struct healthd_config *hc) {
359752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    String8 path;
360752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
361f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    mHealthdConfig = hc;
362752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
363752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (dir == NULL) {
364752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
365752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    } else {
366752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        struct dirent* entry;
367752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
368752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        while ((entry = readdir(dir))) {
369752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            const char* name = entry->d_name;
370752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
371752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            if (!strcmp(name, ".") || !strcmp(name, ".."))
372752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                continue;
373752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
374752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            char buf[20];
375752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            // Look for "type" file in each subdirectory
376752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            path.clear();
377752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
378752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            switch(readPowerSupplyType(path)) {
379752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_AC:
380752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_USB:
381752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
382752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.clear();
383752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
384752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                if (access(path.string(), R_OK) == 0)
385752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    mChargerNames.add(String8(name));
386752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
387752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
388752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
3896dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor                mBatteryDevicePresent = true;
3906dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor
391f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryStatusPath.isEmpty()) {
392f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
393f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
394f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
395f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
396f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryStatusPath = path;
397f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
398752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
399f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryHealthPath.isEmpty()) {
400752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    path.clear();
401f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
402f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
403752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    if (access(path, R_OK) == 0)
404f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryHealthPath = path;
405752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
406752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
407f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryPresentPath.isEmpty()) {
408f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
409f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
410f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
411f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
412f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryPresentPath = path;
413f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
414b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
415f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
416f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
417f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
418f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
419f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
420f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryCapacityPath = path;
421f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
422b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
423f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
424f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
425f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/voltage_now",
426f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
427f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0) {
428f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryVoltagePath = path;
429f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    } else {
430f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.clear();
431f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.appendFormat("%s/%s/batt_vol",
432f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                          POWER_SUPPLY_SYSFS_PATH, name);
433f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        if (access(path, R_OK) == 0)
434f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                            mHealthdConfig->batteryVoltagePath = path;
435f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    }
436f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
437f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
438f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
439752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    path.clear();
440f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/current_now",
441f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
442752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    if (access(path, R_OK) == 0)
443f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryCurrentNowPath = path;
444f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
445f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
446bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
447bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    path.clear();
448bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    path.appendFormat("%s/%s/current_avg",
449bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
450bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    if (access(path, R_OK) == 0)
451bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                        mHealthdConfig->batteryCurrentAvgPath = path;
452bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                }
453bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor
454f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
455f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
456f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/charge_counter",
457f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
458f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
459f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryChargeCounterPath = path;
460f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
461f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
462f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
463f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
464f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
465f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
466f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0) {
467f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryTemperaturePath = path;
468f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    } else {
469f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.clear();
470f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.appendFormat("%s/%s/batt_temp",
471f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                          POWER_SUPPLY_SYSFS_PATH, name);
472f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        if (access(path, R_OK) == 0)
473f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                            mHealthdConfig->batteryTemperaturePath = path;
474f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    }
475f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
476f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
477f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
478f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
479f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/technology",
480f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
481f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
482f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryTechnologyPath = path;
483752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
484752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
485752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
486752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
487752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
488752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
489752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            }
490752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
491752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        closedir(dir);
492752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
493752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
494752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (!mChargerNames.size())
495752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
4966dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    if (!mBatteryDevicePresent) {
4976dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        KLOG_INFO(LOG_TAG, "No battery devices found\n");
4986dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        hc->periodic_chores_interval_fast = -1;
4996dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        hc->periodic_chores_interval_slow = -1;
5006dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    } else {
5016dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryStatusPath.isEmpty())
5026dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
5036dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryHealthPath.isEmpty())
5046dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
5056dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryPresentPath.isEmpty())
5066dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
5076dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryCapacityPath.isEmpty())
5086dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
5096dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryVoltagePath.isEmpty())
5106dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
5116dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryTemperaturePath.isEmpty())
5126dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
5136dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryTechnologyPath.isEmpty())
5146dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
5156dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    }
516752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
517752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
518752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; // namespace android
519