BatteryMonitor.cpp revision f18ec9f227b8298467cc5288bc4a85c76526d67e
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>
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>
33acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn#include <log/log_read.h>
34c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor#include <utils/Errors.h>
35752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/String8.h>
36752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/Vector.h>
37752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
38752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SUBSYSTEM "power_supply"
39752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
40a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi#define FAKE_BATTERY_CAPACITY 42
41a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi#define FAKE_BATTERY_TEMPERATURE 424
42f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi#define ALWAYS_PLUGGED_CAPACITY 100
43752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
44752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynornamespace android {
45752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
46752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstruct sysfsStringEnumMap {
476f5b47f9144960412b0fb6bc417f0c41bf53438aMark Salyzyn    const char* s;
48752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int val;
49752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor};
50752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
51752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstatic int mapSysfsString(const char* str,
52752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                          struct sysfsStringEnumMap map[]) {
53752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    for (int i = 0; map[i].s; i++)
54752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (!strcmp(str, map[i].s))
55752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            return map[i].val;
56752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
57752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return -1;
58752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
59752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
60752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryStatus(const char* status) {
61752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int ret;
62752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap batteryStatusMap[] = {
63752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unknown", BATTERY_STATUS_UNKNOWN },
64752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Charging", BATTERY_STATUS_CHARGING },
65752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Discharging", BATTERY_STATUS_DISCHARGING },
66752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Not charging", BATTERY_STATUS_NOT_CHARGING },
67752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Full", BATTERY_STATUS_FULL },
68752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { NULL, 0 },
69752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
70752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
71752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = mapSysfsString(status, batteryStatusMap);
72752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0) {
73752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
74752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = BATTERY_STATUS_UNKNOWN;
75752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
76752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
77752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
78752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
79752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
80752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryHealth(const char* status) {
81752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int ret;
82752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap batteryHealthMap[] = {
83752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unknown", BATTERY_HEALTH_UNKNOWN },
84752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Good", BATTERY_HEALTH_GOOD },
85752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Overheat", BATTERY_HEALTH_OVERHEAT },
86752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Dead", BATTERY_HEALTH_DEAD },
87752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE },
88752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE },
89752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { "Cold", BATTERY_HEALTH_COLD },
90752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        { NULL, 0 },
91752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
92752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
93752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = mapSysfsString(status, batteryHealthMap);
94752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0) {
95752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
96752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = BATTERY_HEALTH_UNKNOWN;
97752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
98752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
99752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
100752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
101752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
102752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::readFromFile(const String8& path, char* buf, size_t size) {
103752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char *cp = NULL;
104752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
105752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (path.isEmpty())
106752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return -1;
107752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int fd = open(path.string(), O_RDONLY, 0);
108752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (fd == -1) {
109752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "Could not open '%s'\n", path.string());
110752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return -1;
111752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
112752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
113752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ssize_t count = TEMP_FAILURE_RETRY(read(fd, buf, size));
114752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (count > 0)
115752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            cp = (char *)memrchr(buf, '\n', count);
116752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
117752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (cp)
118752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        *cp = '\0';
119752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    else
120752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        buf[0] = '\0';
121752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
122752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    close(fd);
123752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return count;
124752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
125752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
126752faf2c18407fd79127fb3f3773910b4ddf669dTodd PoynorBatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) {
127752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
128752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
129752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int length = readFromFile(path, buf, SIZE);
130752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    BatteryMonitor::PowerSupplyType ret;
131752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    struct sysfsStringEnumMap supplyTypeMap[] = {
132752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN },
133752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY },
134752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "UPS", ANDROID_POWER_SUPPLY_TYPE_AC },
135752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Mains", ANDROID_POWER_SUPPLY_TYPE_AC },
136752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB", ANDROID_POWER_SUPPLY_TYPE_USB },
137752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC },
138752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC },
139752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC },
140752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS },
141752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            { NULL, 0 },
142752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    };
143752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
144752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (length <= 0)
145752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
146752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
147752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap);
148752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (ret < 0)
149752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
150752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
151752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return ret;
152752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
153752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
154752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::getBooleanField(const String8& path) {
155752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 16;
156752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
157752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
158752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    bool value = false;
159752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (readFromFile(path, buf, SIZE) > 0) {
160752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (buf[0] != '0') {
161752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            value = true;
162752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
163752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
164752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
165752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return value;
166752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
167752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
168752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getIntField(const String8& path) {
169752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
170752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
171752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
172752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    int value = 0;
173752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (readFromFile(path, buf, SIZE) > 0) {
174752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        value = strtol(buf, NULL, 0);
175752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
176752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return value;
177752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
178752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
179752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::update(void) {
18010b235e7436256da9adc827125645f141bd8fac9Todd Poynor    bool logthis;
181752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
182752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.chargerAcOnline = false;
183752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.chargerUsbOnline = false;
184752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.chargerWirelessOnline = false;
185752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.batteryStatus = BATTERY_STATUS_UNKNOWN;
186752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    props.batteryHealth = BATTERY_HEALTH_UNKNOWN;
187d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos    props.maxChargingCurrent = 0;
188752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
189f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (!mHealthdConfig->batteryPresentPath.isEmpty())
190f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor        props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
191752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    else
1926dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        props.batteryPresent = mBatteryDevicePresent;
193752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
1943db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor    props.batteryLevel = mBatteryFixedCapacity ?
1953db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        mBatteryFixedCapacity :
1963db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        getIntField(mHealthdConfig->batteryCapacityPath);
197f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
198b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
199cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
200cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath) / 1000;
201cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
202cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryFullChargePath.isEmpty())
203cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);
204cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
205cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
206cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
207cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
2083db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor    props.batteryTemperature = mBatteryFixedTemperature ?
2093db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        mBatteryFixedTemperature :
2103db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor        getIntField(mHealthdConfig->batteryTemperaturePath);
211752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
212f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    // For devices which do not have battery and are always plugged
213f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    // into power souce.
214f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    if (mAlwaysPluggedDevice) {
215f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.chargerAcOnline = true;
216f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.batteryPresent = true;
217f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.batteryStatus = BATTERY_STATUS_CHARGING;
218f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        props.batteryHealth = BATTERY_HEALTH_GOOD;
219f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    }
220f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi
221752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    const int SIZE = 128;
222752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    char buf[SIZE];
223752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    String8 btech;
224752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
225f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0)
226752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryStatus = getBatteryStatus(buf);
227752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
228f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0)
229752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryHealth = getBatteryHealth(buf);
230752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
231f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0)
232752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        props.batteryTechnology = String8(buf);
233752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
234752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    unsigned int i;
235752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
236752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    for (i = 0; i < mChargerNames.size(); i++) {
237752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        String8 path;
238752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
239752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                          mChargerNames[i].string());
240752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
241752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        if (readFromFile(path, buf, SIZE) > 0) {
242752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            if (buf[0] != '0') {
243752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.clear();
244752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
245752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                                  mChargerNames[i].string());
246752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                switch(readPowerSupplyType(path)) {
247752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_AC:
248752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerAcOnline = true;
249752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
250752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_USB:
251752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerUsbOnline = true;
252752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
253752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
254752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    props.chargerWirelessOnline = true;
255752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    break;
256752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                default:
257752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
258752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                                 mChargerNames[i].string());
259752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
260d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                path.clear();
261d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
262d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                                  mChargerNames[i].string());
263d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                if (access(path.string(), R_OK) == 0) {
264d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                    int maxChargingCurrent = getIntField(path);
265d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                    if (props.maxChargingCurrent < maxChargingCurrent) {
266d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                        props.maxChargingCurrent = maxChargingCurrent;
267d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                    }
268d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos                }
269752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            }
270752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
271752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
272752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
27310b235e7436256da9adc827125645f141bd8fac9Todd Poynor    logthis = !healthd_board_battery_update(&props);
274b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
27510b235e7436256da9adc827125645f141bd8fac9Todd Poynor    if (logthis) {
27610b235e7436256da9adc827125645f141bd8fac9Todd Poynor        char dmesgline[256];
277cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        size_t len;
278c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor        if (props.batteryPresent) {
2796dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            snprintf(dmesgline, sizeof(dmesgline),
28010b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
28110b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryLevel, props.batteryVoltage,
28210b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryTemperature < 0 ? "-" : "",
28310b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 abs(props.batteryTemperature / 10),
28410b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 abs(props.batteryTemperature % 10), props.batteryHealth,
28510b235e7436256da9adc827125645f141bd8fac9Todd Poynor                 props.batteryStatus);
286b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
287cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            len = strlen(dmesgline);
288c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor            if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
289cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
290cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                " c=%d", props.batteryCurrent);
291cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            }
292cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
293cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
294cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
295cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                " fc=%d", props.batteryFullCharge);
296cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            }
29710b235e7436256da9adc827125645f141bd8fac9Todd Poynor
298cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
299cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
300cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                " cc=%d", props.batteryCycleCount);
301c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor            }
302c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor        } else {
303c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor            snprintf(dmesgline, sizeof(dmesgline),
304c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor                 "battery none");
30510b235e7436256da9adc827125645f141bd8fac9Todd Poynor        }
306b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
307cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        len = strlen(dmesgline);
308acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
309acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                 props.chargerAcOnline ? "a" : "",
310acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                 props.chargerUsbOnline ? "u" : "",
311acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                 props.chargerWirelessOnline ? "w" : "");
312acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn
313acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        log_time realtime(CLOCK_REALTIME);
314acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        time_t t = realtime.tv_sec;
315acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        struct tm *tmp = gmtime(&t);
316acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        if (tmp) {
317acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn            static const char fmt[] = " %Y-%m-%d %H:%M:%S.XXXXXXXXX UTC";
318acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn            len = strlen(dmesgline);
319acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn            if ((len < (sizeof(dmesgline) - sizeof(fmt) - 8)) // margin
320acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                    && strftime(dmesgline + len, sizeof(dmesgline) - len,
321acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                                fmt, tmp)) {
322acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                char *usec = strchr(dmesgline + len, 'X');
323acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                if (usec) {
324acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                    len = usec - dmesgline;
325acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                    snprintf(dmesgline + len, sizeof(dmesgline) - len,
326acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                             "%09u", realtime.tv_nsec);
327acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                    usec[9] = ' ';
328acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn                }
329acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn            }
330acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        }
331acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn
332acb1ddf56c98a75a49b263f99ef07ce361dc4323Mark Salyzyn        KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
33310b235e7436256da9adc827125645f141bd8fac9Todd Poynor    }
334752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
335c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynor    healthd_mode_ops->battery_update(&props);
336752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    return props.chargerAcOnline | props.chargerUsbOnline |
337752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            props.chargerWirelessOnline;
338752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
339752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
340c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynorstatus_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
341c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    status_t ret = BAD_VALUE;
342c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
3438f132af495d208272ea55d0ca24068926fa80e51Todd Poynor    val->valueInt64 = LONG_MIN;
3448f132af495d208272ea55d0ca24068926fa80e51Todd Poynor
345c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    switch(id) {
346c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    case BATTERY_PROP_CHARGE_COUNTER:
347c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
3488f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
349c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor                getIntField(mHealthdConfig->batteryChargeCounterPath);
350c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NO_ERROR;
351c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        } else {
352c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NAME_NOT_FOUND;
353c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        }
354c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
355c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
356c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    case BATTERY_PROP_CURRENT_NOW:
357c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
3588f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
359c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor                getIntField(mHealthdConfig->batteryCurrentNowPath);
360c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NO_ERROR;
361c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        } else {
362c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor            ret = NAME_NOT_FOUND;
363c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        }
364c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
365c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
366bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor    case BATTERY_PROP_CURRENT_AVG:
367bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
3688f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
369bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                getIntField(mHealthdConfig->batteryCurrentAvgPath);
370bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            ret = NO_ERROR;
371bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        } else {
372bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor            ret = NAME_NOT_FOUND;
373bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        }
374bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor        break;
375bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor
376347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence    case BATTERY_PROP_CAPACITY:
377347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
3788f132af495d208272ea55d0ca24068926fa80e51Todd Poynor            val->valueInt64 =
379347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence                getIntField(mHealthdConfig->batteryCapacityPath);
380347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence            ret = NO_ERROR;
381347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        } else {
382347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence            ret = NAME_NOT_FOUND;
383347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        }
384347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence        break;
385347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence
3868f132af495d208272ea55d0ca24068926fa80e51Todd Poynor    case BATTERY_PROP_ENERGY_COUNTER:
387e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor        if (mHealthdConfig->energyCounter) {
388e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor            ret = mHealthdConfig->energyCounter(&val->valueInt64);
389e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor        } else {
390e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor            ret = NAME_NOT_FOUND;
391e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor        }
3928f132af495d208272ea55d0ca24068926fa80e51Todd Poynor        break;
3938f132af495d208272ea55d0ca24068926fa80e51Todd Poynor
394c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    default:
395c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor        break;
396c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    }
397c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
398c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor    return ret;
399c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor}
400c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor
401020369d8724eff2b87350e54e157a609846166e4Todd Poynorvoid BatteryMonitor::dumpState(int fd) {
402020369d8724eff2b87350e54e157a609846166e4Todd Poynor    int v;
403020369d8724eff2b87350e54e157a609846166e4Todd Poynor    char vs[128];
404020369d8724eff2b87350e54e157a609846166e4Todd Poynor
405d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos    snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d\n",
406020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.chargerAcOnline, props.chargerUsbOnline,
407d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos             props.chargerWirelessOnline, props.maxChargingCurrent);
408020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
409020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
410020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryStatus, props.batteryHealth, props.batteryPresent);
411020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
412020369d8724eff2b87350e54e157a609846166e4Todd Poynor    snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n",
413020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryLevel, props.batteryVoltage,
414020369d8724eff2b87350e54e157a609846166e4Todd Poynor             props.batteryTemperature);
415020369d8724eff2b87350e54e157a609846166e4Todd Poynor    write(fd, vs, strlen(vs));
416020369d8724eff2b87350e54e157a609846166e4Todd Poynor
417020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
418020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryCurrentNowPath);
419020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "current now: %d\n", v);
420020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
421020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
422020369d8724eff2b87350e54e157a609846166e4Todd Poynor
423020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
424020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
425020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "current avg: %d\n", v);
426020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
427020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
428020369d8724eff2b87350e54e157a609846166e4Todd Poynor
429020369d8724eff2b87350e54e157a609846166e4Todd Poynor    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
430020369d8724eff2b87350e54e157a609846166e4Todd Poynor        v = getIntField(mHealthdConfig->batteryChargeCounterPath);
431020369d8724eff2b87350e54e157a609846166e4Todd Poynor        snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
432020369d8724eff2b87350e54e157a609846166e4Todd Poynor        write(fd, vs, strlen(vs));
433020369d8724eff2b87350e54e157a609846166e4Todd Poynor    }
434cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
435cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
436cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrent);
437cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        write(fd, vs, strlen(vs));
438cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    }
439cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
440cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
441cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
442cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        write(fd, vs, strlen(vs));
443cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    }
444cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
445cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
446cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge);
447cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        write(fd, vs, strlen(vs));
448cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi    }
449020369d8724eff2b87350e54e157a609846166e4Todd Poynor}
450020369d8724eff2b87350e54e157a609846166e4Todd Poynor
451c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynorvoid BatteryMonitor::init(struct healthd_config *hc) {
452752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    String8 path;
4533db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor    char pval[PROPERTY_VALUE_MAX];
454752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
455f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor    mHealthdConfig = hc;
456752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
457752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    if (dir == NULL) {
458752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
459752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    } else {
460752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        struct dirent* entry;
461752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
462752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        while ((entry = readdir(dir))) {
463752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            const char* name = entry->d_name;
464752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
465752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            if (!strcmp(name, ".") || !strcmp(name, ".."))
466752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                continue;
467752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
468752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            // Look for "type" file in each subdirectory
469752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            path.clear();
470752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
471752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            switch(readPowerSupplyType(path)) {
472752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_AC:
473752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_USB:
474752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
475752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.clear();
476752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
477752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                if (access(path.string(), R_OK) == 0)
478752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    mChargerNames.add(String8(name));
479752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
480752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
481752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
4826dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor                mBatteryDevicePresent = true;
4836dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor
484f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryStatusPath.isEmpty()) {
485f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
486f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
487f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
488f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
489f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryStatusPath = path;
490f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
491752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
492f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryHealthPath.isEmpty()) {
493752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    path.clear();
494f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
495f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
496752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    if (access(path, R_OK) == 0)
497f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryHealthPath = path;
498752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
499752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
500f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryPresentPath.isEmpty()) {
501f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
502f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
503f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
504f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
505f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryPresentPath = path;
506f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
507b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
508f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
509f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
510f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
511f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
512f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
513f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryCapacityPath = path;
514f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
515b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor
516f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
517f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
518f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/voltage_now",
519f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
520f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0) {
521f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryVoltagePath = path;
522f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    } else {
523f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.clear();
524f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.appendFormat("%s/%s/batt_vol",
525f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                          POWER_SUPPLY_SYSFS_PATH, name);
526f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        if (access(path, R_OK) == 0)
527f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                            mHealthdConfig->batteryVoltagePath = path;
528f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    }
529f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
530f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
531cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
532cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.clear();
533cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.appendFormat("%s/%s/charge_full",
534cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                      POWER_SUPPLY_SYSFS_PATH, name);
535cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    if (access(path, R_OK) == 0)
536cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                        mHealthdConfig->batteryFullChargePath = path;
537cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                }
538cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
539f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
540752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    path.clear();
541f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/current_now",
542f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
543752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                    if (access(path, R_OK) == 0)
544f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryCurrentNowPath = path;
545f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
546f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
547cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
548cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.clear();
549cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    path.appendFormat("%s/%s/cycle_count",
550cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                                      POWER_SUPPLY_SYSFS_PATH, name);
551cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                    if (access(path, R_OK) == 0)
552cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                        mHealthdConfig->batteryCycleCountPath = path;
553cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi                }
554cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi
555bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
556bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    path.clear();
557bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    path.appendFormat("%s/%s/current_avg",
558bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
559bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                    if (access(path, R_OK) == 0)
560bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                        mHealthdConfig->batteryCurrentAvgPath = path;
561bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor                }
562bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor
563f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
564f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
565f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/charge_counter",
566f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
567f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
568f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryChargeCounterPath = path;
569f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
570f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
571f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
572f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
573f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
574f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      name);
575f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0) {
576f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryTemperaturePath = path;
577f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    } else {
578f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.clear();
579f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        path.appendFormat("%s/%s/batt_temp",
580f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                          POWER_SUPPLY_SYSFS_PATH, name);
581f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        if (access(path, R_OK) == 0)
582f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                            mHealthdConfig->batteryTemperaturePath = path;
583f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    }
584f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                }
585f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor
586f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
587f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.clear();
588f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    path.appendFormat("%s/%s/technology",
589f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                                      POWER_SUPPLY_SYSFS_PATH, name);
590f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                    if (access(path, R_OK) == 0)
591f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor                        mHealthdConfig->batteryTechnologyPath = path;
592752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                }
593752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
594752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
595752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
596752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
597752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor                break;
598752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor            }
599752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        }
600752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        closedir(dir);
601752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor    }
602752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
603f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    if (!mChargerNames.size()) {
604752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor        KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
605f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY;
606f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
607f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        mAlwaysPluggedDevice = true;
608f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi    }
6096dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    if (!mBatteryDevicePresent) {
610ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor        KLOG_WARNING(LOG_TAG, "No battery devices found\n");
6116dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        hc->periodic_chores_interval_fast = -1;
6126dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        hc->periodic_chores_interval_slow = -1;
6136dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    } else {
6146dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryStatusPath.isEmpty())
6156dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
6166dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryHealthPath.isEmpty())
6176dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
6186dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryPresentPath.isEmpty())
6196dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
6206dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryCapacityPath.isEmpty())
6216dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
6226dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryVoltagePath.isEmpty())
6236dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
6246dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryTemperaturePath.isEmpty())
6256dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
6266dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor        if (mHealthdConfig->batteryTechnologyPath.isEmpty())
6276dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor            KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
628f18ec9f227b8298467cc5288bc4a85c76526d67eRuchi Kandoi        if (mHealthdConfig->batteryCurrentNowPath.isEmpty())
629cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
630cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        if (mHealthdConfig->batteryFullChargePath.isEmpty())
631cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
632cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi        if (mHealthdConfig->batteryCycleCountPath.isEmpty())
633cc338801e46776541fb661956ce76a3c97f5bb45Ruchi Kandoi            KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
6346dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor    }
6353db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor
636a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi    if (property_get("ro.boot.fake_battery", pval, NULL) > 0
637a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi                                               && strtol(pval, NULL, 10) != 0) {
638a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi        mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
639a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
640a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi    }
641752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}
642752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor
643752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; // namespace android
644