blob: 5890f9aab6ab313287f02164867626930d48cf6d [file] [log] [blame]
Todd Poynor752faf22013-06-12 13:25:59 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "healthd"
18
Yabin Cuie98e1772016-02-17 12:21:34 -080019#include <healthd/healthd.h>
20#include <healthd/BatteryMonitor.h>
Todd Poynor752faf22013-06-12 13:25:59 -070021
22#include <dirent.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <stdio.h>
26#include <stdlib.h>
Mark Salyzynacb1ddf2015-07-23 09:22:50 -070027#include <sys/types.h>
Todd Poynor752faf22013-06-12 13:25:59 -070028#include <unistd.h>
Thierry Strudelf73de6f2019-01-11 17:09:20 -080029
30#include <algorithm>
James Hawkins588a2ca2016-02-18 14:52:46 -080031#include <memory>
Yifan Hong1d4368b2019-10-07 11:18:04 -070032#include <optional>
Mark Salyzynacb1ddf2015-07-23 09:22:50 -070033
Michael Scott3217c5c2016-06-05 11:20:13 -070034#include <android-base/file.h>
Elliott Hughesda46b392016-10-11 17:09:00 -070035#include <android-base/parseint.h>
Michael Scott3217c5c2016-06-05 11:20:13 -070036#include <android-base/strings.h>
Yifan Hong1d4368b2019-10-07 11:18:04 -070037#include <android/hardware/health/2.1/types.h>
Todd Poynor752faf22013-06-12 13:25:59 -070038#include <batteryservice/BatteryService.h>
39#include <cutils/klog.h>
Todd Poynor3db03a52014-05-21 16:28:13 -070040#include <cutils/properties.h>
Todd Poynorc133b712013-08-14 17:39:13 -070041#include <utils/Errors.h>
Todd Poynor752faf22013-06-12 13:25:59 -070042#include <utils/String8.h>
43#include <utils/Vector.h>
44
45#define POWER_SUPPLY_SUBSYSTEM "power_supply"
46#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
Ruchi Kandoia78fc232014-07-10 15:06:21 -070047#define FAKE_BATTERY_CAPACITY 42
48#define FAKE_BATTERY_TEMPERATURE 424
Ruchi Kandoi5c09ec12016-02-25 16:19:30 -080049#define MILLION 1.0e6
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -070050#define DEFAULT_VBUS_VOLTAGE 5000000
Todd Poynor752faf22013-06-12 13:25:59 -070051
Yifan Hong1d4368b2019-10-07 11:18:04 -070052using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
53using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo;
54using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
55using android::hardware::health::V1_0::BatteryHealth;
56using android::hardware::health::V1_0::BatteryStatus;
Yifan Hong35cb0832019-10-07 13:58:29 -070057using android::hardware::health::V2_1::BatteryCapacityLevel;
Stephane Lee06846042020-02-12 17:00:24 -080058using android::hardware::health::V2_1::Constants;
Yifan Hong1d4368b2019-10-07 11:18:04 -070059
Todd Poynor752faf22013-06-12 13:25:59 -070060namespace android {
61
Yifan Hong1d4368b2019-10-07 11:18:04 -070062template <typename T>
63struct SysfsStringEnumMap {
Mark Salyzyn6f5b47f2014-05-15 15:00:59 -070064 const char* s;
Yifan Hong1d4368b2019-10-07 11:18:04 -070065 T val;
Todd Poynor752faf22013-06-12 13:25:59 -070066};
67
Yifan Hong1d4368b2019-10-07 11:18:04 -070068template <typename T>
69static std::optional<T> mapSysfsString(const char* str, SysfsStringEnumMap<T> map[]) {
Todd Poynor752faf22013-06-12 13:25:59 -070070 for (int i = 0; map[i].s; i++)
71 if (!strcmp(str, map[i].s))
72 return map[i].val;
73
Yifan Hong1d4368b2019-10-07 11:18:04 -070074 return std::nullopt;
Yabin Cuidb04a492016-02-16 17:19:23 -080075}
76
Yifan Hong6cabe9b2019-11-05 17:04:50 -080077static void initHealthInfo(HealthInfo_2_1* health_info_2_1) {
78 *health_info_2_1 = HealthInfo_2_1{};
79
80 // HIDL enum values are zero initialized, so they need to be initialized
81 // properly.
Stephane Leebab68772020-08-12 22:38:20 -070082 health_info_2_1->batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED;
Stephane Lee06846042020-02-12 17:00:24 -080083 health_info_2_1->batteryChargeTimeToFullNowSeconds =
84 (int64_t)Constants::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED;
Yifan Hong6cabe9b2019-11-05 17:04:50 -080085 auto* props = &health_info_2_1->legacy.legacy;
86 props->batteryStatus = BatteryStatus::UNKNOWN;
87 props->batteryHealth = BatteryHealth::UNKNOWN;
88}
89
Todd Poynore030a102018-01-19 14:03:59 -080090BatteryMonitor::BatteryMonitor()
91 : mHealthdConfig(nullptr),
92 mBatteryDevicePresent(false),
93 mBatteryFixedCapacity(0),
Yifan Hong1d4368b2019-10-07 11:18:04 -070094 mBatteryFixedTemperature(0),
Jack Wu06b90412021-12-15 20:40:21 +080095 mChargerDockOnline(false),
Yifan Hong6cabe9b2019-11-05 17:04:50 -080096 mHealthInfo(std::make_unique<HealthInfo_2_1>()) {
97 initHealthInfo(mHealthInfo.get());
98}
Yifan Hong1d4368b2019-10-07 11:18:04 -070099
100BatteryMonitor::~BatteryMonitor() {}
101
102const HealthInfo_1_0& BatteryMonitor::getHealthInfo_1_0() const {
103 return getHealthInfo_2_0().legacy;
Yabin Cuidb04a492016-02-16 17:19:23 -0800104}
105
Yifan Hong1d4368b2019-10-07 11:18:04 -0700106const HealthInfo_2_0& BatteryMonitor::getHealthInfo_2_0() const {
107 return getHealthInfo_2_1().legacy;
Hridya Valsaraju7fa72252018-01-12 17:44:33 -0800108}
109
Yifan Hong1d4368b2019-10-07 11:18:04 -0700110const HealthInfo_2_1& BatteryMonitor::getHealthInfo_2_1() const {
111 return *mHealthInfo;
112}
113
114BatteryStatus getBatteryStatus(const char* status) {
115 static SysfsStringEnumMap<BatteryStatus> batteryStatusMap[] = {
116 {"Unknown", BatteryStatus::UNKNOWN},
117 {"Charging", BatteryStatus::CHARGING},
118 {"Discharging", BatteryStatus::DISCHARGING},
119 {"Not charging", BatteryStatus::NOT_CHARGING},
120 {"Full", BatteryStatus::FULL},
121 {NULL, BatteryStatus::UNKNOWN},
Todd Poynor752faf22013-06-12 13:25:59 -0700122 };
123
Yifan Hong1d4368b2019-10-07 11:18:04 -0700124 auto ret = mapSysfsString(status, batteryStatusMap);
125 if (!ret) {
Todd Poynor752faf22013-06-12 13:25:59 -0700126 KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
Yifan Hong1d4368b2019-10-07 11:18:04 -0700127 *ret = BatteryStatus::UNKNOWN;
Todd Poynor752faf22013-06-12 13:25:59 -0700128 }
129
Yifan Hong1d4368b2019-10-07 11:18:04 -0700130 return *ret;
Todd Poynor752faf22013-06-12 13:25:59 -0700131}
132
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800133BatteryCapacityLevel getBatteryCapacityLevel(const char* capacityLevel) {
134 static SysfsStringEnumMap<BatteryCapacityLevel> batteryCapacityLevelMap[] = {
135 {"Unknown", BatteryCapacityLevel::UNKNOWN},
136 {"Critical", BatteryCapacityLevel::CRITICAL},
137 {"Low", BatteryCapacityLevel::LOW},
138 {"Normal", BatteryCapacityLevel::NORMAL},
139 {"High", BatteryCapacityLevel::HIGH},
140 {"Full", BatteryCapacityLevel::FULL},
Stephane Lee06846042020-02-12 17:00:24 -0800141 {NULL, BatteryCapacityLevel::UNSUPPORTED},
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800142 };
143
144 auto ret = mapSysfsString(capacityLevel, batteryCapacityLevelMap);
145 if (!ret) {
Stephane Lee06846042020-02-12 17:00:24 -0800146 KLOG_WARNING(LOG_TAG, "Unsupported battery capacity level '%s'\n", capacityLevel);
147 *ret = BatteryCapacityLevel::UNSUPPORTED;
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800148 }
149
150 return *ret;
151}
152
Yifan Hong1d4368b2019-10-07 11:18:04 -0700153BatteryHealth getBatteryHealth(const char* status) {
154 static SysfsStringEnumMap<BatteryHealth> batteryHealthMap[] = {
155 {"Unknown", BatteryHealth::UNKNOWN},
156 {"Good", BatteryHealth::GOOD},
157 {"Overheat", BatteryHealth::OVERHEAT},
158 {"Dead", BatteryHealth::DEAD},
159 {"Over voltage", BatteryHealth::OVER_VOLTAGE},
160 {"Unspecified failure", BatteryHealth::UNSPECIFIED_FAILURE},
161 {"Cold", BatteryHealth::COLD},
162 // battery health values from JEITA spec
163 {"Warm", BatteryHealth::GOOD},
164 {"Cool", BatteryHealth::GOOD},
165 {"Hot", BatteryHealth::OVERHEAT},
166 {NULL, BatteryHealth::UNKNOWN},
Todd Poynor752faf22013-06-12 13:25:59 -0700167 };
168
Yifan Hong1d4368b2019-10-07 11:18:04 -0700169 auto ret = mapSysfsString(status, batteryHealthMap);
170 if (!ret) {
Todd Poynor752faf22013-06-12 13:25:59 -0700171 KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
Yifan Hong1d4368b2019-10-07 11:18:04 -0700172 *ret = BatteryHealth::UNKNOWN;
Todd Poynor752faf22013-06-12 13:25:59 -0700173 }
174
Yifan Hong1d4368b2019-10-07 11:18:04 -0700175 return *ret;
Todd Poynor752faf22013-06-12 13:25:59 -0700176}
177
Michael Scott3217c5c2016-06-05 11:20:13 -0700178int BatteryMonitor::readFromFile(const String8& path, std::string* buf) {
Steven Moreland2aac3352017-03-10 22:31:08 -0800179 if (android::base::ReadFileToString(path.c_str(), buf)) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700180 *buf = android::base::Trim(*buf);
Todd Poynor752faf22013-06-12 13:25:59 -0700181 }
Michael Scott3217c5c2016-06-05 11:20:13 -0700182 return buf->length();
Todd Poynor752faf22013-06-12 13:25:59 -0700183}
184
185BatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) {
Yifan Hong1d4368b2019-10-07 11:18:04 -0700186 static SysfsStringEnumMap<int> supplyTypeMap[] = {
187 {"Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
188 {"Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY},
189 {"UPS", ANDROID_POWER_SUPPLY_TYPE_AC},
190 {"Mains", ANDROID_POWER_SUPPLY_TYPE_AC},
191 {"USB", ANDROID_POWER_SUPPLY_TYPE_USB},
192 {"USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC},
193 {"USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC},
194 {"USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC},
195 {"USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC},
196 {"USB_C", ANDROID_POWER_SUPPLY_TYPE_AC},
197 {"USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC},
198 {"USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB},
199 {"Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS},
Jack Wu06b90412021-12-15 20:40:21 +0800200 {"Dock", ANDROID_POWER_SUPPLY_TYPE_DOCK},
Yifan Hong1d4368b2019-10-07 11:18:04 -0700201 {NULL, 0},
Todd Poynor752faf22013-06-12 13:25:59 -0700202 };
Yifan Hong1d4368b2019-10-07 11:18:04 -0700203 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700204
Michael Scott3217c5c2016-06-05 11:20:13 -0700205 if (readFromFile(path, &buf) <= 0)
Todd Poynor752faf22013-06-12 13:25:59 -0700206 return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
207
Yifan Hong1d4368b2019-10-07 11:18:04 -0700208 auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
John Stultz47a6bf02019-11-06 00:23:34 +0000209 if (!ret) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700210 KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
Yifan Hong1d4368b2019-10-07 11:18:04 -0700211 *ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
Johan Redestig32828612016-02-03 13:45:54 +0100212 }
Todd Poynor752faf22013-06-12 13:25:59 -0700213
Yifan Hong1d4368b2019-10-07 11:18:04 -0700214 return static_cast<BatteryMonitor::PowerSupplyType>(*ret);
Todd Poynor752faf22013-06-12 13:25:59 -0700215}
216
217bool BatteryMonitor::getBooleanField(const String8& path) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700218 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700219 bool value = false;
Michael Scott3217c5c2016-06-05 11:20:13 -0700220
221 if (readFromFile(path, &buf) > 0)
222 if (buf[0] != '0')
Todd Poynor752faf22013-06-12 13:25:59 -0700223 value = true;
Todd Poynor752faf22013-06-12 13:25:59 -0700224
225 return value;
226}
227
228int BatteryMonitor::getIntField(const String8& path) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700229 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700230 int value = 0;
Michael Scott3217c5c2016-06-05 11:20:13 -0700231
232 if (readFromFile(path, &buf) > 0)
Elliott Hughesda46b392016-10-11 17:09:00 -0700233 android::base::ParseInt(buf, &value);
Michael Scott3217c5c2016-06-05 11:20:13 -0700234
Todd Poynor752faf22013-06-12 13:25:59 -0700235 return value;
236}
237
Kazuhiro Inaba8e4d9822019-06-12 13:46:08 +0900238bool BatteryMonitor::isScopedPowerSupply(const char* name) {
239 constexpr char kScopeDevice[] = "Device";
240
241 String8 path;
242 path.appendFormat("%s/%s/scope", POWER_SUPPLY_SYSFS_PATH, name);
243 std::string scope;
244 return (readFromFile(path, &scope) > 0 && scope == kScopeDevice);
245}
246
Yifan Hong1353e702019-10-07 10:41:30 -0700247void BatteryMonitor::updateValues(void) {
Yifan Hong6cabe9b2019-11-05 17:04:50 -0800248 initHealthInfo(mHealthInfo.get());
Yifan Hong1d4368b2019-10-07 11:18:04 -0700249
250 HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
Todd Poynor752faf22013-06-12 13:25:59 -0700251
Todd Poynorf5d30122013-08-12 17:03:35 -0700252 if (!mHealthdConfig->batteryPresentPath.isEmpty())
253 props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
Todd Poynor752faf22013-06-12 13:25:59 -0700254 else
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700255 props.batteryPresent = mBatteryDevicePresent;
Todd Poynor752faf22013-06-12 13:25:59 -0700256
Todd Poynor3db03a52014-05-21 16:28:13 -0700257 props.batteryLevel = mBatteryFixedCapacity ?
258 mBatteryFixedCapacity :
259 getIntField(mHealthdConfig->batteryCapacityPath);
Todd Poynorf5d30122013-08-12 17:03:35 -0700260 props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
Todd Poynorb45f1f52013-07-30 18:57:16 -0700261
Ruchi Kandoicc338802015-08-24 13:01:16 -0700262 if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
Yifan Honge5bd5f92020-04-08 16:14:45 -0700263 props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath);
Ruchi Kandoicc338802015-08-24 13:01:16 -0700264
265 if (!mHealthdConfig->batteryFullChargePath.isEmpty())
266 props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);
267
268 if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
269 props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
270
Ruchi Kandoi3f9886b2016-04-07 12:34:40 -0700271 if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
272 props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);
273
Yifan Hong35cb0832019-10-07 13:58:29 -0700274 if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty())
275 mHealthInfo->legacy.batteryCurrentAverage =
276 getIntField(mHealthdConfig->batteryCurrentAvgPath);
277
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800278 if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
279 mHealthInfo->batteryChargeTimeToFullNowSeconds =
280 getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
281
Stephane Lee1c108ed2020-02-10 18:23:57 -0800282 if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
283 mHealthInfo->batteryFullChargeDesignCapacityUah =
284 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
Yifan Hong35cb0832019-10-07 13:58:29 -0700285
Todd Poynor3db03a52014-05-21 16:28:13 -0700286 props.batteryTemperature = mBatteryFixedTemperature ?
287 mBatteryFixedTemperature :
288 getIntField(mHealthdConfig->batteryTemperaturePath);
Todd Poynor752faf22013-06-12 13:25:59 -0700289
Michael Scott3217c5c2016-06-05 11:20:13 -0700290 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700291
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800292 if (readFromFile(mHealthdConfig->batteryCapacityLevelPath, &buf) > 0)
293 mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());
294
Michael Scott3217c5c2016-06-05 11:20:13 -0700295 if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
296 props.batteryStatus = getBatteryStatus(buf.c_str());
Todd Poynor752faf22013-06-12 13:25:59 -0700297
Michael Scott3217c5c2016-06-05 11:20:13 -0700298 if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
299 props.batteryHealth = getBatteryHealth(buf.c_str());
Todd Poynor752faf22013-06-12 13:25:59 -0700300
Michael Scott3217c5c2016-06-05 11:20:13 -0700301 if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
302 props.batteryTechnology = String8(buf.c_str());
Todd Poynor752faf22013-06-12 13:25:59 -0700303
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700304 double MaxPower = 0;
Todd Poynor752faf22013-06-12 13:25:59 -0700305
ShevT9d98a6a2018-07-26 11:47:47 +0300306 for (size_t i = 0; i < mChargerNames.size(); i++) {
Todd Poynor752faf22013-06-12 13:25:59 -0700307 String8 path;
308 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
309 mChargerNames[i].string());
Michael Scott3217c5c2016-06-05 11:20:13 -0700310 if (getIntField(path)) {
311 path.clear();
312 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
313 mChargerNames[i].string());
314 switch(readPowerSupplyType(path)) {
315 case ANDROID_POWER_SUPPLY_TYPE_AC:
316 props.chargerAcOnline = true;
317 break;
318 case ANDROID_POWER_SUPPLY_TYPE_USB:
319 props.chargerUsbOnline = true;
320 break;
321 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
322 props.chargerWirelessOnline = true;
323 break;
Jack Wu06b90412021-12-15 20:40:21 +0800324 case ANDROID_POWER_SUPPLY_TYPE_DOCK:
325 mChargerDockOnline = true;
326 break;
Michael Scott3217c5c2016-06-05 11:20:13 -0700327 default:
Jack Wu06b90412021-12-15 20:40:21 +0800328 path.clear();
329 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH,
330 mChargerNames[i].string());
331 if (access(path.string(), R_OK) == 0) {
332 mChargerDockOnline = true;
333 KLOG_INFO(LOG_TAG, "%s: online\n",
334 mChargerNames[i].string());
335 } else {
336 KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
337 mChargerNames[i].string());
338 }
Michael Scott3217c5c2016-06-05 11:20:13 -0700339 }
340 path.clear();
341 path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
342 mChargerNames[i].string());
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700343 int ChargingCurrent =
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700344 (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;
345
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700346 path.clear();
347 path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
348 mChargerNames[i].string());
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700349
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700350 int ChargingVoltage =
351 (access(path.string(), R_OK) == 0) ? getIntField(path) :
352 DEFAULT_VBUS_VOLTAGE;
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700353
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700354 double power = ((double)ChargingCurrent / MILLION) *
355 ((double)ChargingVoltage / MILLION);
356 if (MaxPower < power) {
357 props.maxChargingCurrent = ChargingCurrent;
358 props.maxChargingVoltage = ChargingVoltage;
359 MaxPower = power;
Todd Poynor752faf22013-06-12 13:25:59 -0700360 }
361 }
362 }
Yifan Hong1353e702019-10-07 10:41:30 -0700363}
Todd Poynor752faf22013-06-12 13:25:59 -0700364
Yifan Hong1353e702019-10-07 10:41:30 -0700365void BatteryMonitor::logValues(void) {
Yifan Hong605e7d22021-02-08 15:14:48 -0800366 logValues(*mHealthInfo, *mHealthdConfig);
367}
368
369void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo& health_info,
370 const struct healthd_config& healthd_config) {
Yifan Hong1353e702019-10-07 10:41:30 -0700371 char dmesgline[256];
372 size_t len;
Yifan Hong605e7d22021-02-08 15:14:48 -0800373 const HealthInfo_1_0& props = health_info.legacy.legacy;
Yifan Hong1353e702019-10-07 10:41:30 -0700374 if (props.batteryPresent) {
375 snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
376 props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "",
377 abs(props.batteryTemperature / 10), abs(props.batteryTemperature % 10),
378 props.batteryHealth, props.batteryStatus);
Todd Poynorb45f1f52013-07-30 18:57:16 -0700379
Yifan Hong1353e702019-10-07 10:41:30 -0700380 len = strlen(dmesgline);
Yifan Hong605e7d22021-02-08 15:14:48 -0800381 if (!healthd_config.batteryCurrentNowPath.isEmpty()) {
Yifan Hong1353e702019-10-07 10:41:30 -0700382 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
383 props.batteryCurrent);
Todd Poynor10b235e2013-08-07 15:25:14 -0700384 }
385
Yifan Hong605e7d22021-02-08 15:14:48 -0800386 if (!healthd_config.batteryFullChargePath.isEmpty()) {
Yifan Hong1353e702019-10-07 10:41:30 -0700387 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
388 props.batteryFullCharge);
389 }
Mark Salyzynacb1ddf2015-07-23 09:22:50 -0700390
Yifan Hong605e7d22021-02-08 15:14:48 -0800391 if (!healthd_config.batteryCycleCountPath.isEmpty()) {
Yifan Hong1353e702019-10-07 10:41:30 -0700392 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
393 props.batteryCycleCount);
394 }
395 } else {
396 len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
Todd Poynorb45f1f52013-07-30 18:57:16 -0700397 }
398
Yifan Hong1353e702019-10-07 10:41:30 -0700399 snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
400 props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
401 props.chargerWirelessOnline ? "w" : "");
402
403 KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
404}
405
406bool BatteryMonitor::isChargerOnline() {
Yifan Hong1d4368b2019-10-07 11:18:04 -0700407 const HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
Jack Wu06b90412021-12-15 20:40:21 +0800408 return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline |
409 mChargerDockOnline;
Todd Poynor752faf22013-06-12 13:25:59 -0700410}
411
Yabin Cuiaedf6032016-02-19 18:03:23 -0800412int BatteryMonitor::getChargeStatus() {
Yifan Hong1d4368b2019-10-07 11:18:04 -0700413 BatteryStatus result = BatteryStatus::UNKNOWN;
Yabin Cuiaedf6032016-02-19 18:03:23 -0800414 if (!mHealthdConfig->batteryStatusPath.isEmpty()) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700415 std::string buf;
416 if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
417 result = getBatteryStatus(buf.c_str());
Yabin Cuiaedf6032016-02-19 18:03:23 -0800418 }
Yifan Hong1d4368b2019-10-07 11:18:04 -0700419 return static_cast<int>(result);
Yabin Cuiaedf6032016-02-19 18:03:23 -0800420}
421
Todd Poynorc133b712013-08-14 17:39:13 -0700422status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
423 status_t ret = BAD_VALUE;
Jin Qian72adf112017-02-02 17:31:13 -0800424 std::string buf;
Todd Poynorc133b712013-08-14 17:39:13 -0700425
Todd Poynor8f132af2014-05-08 17:15:45 -0700426 val->valueInt64 = LONG_MIN;
427
Todd Poynorc133b712013-08-14 17:39:13 -0700428 switch(id) {
429 case BATTERY_PROP_CHARGE_COUNTER:
430 if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700431 val->valueInt64 =
Todd Poynorc133b712013-08-14 17:39:13 -0700432 getIntField(mHealthdConfig->batteryChargeCounterPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700433 ret = OK;
Todd Poynorc133b712013-08-14 17:39:13 -0700434 } else {
435 ret = NAME_NOT_FOUND;
436 }
437 break;
438
439 case BATTERY_PROP_CURRENT_NOW:
440 if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700441 val->valueInt64 =
Todd Poynorc133b712013-08-14 17:39:13 -0700442 getIntField(mHealthdConfig->batteryCurrentNowPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700443 ret = OK;
Todd Poynorc133b712013-08-14 17:39:13 -0700444 } else {
445 ret = NAME_NOT_FOUND;
446 }
447 break;
448
Todd Poynorbc102112013-08-27 18:11:49 -0700449 case BATTERY_PROP_CURRENT_AVG:
450 if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700451 val->valueInt64 =
Todd Poynorbc102112013-08-27 18:11:49 -0700452 getIntField(mHealthdConfig->batteryCurrentAvgPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700453 ret = OK;
Todd Poynorbc102112013-08-27 18:11:49 -0700454 } else {
455 ret = NAME_NOT_FOUND;
456 }
457 break;
458
Paul Lawrence347c8de2014-03-19 15:04:40 -0700459 case BATTERY_PROP_CAPACITY:
460 if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700461 val->valueInt64 =
Paul Lawrence347c8de2014-03-19 15:04:40 -0700462 getIntField(mHealthdConfig->batteryCapacityPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700463 ret = OK;
Paul Lawrence347c8de2014-03-19 15:04:40 -0700464 } else {
465 ret = NAME_NOT_FOUND;
466 }
467 break;
468
Todd Poynor8f132af2014-05-08 17:15:45 -0700469 case BATTERY_PROP_ENERGY_COUNTER:
Todd Poynore14b37e2014-05-20 13:54:40 -0700470 if (mHealthdConfig->energyCounter) {
471 ret = mHealthdConfig->energyCounter(&val->valueInt64);
472 } else {
473 ret = NAME_NOT_FOUND;
474 }
Todd Poynor8f132af2014-05-08 17:15:45 -0700475 break;
476
Jin Qian72adf112017-02-02 17:31:13 -0800477 case BATTERY_PROP_BATTERY_STATUS:
Todd Poynore030a102018-01-19 14:03:59 -0800478 val->valueInt64 = getChargeStatus();
Elliott Hughes643268f2018-10-08 11:10:11 -0700479 ret = OK;
Jin Qian72adf112017-02-02 17:31:13 -0800480 break;
481
Todd Poynorc133b712013-08-14 17:39:13 -0700482 default:
483 break;
484 }
485
Todd Poynorc133b712013-08-14 17:39:13 -0700486 return ret;
487}
488
Todd Poynor020369d2013-09-18 20:09:33 -0700489void BatteryMonitor::dumpState(int fd) {
490 int v;
491 char vs[128];
Yifan Hong1d4368b2019-10-07 11:18:04 -0700492 const HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
Todd Poynor020369d2013-09-18 20:09:33 -0700493
Jack Wu06b90412021-12-15 20:40:21 +0800494 snprintf(vs, sizeof(vs),
495 "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n",
496 props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline,
497 mChargerDockOnline, props.maxChargingCurrent, props.maxChargingVoltage);
Todd Poynor020369d2013-09-18 20:09:33 -0700498 write(fd, vs, strlen(vs));
499 snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
500 props.batteryStatus, props.batteryHealth, props.batteryPresent);
501 write(fd, vs, strlen(vs));
502 snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n",
503 props.batteryLevel, props.batteryVoltage,
504 props.batteryTemperature);
505 write(fd, vs, strlen(vs));
506
507 if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
508 v = getIntField(mHealthdConfig->batteryCurrentNowPath);
509 snprintf(vs, sizeof(vs), "current now: %d\n", v);
510 write(fd, vs, strlen(vs));
511 }
512
513 if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
514 v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
515 snprintf(vs, sizeof(vs), "current avg: %d\n", v);
516 write(fd, vs, strlen(vs));
517 }
518
519 if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
520 v = getIntField(mHealthdConfig->batteryChargeCounterPath);
521 snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
522 write(fd, vs, strlen(vs));
523 }
Ruchi Kandoicc338802015-08-24 13:01:16 -0700524
525 if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
526 snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrent);
527 write(fd, vs, strlen(vs));
528 }
529
530 if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
531 snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
532 write(fd, vs, strlen(vs));
533 }
534
535 if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
536 snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge);
537 write(fd, vs, strlen(vs));
538 }
Todd Poynor020369d2013-09-18 20:09:33 -0700539}
540
Todd Poynorc7464c92013-09-10 12:40:00 -0700541void BatteryMonitor::init(struct healthd_config *hc) {
Todd Poynor752faf22013-06-12 13:25:59 -0700542 String8 path;
Todd Poynor3db03a52014-05-21 16:28:13 -0700543 char pval[PROPERTY_VALUE_MAX];
Todd Poynor752faf22013-06-12 13:25:59 -0700544
Todd Poynorf5d30122013-08-12 17:03:35 -0700545 mHealthdConfig = hc;
James Hawkins588a2ca2016-02-18 14:52:46 -0800546 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
Todd Poynor752faf22013-06-12 13:25:59 -0700547 if (dir == NULL) {
548 KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
549 } else {
550 struct dirent* entry;
551
James Hawkins588a2ca2016-02-18 14:52:46 -0800552 while ((entry = readdir(dir.get()))) {
Todd Poynor752faf22013-06-12 13:25:59 -0700553 const char* name = entry->d_name;
Thierry Strudelf73de6f2019-01-11 17:09:20 -0800554 std::vector<String8>::iterator itIgnoreName;
Todd Poynor752faf22013-06-12 13:25:59 -0700555
556 if (!strcmp(name, ".") || !strcmp(name, ".."))
557 continue;
558
Thierry Strudelf73de6f2019-01-11 17:09:20 -0800559 itIgnoreName = find(hc->ignorePowerSupplyNames.begin(),
560 hc->ignorePowerSupplyNames.end(), String8(name));
561 if (itIgnoreName != hc->ignorePowerSupplyNames.end())
562 continue;
563
Todd Poynor752faf22013-06-12 13:25:59 -0700564 // Look for "type" file in each subdirectory
565 path.clear();
566 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
567 switch(readPowerSupplyType(path)) {
568 case ANDROID_POWER_SUPPLY_TYPE_AC:
569 case ANDROID_POWER_SUPPLY_TYPE_USB:
570 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
Jack Wu06b90412021-12-15 20:40:21 +0800571 case ANDROID_POWER_SUPPLY_TYPE_DOCK:
Todd Poynor752faf22013-06-12 13:25:59 -0700572 path.clear();
573 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
574 if (access(path.string(), R_OK) == 0)
575 mChargerNames.add(String8(name));
576 break;
577
578 case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
Kazuhiro Inaba8e4d9822019-06-12 13:46:08 +0900579 // Some devices expose the battery status of sub-component like
580 // stylus. Such a device-scoped battery info needs to be skipped
581 // in BatteryMonitor, which is intended to report the status of
582 // the battery supplying the power to the whole system.
583 if (isScopedPowerSupply(name)) continue;
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700584 mBatteryDevicePresent = true;
585
Todd Poynorf5d30122013-08-12 17:03:35 -0700586 if (mHealthdConfig->batteryStatusPath.isEmpty()) {
Todd Poynor752faf22013-06-12 13:25:59 -0700587 path.clear();
Todd Poynorf5d30122013-08-12 17:03:35 -0700588 path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
589 name);
Todd Poynor752faf22013-06-12 13:25:59 -0700590 if (access(path, R_OK) == 0)
Todd Poynorf5d30122013-08-12 17:03:35 -0700591 mHealthdConfig->batteryStatusPath = path;
Todd Poynor752faf22013-06-12 13:25:59 -0700592 }
593
Todd Poynorf5d30122013-08-12 17:03:35 -0700594 if (mHealthdConfig->batteryHealthPath.isEmpty()) {
Todd Poynor752faf22013-06-12 13:25:59 -0700595 path.clear();
Todd Poynorf5d30122013-08-12 17:03:35 -0700596 path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
597 name);
Todd Poynor752faf22013-06-12 13:25:59 -0700598 if (access(path, R_OK) == 0)
Todd Poynorf5d30122013-08-12 17:03:35 -0700599 mHealthdConfig->batteryHealthPath = path;
Todd Poynor752faf22013-06-12 13:25:59 -0700600 }
601
Todd Poynorf5d30122013-08-12 17:03:35 -0700602 if (mHealthdConfig->batteryPresentPath.isEmpty()) {
603 path.clear();
604 path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
605 name);
606 if (access(path, R_OK) == 0)
607 mHealthdConfig->batteryPresentPath = path;
608 }
609
610 if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
611 path.clear();
612 path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
613 name);
614 if (access(path, R_OK) == 0)
615 mHealthdConfig->batteryCapacityPath = path;
616 }
617
618 if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
619 path.clear();
620 path.appendFormat("%s/%s/voltage_now",
621 POWER_SUPPLY_SYSFS_PATH, name);
622 if (access(path, R_OK) == 0) {
623 mHealthdConfig->batteryVoltagePath = path;
Todd Poynorf5d30122013-08-12 17:03:35 -0700624 }
625 }
626
Ruchi Kandoicc338802015-08-24 13:01:16 -0700627 if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
628 path.clear();
629 path.appendFormat("%s/%s/charge_full",
630 POWER_SUPPLY_SYSFS_PATH, name);
631 if (access(path, R_OK) == 0)
632 mHealthdConfig->batteryFullChargePath = path;
633 }
634
Todd Poynorf5d30122013-08-12 17:03:35 -0700635 if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
636 path.clear();
637 path.appendFormat("%s/%s/current_now",
638 POWER_SUPPLY_SYSFS_PATH, name);
639 if (access(path, R_OK) == 0)
640 mHealthdConfig->batteryCurrentNowPath = path;
641 }
642
Ruchi Kandoicc338802015-08-24 13:01:16 -0700643 if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
644 path.clear();
645 path.appendFormat("%s/%s/cycle_count",
646 POWER_SUPPLY_SYSFS_PATH, name);
647 if (access(path, R_OK) == 0)
648 mHealthdConfig->batteryCycleCountPath = path;
649 }
650
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800651 if (mHealthdConfig->batteryCapacityLevelPath.isEmpty()) {
652 path.clear();
653 path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
654 if (access(path, R_OK) == 0) mHealthdConfig->batteryCapacityLevelPath = path;
655 }
656
657 if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty()) {
658 path.clear();
659 path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
660 if (access(path, R_OK) == 0)
661 mHealthdConfig->batteryChargeTimeToFullNowPath = path;
662 }
663
Stephane Lee1c108ed2020-02-10 18:23:57 -0800664 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty()) {
665 path.clear();
666 path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
667 if (access(path, R_OK) == 0)
668 mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
669 }
670
Todd Poynorbc102112013-08-27 18:11:49 -0700671 if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
672 path.clear();
673 path.appendFormat("%s/%s/current_avg",
674 POWER_SUPPLY_SYSFS_PATH, name);
675 if (access(path, R_OK) == 0)
676 mHealthdConfig->batteryCurrentAvgPath = path;
677 }
678
Todd Poynorf5d30122013-08-12 17:03:35 -0700679 if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
680 path.clear();
681 path.appendFormat("%s/%s/charge_counter",
682 POWER_SUPPLY_SYSFS_PATH, name);
683 if (access(path, R_OK) == 0)
684 mHealthdConfig->batteryChargeCounterPath = path;
685 }
686
687 if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
688 path.clear();
689 path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
690 name);
691 if (access(path, R_OK) == 0) {
692 mHealthdConfig->batteryTemperaturePath = path;
Todd Poynorf5d30122013-08-12 17:03:35 -0700693 }
694 }
695
696 if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
697 path.clear();
698 path.appendFormat("%s/%s/technology",
699 POWER_SUPPLY_SYSFS_PATH, name);
700 if (access(path, R_OK) == 0)
701 mHealthdConfig->batteryTechnologyPath = path;
702 }
703
Todd Poynor752faf22013-06-12 13:25:59 -0700704 break;
705
706 case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
707 break;
708 }
Jack Wu06b90412021-12-15 20:40:21 +0800709
710 // Look for "is_dock" file
711 path.clear();
712 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, name);
713 if (access(path.string(), R_OK) == 0) {
714 path.clear();
715 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
716 if (access(path.string(), R_OK) == 0)
717 mChargerNames.add(String8(name));
718
719 }
Todd Poynor752faf22013-06-12 13:25:59 -0700720 }
Todd Poynor752faf22013-06-12 13:25:59 -0700721 }
722
Ian Pedowitz585ab652015-10-12 19:01:00 -0700723 // Typically the case for devices which do not have a battery and
724 // and are always plugged into AC mains.
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700725 if (!mBatteryDevicePresent) {
Todd Poynorebeb0c02014-09-23 14:54:24 -0700726 KLOG_WARNING(LOG_TAG, "No battery devices found\n");
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700727 hc->periodic_chores_interval_fast = -1;
728 hc->periodic_chores_interval_slow = -1;
729 } else {
730 if (mHealthdConfig->batteryStatusPath.isEmpty())
731 KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
732 if (mHealthdConfig->batteryHealthPath.isEmpty())
733 KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
734 if (mHealthdConfig->batteryPresentPath.isEmpty())
735 KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
736 if (mHealthdConfig->batteryCapacityPath.isEmpty())
737 KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
738 if (mHealthdConfig->batteryVoltagePath.isEmpty())
739 KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
740 if (mHealthdConfig->batteryTemperaturePath.isEmpty())
741 KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
742 if (mHealthdConfig->batteryTechnologyPath.isEmpty())
743 KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
Ruchi Kandoif18ec9f2015-09-28 13:35:59 -0700744 if (mHealthdConfig->batteryCurrentNowPath.isEmpty())
Ruchi Kandoicc338802015-08-24 13:01:16 -0700745 KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
746 if (mHealthdConfig->batteryFullChargePath.isEmpty())
747 KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
748 if (mHealthdConfig->batteryCycleCountPath.isEmpty())
749 KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800750 if (mHealthdConfig->batteryCapacityLevelPath.isEmpty())
751 KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
752 if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
753 KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
Stephane Lee1c108ed2020-02-10 18:23:57 -0800754 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
755 KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700756 }
Todd Poynor3db03a52014-05-21 16:28:13 -0700757
Ruchi Kandoia78fc232014-07-10 15:06:21 -0700758 if (property_get("ro.boot.fake_battery", pval, NULL) > 0
759 && strtol(pval, NULL, 10) != 0) {
760 mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
761 mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
762 }
Todd Poynor752faf22013-06-12 13:25:59 -0700763}
764
765}; // namespace android