BatteryMonitor.cpp revision 5c09ec17261fc2217009f72ec45c1f00df51ccde
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
19f6dbc6d4b830c57c0155a607d0d8a2cb6b1e0040Yabin Cui#include <healthd/healthd.h>
20f6dbc6d4b830c57c0155a607d0d8a2cb6b1e0040Yabin Cui#include <healthd/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>
27acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn#include <sys/types.h>
28752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <unistd.h>
29acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn
30752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <batteryservice/BatteryService.h>
31752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <cutils/klog.h>
323db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor#include <cutils/properties.h>
33c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor#include <utils/Errors.h>
34752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/String8.h>
35752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/Vector.h>
36752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
37752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SUBSYSTEM "power_supply"
38752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
39a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi#define FAKE_BATTERY_CAPACITY 42
40a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi#define FAKE_BATTERY_TEMPERATURE 424
41f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi#define ALWAYS_PLUGGED_CAPACITY 100
425c09ec17261fc2217009f72ec45c1f00df51ccdeRuchi Kandoi#define MILLION 1.0e6
4340e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan#define DEFAULT_VBUS_VOLTAGE 5000000
44752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
45752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynornamespace android {
46752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
47752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstruct sysfsStringEnumMap {
486f5b47f9144960412b0fb6bc417f0c41bf53438aMark Salyzyn    const char* s;
49752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int val;
50752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor};
51752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
52752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstatic int mapSysfsString(const char* str,
53752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                          struct sysfsStringEnumMap map[]) {
54752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    for (int i = 0; map[i].s; i++)
55752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (!strcmp(str, map[i].s))
56752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            return map[i].val;
57752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
58752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return -1;
59752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
60752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
61ac3387b71baf99b2680af038c5997eb52218f661Yabin Cuistatic void initBatteryProperties(BatteryProperties* props) {
62ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->chargerAcOnline = false;
63ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->chargerUsbOnline = false;
64ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->chargerWirelessOnline = false;
65ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->maxChargingCurrent = 0;
6640e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan    props->maxChargingVoltage = 0;
67ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryStatus = BATTERY_STATUS_UNKNOWN;
68ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryHealth = BATTERY_HEALTH_UNKNOWN;
69ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryPresent = false;
70ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryLevel = 0;
71ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryVoltage = 0;
72ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryTemperature = 0;
73ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryCurrent = 0;
74ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryCycleCount = 0;
75ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryFullCharge = 0;
76ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    props->batteryTechnology.clear();
77ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui}
78ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui
79ac3387b71baf99b2680af038c5997eb52218f661Yabin CuiBatteryMonitor::BatteryMonitor() : mHealthdConfig(nullptr), mBatteryDevicePresent(false),
80ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    mAlwaysPluggedDevice(false), mBatteryFixedCapacity(0), mBatteryFixedTemperature(0) {
81ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    initBatteryProperties(&props);
82ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui}
83ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui
84752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryStatus(const char* status) {
85752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int ret;
86752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap batteryStatusMap[] = {
87752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unknown", BATTERY_STATUS_UNKNOWN },
88752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Charging", BATTERY_STATUS_CHARGING },
89752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Discharging", BATTERY_STATUS_DISCHARGING },
90752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Not charging", BATTERY_STATUS_NOT_CHARGING },
91752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Full", BATTERY_STATUS_FULL },
92752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { NULL, 0 },
93752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
94752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
95752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = mapSysfsString(status, batteryStatusMap);
96752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0) {
97752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
98752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = BATTERY_STATUS_UNKNOWN;
99752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
100752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
101752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
102752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
103752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
104752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryHealth(const char* status) {
105752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int ret;
106752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap batteryHealthMap[] = {
107752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unknown", BATTERY_HEALTH_UNKNOWN },
108752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Good", BATTERY_HEALTH_GOOD },
109752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Overheat", BATTERY_HEALTH_OVERHEAT },
110752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Dead", BATTERY_HEALTH_DEAD },
111752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE },
112752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE },
113752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Cold", BATTERY_HEALTH_COLD },
114752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { NULL, 0 },
115752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
116752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
117752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = mapSysfsString(status, batteryHealthMap);
118752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0) {
119752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
120752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = BATTERY_HEALTH_UNKNOWN;
121752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
122752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
123752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
124752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
125752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
126752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::readFromFile(const String8& path, char* buf, size_t size) {
127752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char *cp = NULL;
128752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
129752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (path.isEmpty())
130752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return -1;
131752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int fd = open(path.string(), O_RDONLY, 0);
132752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (fd == -1) {
133752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "Could not open '%s'\n", path.string());
134752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return -1;
135752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
136752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
137752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ssize_t count = TEMP_FAILURE_RETRY(read(fd, buf, size));
138752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (count > 0)
139752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            cp = (char *)memrchr(buf, '\n', count);
140752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
141752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (cp)
142752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        *cp = '\0';
143752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    else
144752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        buf[0] = '\0';
145752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
146752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    close(fd);
147752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return count;
148752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
149752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
150752faf2c18407fd79127fb3f3773910b4ddf669dTodd PoynorBatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) {
151752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
152752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
153752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int length = readFromFile(path, buf, SIZE);
154752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    BatteryMonitor::PowerSupplyType ret;
155752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap supplyTypeMap[] = {
156752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN },
157752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY },
158752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "UPS", ANDROID_POWER_SUPPLY_TYPE_AC },
159752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Mains", ANDROID_POWER_SUPPLY_TYPE_AC },
160752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB", ANDROID_POWER_SUPPLY_TYPE_USB },
161752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC },
1623282861b68978abbbacb9b7dce260f70f9695187Johan Redestig            { "USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC },
163752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC },
164752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC },
1658a4eef60e135260f1f35675f4ad5107ae1457ed0Benson Leung            { "USB_C", ANDROID_POWER_SUPPLY_TYPE_AC },
1668a4eef60e135260f1f35675f4ad5107ae1457ed0Benson Leung            { "USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC },
1678a4eef60e135260f1f35675f4ad5107ae1457ed0Benson Leung            { "USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB },
168752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS },
169752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { NULL, 0 },
170752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
171752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
172752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (length <= 0)
173752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
174752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
175752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap);
1763282861b68978abbbacb9b7dce260f70f9695187Johan Redestig    if (ret < 0) {
1773282861b68978abbbacb9b7dce260f70f9695187Johan Redestig        KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf);
178752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
1793282861b68978abbbacb9b7dce260f70f9695187Johan Redestig    }
180752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
181752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
182752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
183752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
184752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::getBooleanField(const String8& path) {
185752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 16;
186752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
187752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
188752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    bool value = false;
189752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (readFromFile(path, buf, SIZE) > 0) {
190752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (buf[0] != '0') {
191752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            value = true;
192752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
193752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
194752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
195752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return value;
196752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
197752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
198752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getIntField(const String8& path) {
199752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
200752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
201752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
202752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int value = 0;
203752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (readFromFile(path, buf, SIZE) > 0) {
204752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        value = strtol(buf, NULL, 0);
205752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
206752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return value;
207752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
208752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
209752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::update(void) {
21010b235e7436256da9adc827125645f141bd8fac9Todd Poynor    bool logthis;
211752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
212ac3387b71baf99b2680af038c5997eb52218f661Yabin Cui    initBatteryProperties(&props);
213752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
214f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (!mHealthdConfig->batteryPresentPath.isEmpty())
215f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor        props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
216752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    else
2176dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        props.batteryPresent = mBatteryDevicePresent;
218752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
2193db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor    props.batteryLevel = mBatteryFixedCapacity ?
2203db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        mBatteryFixedCapacity :
2213db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        getIntField(mHealthdConfig->batteryCapacityPath);
222f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
223b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
224cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
225cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath) / 1000;
226cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
227cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryFullChargePath.isEmpty())
228cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);
229cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
230cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
231cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
232cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
2333db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor    props.batteryTemperature = mBatteryFixedTemperature ?
2343db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        mBatteryFixedTemperature :
2353db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        getIntField(mHealthdConfig->batteryTemperaturePath);
236752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
237f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    // For devices which do not have battery and are always plugged
238f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    // into power souce.
239f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    if (mAlwaysPluggedDevice) {
240f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.chargerAcOnline = true;
241f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.batteryPresent = true;
242f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.batteryStatus = BATTERY_STATUS_CHARGING;
243f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.batteryHealth = BATTERY_HEALTH_GOOD;
244f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    }
245f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi
246752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
247752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
248752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    String8 btech;
249752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
250f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0)
251752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryStatus = getBatteryStatus(buf);
252752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
253f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0)
254752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryHealth = getBatteryHealth(buf);
255752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
256f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0)
257752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryTechnology = String8(buf);
258752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
259752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    unsigned int i;
26040e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan    double MaxPower = 0;
261752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
262752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    for (i = 0; i < mChargerNames.size(); i++) {
263752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        String8 path;
264752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
265752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                          mChargerNames[i].string());
266752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
267752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (readFromFile(path, buf, SIZE) > 0) {
268752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            if (buf[0] != '0') {
269752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.clear();
270752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
271752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                                  mChargerNames[i].string());
272752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                switch(readPowerSupplyType(path)) {
273752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_AC:
274752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerAcOnline = true;
275752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
276752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_USB:
277752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerUsbOnline = true;
278752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
279752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
280752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerWirelessOnline = true;
281752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
282752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                default:
283752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
284752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                                 mChargerNames[i].string());
285752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
286d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                path.clear();
287d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
288d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                                  mChargerNames[i].string());
28940e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                int ChargingCurrent =
29040e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                    (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;
29140e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan
29240e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                path.clear();
29340e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
29440e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                                  mChargerNames[i].string());
29540e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan
29640e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                int ChargingVoltage =
29740e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                    (access(path.string(), R_OK) == 0) ? getIntField(path) :
29840e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                    DEFAULT_VBUS_VOLTAGE;
29940e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan
30040e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                double power = ((double)ChargingCurrent / MILLION) *
30140e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                        ((double)ChargingVoltage / MILLION);
30240e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                if (MaxPower < power) {
30340e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                    props.maxChargingCurrent = ChargingCurrent;
30440e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                    props.maxChargingVoltage = ChargingVoltage;
30540e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan                    MaxPower = power;
306d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                }
307752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            }
308752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
309752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
310752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
31110b235e7436256da9adc827125645f141bd8fac9Todd Poynor    logthis = !healthd_board_battery_update(&props);
312b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
31310b235e7436256da9adc827125645f141bd8fac9Todd Poynor    if (logthis) {
31410b235e7436256da9adc827125645f141bd8fac9Todd Poynor        char dmesgline[256];
315cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        size_t len;
316c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor        if (props.batteryPresent) {
3176dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            snprintf(dmesgline, sizeof(dmesgline),
31810b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
31910b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryLevel, props.batteryVoltage,
32010b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryTemperature < 0 ? "-" : "",
32110b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 abs(props.batteryTemperature / 10),
32210b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 abs(props.batteryTemperature % 10), props.batteryHealth,
32310b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryStatus);
324b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
325cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            len = strlen(dmesgline);
326c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor            if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
327cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
328cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                " c=%d", props.batteryCurrent);
329cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            }
330cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
331cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
332cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
333cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                " fc=%d", props.batteryFullCharge);
334cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            }
33510b235e7436256da9adc827125645f141bd8fac9Todd Poynor
336cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
337cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
338cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                " cc=%d", props.batteryCycleCount);
339c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor            }
340c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor        } else {
341c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor            snprintf(dmesgline, sizeof(dmesgline),
342c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor                 "battery none");
34310b235e7436256da9adc827125645f141bd8fac9Todd Poynor        }
344b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
345cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        len = strlen(dmesgline);
346acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
347acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                 props.chargerAcOnline ? "a" : "",
348acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                 props.chargerUsbOnline ? "u" : "",
349acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                 props.chargerWirelessOnline ? "w" : "");
350acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn
351acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
35210b235e7436256da9adc827125645f141bd8fac9Todd Poynor    }
353752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
354c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynor    healthd_mode_ops->battery_update(&props);
355752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return props.chargerAcOnline | props.chargerUsbOnline |
356752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            props.chargerWirelessOnline;
357752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
358752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
359b0580d710fe6a237eff9b35df05242e5a872319fYabin Cuiint BatteryMonitor::getChargeStatus() {
360b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui    int result = BATTERY_STATUS_UNKNOWN;
361b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui    if (!mHealthdConfig->batteryStatusPath.isEmpty()) {
362b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui        char buf[128];
363b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui        if (readFromFile(mHealthdConfig->batteryStatusPath, buf, sizeof(buf)) > 0) {
364b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui            result = getBatteryStatus(buf);
365b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui        }
366b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui    }
367b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui    return result;
368b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui}
369b0580d710fe6a237eff9b35df05242e5a872319fYabin Cui
370c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynorstatus_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
371c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    status_t ret = BAD_VALUE;
372c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
3738f132af495d208272ea55d0ca24068926fa80e51Todd Poynor    val->valueInt64 = LONG_MIN;
3748f132af495d208272ea55d0ca24068926fa80e51Todd Poynor
375c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    switch(id) {
376c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    case BATTERY_PROP_CHARGE_COUNTER:
377c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
3788f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
379c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor                getIntField(mHealthdConfig->batteryChargeCounterPath);
380c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NO_ERROR;
381c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        } else {
382c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NAME_NOT_FOUND;
383c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        }
384c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
385c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
386c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    case BATTERY_PROP_CURRENT_NOW:
387c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
3888f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
389c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor                getIntField(mHealthdConfig->batteryCurrentNowPath);
390c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NO_ERROR;
391c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        } else {
392c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NAME_NOT_FOUND;
393c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        }
394c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
395c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
396bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor    case BATTERY_PROP_CURRENT_AVG:
397bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
3988f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
399bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                getIntField(mHealthdConfig->batteryCurrentAvgPath);
400bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            ret = NO_ERROR;
401bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        } else {
402bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            ret = NAME_NOT_FOUND;
403bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        }
404bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        break;
405bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor
406347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence    case BATTERY_PROP_CAPACITY:
407347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
4088f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
409347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence                getIntField(mHealthdConfig->batteryCapacityPath);
410347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence            ret = NO_ERROR;
411347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        } else {
412347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence            ret = NAME_NOT_FOUND;
413347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        }
414347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        break;
415347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence
4168f132af495d208272ea55d0ca24068926fa80e51Todd Poynor    case BATTERY_PROP_ENERGY_COUNTER:
417e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor        if (mHealthdConfig->energyCounter) {
418e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor            ret = mHealthdConfig->energyCounter(&val->valueInt64);
419e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor        } else {
420e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor            ret = NAME_NOT_FOUND;
421e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor        }
4228f132af495d208272ea55d0ca24068926fa80e51Todd Poynor        break;
4238f132af495d208272ea55d0ca24068926fa80e51Todd Poynor
424c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    default:
425c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
426c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    }
427c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
428c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    return ret;
429c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor}
430c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
431020369d8724eff2b87350e54e157a609846166e4Todd Poynorvoid BatteryMonitor::dumpState(int fd) {
432020369d8724eff2b87350e54e157a609846166e4Todd Poynor    int v;
433020369d8724eff2b87350e54e157a609846166e4Todd Poynor    char vs[128];
434020369d8724eff2b87350e54e157a609846166e4Todd Poynor
43540e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan    snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d voltage_max: %d\n",
436020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.chargerAcOnline, props.chargerUsbOnline,
43740e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan             props.chargerWirelessOnline, props.maxChargingCurrent,
43840e1df4488f30ab49d82a279b5fca77e31746ec0Badhri Jagan Sridharan             props.maxChargingVoltage);
439020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
440020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
441020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryStatus, props.batteryHealth, props.batteryPresent);
442020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
443020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n",
444020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryLevel, props.batteryVoltage,
445020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryTemperature);
446020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
447020369d8724eff2b87350e54e157a609846166e4Todd Poynor
448020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
449020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryCurrentNowPath);
450020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "current now: %d\n", v);
451020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
452020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
453020369d8724eff2b87350e54e157a609846166e4Todd Poynor
454020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
455020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
456020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "current avg: %d\n", v);
457020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
458020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
459020369d8724eff2b87350e54e157a609846166e4Todd Poynor
460020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
461020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryChargeCounterPath);
462020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
463020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
464020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
465cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
466cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
467cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrent);
468cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        write(fd, vs, strlen(vs));
469cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    }
470cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
471cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
472cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
473cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        write(fd, vs, strlen(vs));
474cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    }
475cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
476cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
477cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge);
478cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        write(fd, vs, strlen(vs));
479cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    }
480020369d8724eff2b87350e54e157a609846166e4Todd Poynor}
481020369d8724eff2b87350e54e157a609846166e4Todd Poynor
482c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynorvoid BatteryMonitor::init(struct healthd_config *hc) {
483752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    String8 path;
4843db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor    char pval[PROPERTY_VALUE_MAX];
485752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
486f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    mHealthdConfig = hc;
487752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
488752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (dir == NULL) {
489752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
490752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    } else {
491752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        struct dirent* entry;
492752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
493752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        while ((entry = readdir(dir))) {
494752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            const char* name = entry->d_name;
495752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
496752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            if (!strcmp(name, ".") || !strcmp(name, ".."))
497752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                continue;
498752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
499752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            // Look for "type" file in each subdirectory
500752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            path.clear();
501752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
502752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            switch(readPowerSupplyType(path)) {
503752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_AC:
504752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_USB:
505752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
506752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.clear();
507752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
508752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                if (access(path.string(), R_OK) == 0)
509752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    mChargerNames.add(String8(name));
510752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
511752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
512752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
5136dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor                mBatteryDevicePresent = true;
5146dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor
515f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryStatusPath.isEmpty()) {
516f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
517f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
518f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
519f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
520f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryStatusPath = path;
521f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
522752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
523f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryHealthPath.isEmpty()) {
524752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    path.clear();
525f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
526f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
527752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    if (access(path, R_OK) == 0)
528f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryHealthPath = path;
529752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
530752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
531f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryPresentPath.isEmpty()) {
532f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
533f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
534f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
535f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
536f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryPresentPath = path;
537f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
538b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
539f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
540f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
541f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
542f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
543f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
544f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryCapacityPath = path;
545f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
546b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
547f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
548f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
549f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/voltage_now",
550f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
551f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0) {
552f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryVoltagePath = path;
553f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    } else {
554f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.clear();
555f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.appendFormat("%s/%s/batt_vol",
556f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                          POWER_SUPPLY_SYSFS_PATH, name);
557f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        if (access(path, R_OK) == 0)
558f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                            mHealthdConfig->batteryVoltagePath = path;
559f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    }
560f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
561f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
562cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
563cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.clear();
564cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.appendFormat("%s/%s/charge_full",
565cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                      POWER_SUPPLY_SYSFS_PATH, name);
566cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    if (access(path, R_OK) == 0)
567cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                        mHealthdConfig->batteryFullChargePath = path;
568cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                }
569cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
570f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
571752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    path.clear();
572f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/current_now",
573f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
574752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    if (access(path, R_OK) == 0)
575f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryCurrentNowPath = path;
576f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
577f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
578cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
579cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.clear();
580cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.appendFormat("%s/%s/cycle_count",
581cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                      POWER_SUPPLY_SYSFS_PATH, name);
582cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    if (access(path, R_OK) == 0)
583cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                        mHealthdConfig->batteryCycleCountPath = path;
584cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                }
585cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
586bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
587bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    path.clear();
588bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    path.appendFormat("%s/%s/current_avg",
589bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
590bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    if (access(path, R_OK) == 0)
591bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                        mHealthdConfig->batteryCurrentAvgPath = path;
592bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                }
593bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor
594f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
595f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
596f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/charge_counter",
597f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
598f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
599f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryChargeCounterPath = path;
600f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
601f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
602f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
603f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
604f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
605f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
606f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0) {
607f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryTemperaturePath = path;
608f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    } else {
609f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.clear();
610f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.appendFormat("%s/%s/batt_temp",
611f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                          POWER_SUPPLY_SYSFS_PATH, name);
612f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        if (access(path, R_OK) == 0)
613f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                            mHealthdConfig->batteryTemperaturePath = path;
614f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    }
615f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
616f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
617f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
618f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
619f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/technology",
620f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
621f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
622f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryTechnologyPath = path;
623752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
624752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
625752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
626752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
627752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
628752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
629752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            }
630752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
631752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        closedir(dir);
632752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
633752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
634585ab65c5816f8f9ff212487ffec797e8921697eIan Pedowitz    // This indicates that there is no charger driver registered.
635585ab65c5816f8f9ff212487ffec797e8921697eIan Pedowitz    // Typically the case for devices which do not have a battery and
636585ab65c5816f8f9ff212487ffec797e8921697eIan Pedowitz    // and are always plugged into AC mains.
637f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    if (!mChargerNames.size()) {
638752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
639f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY;
640f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
641f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        mAlwaysPluggedDevice = true;
642f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    }
6436dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    if (!mBatteryDevicePresent) {
644ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor        KLOG_WARNING(LOG_TAG, "No battery devices found\n");
6456dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        hc->periodic_chores_interval_fast = -1;
6466dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        hc->periodic_chores_interval_slow = -1;
6476dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    } else {
6486dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryStatusPath.isEmpty())
6496dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
6506dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryHealthPath.isEmpty())
6516dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
6526dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryPresentPath.isEmpty())
6536dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
6546dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryCapacityPath.isEmpty())
6556dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
6566dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryVoltagePath.isEmpty())
6576dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
6586dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryTemperaturePath.isEmpty())
6596dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
6606dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryTechnologyPath.isEmpty())
6616dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
662f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        if (mHealthdConfig->batteryCurrentNowPath.isEmpty())
663cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
664cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        if (mHealthdConfig->batteryFullChargePath.isEmpty())
665cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
666cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        if (mHealthdConfig->batteryCycleCountPath.isEmpty())
667cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
6686dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    }
6693db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor
670a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi    if (property_get("ro.boot.fake_battery", pval, NULL) > 0
671a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi                                               && strtol(pval, NULL, 10) != 0) {
672a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi        mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
673a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
674a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi    }
675752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
676752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
677752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; // namespace android
678