blob: 44136306fbc7a471abf308d9b818527f332a0406 [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
Yifan Hongb99d15c2022-03-01 12:12:34 -080034#include <aidl/android/hardware/health/HealthInfo.h>
Michael Scott3217c5c2016-06-05 11:20:13 -070035#include <android-base/file.h>
Elliott Hughesda46b392016-10-11 17:09:00 -070036#include <android-base/parseint.h>
Michael Scott3217c5c2016-06-05 11:20:13 -070037#include <android-base/strings.h>
Yifan Hong1d4368b2019-10-07 11:18:04 -070038#include <android/hardware/health/2.1/types.h>
Yifan Hongb99d15c2022-03-01 12:12:34 -080039#include <android/hardware/health/translate-ndk.h>
Todd Poynor752faf22013-06-12 13:25:59 -070040#include <batteryservice/BatteryService.h>
41#include <cutils/klog.h>
Todd Poynor3db03a52014-05-21 16:28:13 -070042#include <cutils/properties.h>
Todd Poynorc133b712013-08-14 17:39:13 -070043#include <utils/Errors.h>
Todd Poynor752faf22013-06-12 13:25:59 -070044#include <utils/String8.h>
45#include <utils/Vector.h>
46
47#define POWER_SUPPLY_SUBSYSTEM "power_supply"
48#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
Ruchi Kandoia78fc232014-07-10 15:06:21 -070049#define FAKE_BATTERY_CAPACITY 42
50#define FAKE_BATTERY_TEMPERATURE 424
Ruchi Kandoi5c09ec12016-02-25 16:19:30 -080051#define MILLION 1.0e6
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -070052#define DEFAULT_VBUS_VOLTAGE 5000000
Todd Poynor752faf22013-06-12 13:25:59 -070053
Yifan Hong1d4368b2019-10-07 11:18:04 -070054using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
55using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo;
56using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
Yifan Hongb99d15c2022-03-01 12:12:34 -080057using aidl::android::hardware::health::BatteryCapacityLevel;
Jack Wue561d032022-11-24 12:19:41 +080058using aidl::android::hardware::health::BatteryChargingPolicy;
59using aidl::android::hardware::health::BatteryChargingState;
Yifan Hongb99d15c2022-03-01 12:12:34 -080060using aidl::android::hardware::health::BatteryHealth;
Jack Wue561d032022-11-24 12:19:41 +080061using aidl::android::hardware::health::BatteryHealthData;
David Andersond5ed26a2023-12-08 15:12:24 -080062using aidl::android::hardware::health::BatteryPartStatus;
Yifan Hongb99d15c2022-03-01 12:12:34 -080063using aidl::android::hardware::health::BatteryStatus;
64using aidl::android::hardware::health::HealthInfo;
65
66namespace {
67
68// Translate from AIDL back to HIDL definition for getHealthInfo_*_* calls.
69// Skips storageInfo and diskStats.
70void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
71 ::android::hardware::health::V1_0::HealthInfo* out) {
72 out->chargerAcOnline = in.chargerAcOnline;
73 out->chargerUsbOnline = in.chargerUsbOnline;
74 out->chargerWirelessOnline = in.chargerWirelessOnline;
75 out->maxChargingCurrent = in.maxChargingCurrentMicroamps;
76 out->maxChargingVoltage = in.maxChargingVoltageMicrovolts;
77 out->batteryStatus =
78 static_cast<::android::hardware::health::V1_0::BatteryStatus>(in.batteryStatus);
79 out->batteryHealth =
80 static_cast<::android::hardware::health::V1_0::BatteryHealth>(in.batteryHealth);
81 out->batteryPresent = in.batteryPresent;
82 out->batteryLevel = in.batteryLevel;
83 out->batteryVoltage = in.batteryVoltageMillivolts;
84 out->batteryTemperature = in.batteryTemperatureTenthsCelsius;
85 out->batteryCurrent = in.batteryCurrentMicroamps;
86 out->batteryCycleCount = in.batteryCycleCount;
87 out->batteryFullCharge = in.batteryFullChargeUah;
88 out->batteryChargeCounter = in.batteryChargeCounterUah;
89 out->batteryTechnology = in.batteryTechnology;
90}
91
92void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
93 ::android::hardware::health::V2_0::HealthInfo* out) {
94 translateToHidl(in, &out->legacy);
95 out->batteryCurrentAverage = in.batteryCurrentAverageMicroamps;
96 // Skip storageInfo and diskStats
97}
98
99void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
100 ::android::hardware::health::V2_1::HealthInfo* out) {
101 translateToHidl(in, &out->legacy);
102 out->batteryCapacityLevel = static_cast<android::hardware::health::V2_1::BatteryCapacityLevel>(
103 in.batteryCapacityLevel);
104 out->batteryChargeTimeToFullNowSeconds = in.batteryChargeTimeToFullNowSeconds;
105 out->batteryFullChargeDesignCapacityUah = in.batteryFullChargeDesignCapacityUah;
106}
107
108} // namespace
Yifan Hong1d4368b2019-10-07 11:18:04 -0700109
Todd Poynor752faf22013-06-12 13:25:59 -0700110namespace android {
111
Yifan Hong1d4368b2019-10-07 11:18:04 -0700112template <typename T>
113struct SysfsStringEnumMap {
Mark Salyzyn6f5b47f2014-05-15 15:00:59 -0700114 const char* s;
Yifan Hong1d4368b2019-10-07 11:18:04 -0700115 T val;
Todd Poynor752faf22013-06-12 13:25:59 -0700116};
117
Yifan Hong1d4368b2019-10-07 11:18:04 -0700118template <typename T>
119static std::optional<T> mapSysfsString(const char* str, SysfsStringEnumMap<T> map[]) {
Todd Poynor752faf22013-06-12 13:25:59 -0700120 for (int i = 0; map[i].s; i++)
121 if (!strcmp(str, map[i].s))
122 return map[i].val;
123
Yifan Hong1d4368b2019-10-07 11:18:04 -0700124 return std::nullopt;
Yabin Cuidb04a492016-02-16 17:19:23 -0800125}
126
Yifan Hongb99d15c2022-03-01 12:12:34 -0800127static void initHealthInfo(HealthInfo* health_info) {
Bart Van Assche024e18f2022-02-24 21:22:07 +0000128 *health_info = {
129 .batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED,
130 .batteryChargeTimeToFullNowSeconds =
131 (int64_t)HealthInfo::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED,
132 .batteryStatus = BatteryStatus::UNKNOWN,
133 .batteryHealth = BatteryHealth::UNKNOWN,
134 };
Yifan Hong6cabe9b2019-11-05 17:04:50 -0800135}
136
Todd Poynore030a102018-01-19 14:03:59 -0800137BatteryMonitor::BatteryMonitor()
138 : mHealthdConfig(nullptr),
139 mBatteryDevicePresent(false),
140 mBatteryFixedCapacity(0),
Yifan Hong1d4368b2019-10-07 11:18:04 -0700141 mBatteryFixedTemperature(0),
Jack Wub57f68a2023-02-04 19:56:06 +0800142 mBatteryHealthStatus(BatteryMonitor::BH_UNKNOWN),
Yifan Hongb99d15c2022-03-01 12:12:34 -0800143 mHealthInfo(std::make_unique<HealthInfo>()) {
Yifan Hong6cabe9b2019-11-05 17:04:50 -0800144 initHealthInfo(mHealthInfo.get());
145}
Yifan Hong1d4368b2019-10-07 11:18:04 -0700146
147BatteryMonitor::~BatteryMonitor() {}
148
Yifan Hongb99d15c2022-03-01 12:12:34 -0800149HealthInfo_1_0 BatteryMonitor::getHealthInfo_1_0() const {
150 HealthInfo_1_0 health_info_1_0;
151 translateToHidl(*mHealthInfo, &health_info_1_0);
152 return health_info_1_0;
Yabin Cuidb04a492016-02-16 17:19:23 -0800153}
154
Yifan Hongb99d15c2022-03-01 12:12:34 -0800155HealthInfo_2_0 BatteryMonitor::getHealthInfo_2_0() const {
156 HealthInfo_2_0 health_info_2_0;
157 translateToHidl(*mHealthInfo, &health_info_2_0);
158 return health_info_2_0;
Hridya Valsaraju7fa72252018-01-12 17:44:33 -0800159}
160
Yifan Hongb99d15c2022-03-01 12:12:34 -0800161HealthInfo_2_1 BatteryMonitor::getHealthInfo_2_1() const {
162 HealthInfo_2_1 health_info_2_1;
163 translateToHidl(*mHealthInfo, &health_info_2_1);
164 return health_info_2_1;
165}
166
167const HealthInfo& BatteryMonitor::getHealthInfo() const {
Yifan Hong1d4368b2019-10-07 11:18:04 -0700168 return *mHealthInfo;
169}
170
171BatteryStatus getBatteryStatus(const char* status) {
172 static SysfsStringEnumMap<BatteryStatus> batteryStatusMap[] = {
173 {"Unknown", BatteryStatus::UNKNOWN},
174 {"Charging", BatteryStatus::CHARGING},
175 {"Discharging", BatteryStatus::DISCHARGING},
176 {"Not charging", BatteryStatus::NOT_CHARGING},
177 {"Full", BatteryStatus::FULL},
178 {NULL, BatteryStatus::UNKNOWN},
Todd Poynor752faf22013-06-12 13:25:59 -0700179 };
180
Yifan Hong1d4368b2019-10-07 11:18:04 -0700181 auto ret = mapSysfsString(status, batteryStatusMap);
182 if (!ret) {
Todd Poynor752faf22013-06-12 13:25:59 -0700183 KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
Yifan Hong1d4368b2019-10-07 11:18:04 -0700184 *ret = BatteryStatus::UNKNOWN;
Todd Poynor752faf22013-06-12 13:25:59 -0700185 }
186
Yifan Hong1d4368b2019-10-07 11:18:04 -0700187 return *ret;
Todd Poynor752faf22013-06-12 13:25:59 -0700188}
189
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800190BatteryCapacityLevel getBatteryCapacityLevel(const char* capacityLevel) {
191 static SysfsStringEnumMap<BatteryCapacityLevel> batteryCapacityLevelMap[] = {
192 {"Unknown", BatteryCapacityLevel::UNKNOWN},
193 {"Critical", BatteryCapacityLevel::CRITICAL},
194 {"Low", BatteryCapacityLevel::LOW},
195 {"Normal", BatteryCapacityLevel::NORMAL},
196 {"High", BatteryCapacityLevel::HIGH},
197 {"Full", BatteryCapacityLevel::FULL},
Stephane Lee06846042020-02-12 17:00:24 -0800198 {NULL, BatteryCapacityLevel::UNSUPPORTED},
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800199 };
200
201 auto ret = mapSysfsString(capacityLevel, batteryCapacityLevelMap);
202 if (!ret) {
Stephane Lee06846042020-02-12 17:00:24 -0800203 KLOG_WARNING(LOG_TAG, "Unsupported battery capacity level '%s'\n", capacityLevel);
204 *ret = BatteryCapacityLevel::UNSUPPORTED;
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800205 }
206
207 return *ret;
208}
209
Yifan Hong1d4368b2019-10-07 11:18:04 -0700210BatteryHealth getBatteryHealth(const char* status) {
211 static SysfsStringEnumMap<BatteryHealth> batteryHealthMap[] = {
212 {"Unknown", BatteryHealth::UNKNOWN},
213 {"Good", BatteryHealth::GOOD},
214 {"Overheat", BatteryHealth::OVERHEAT},
215 {"Dead", BatteryHealth::DEAD},
216 {"Over voltage", BatteryHealth::OVER_VOLTAGE},
217 {"Unspecified failure", BatteryHealth::UNSPECIFIED_FAILURE},
218 {"Cold", BatteryHealth::COLD},
219 // battery health values from JEITA spec
220 {"Warm", BatteryHealth::GOOD},
221 {"Cool", BatteryHealth::GOOD},
222 {"Hot", BatteryHealth::OVERHEAT},
David Anderson629a26b2023-12-11 15:25:13 -0800223 {"Calibration required", BatteryHealth::INCONSISTENT},
Yifan Hong1d4368b2019-10-07 11:18:04 -0700224 {NULL, BatteryHealth::UNKNOWN},
Todd Poynor752faf22013-06-12 13:25:59 -0700225 };
226
Yifan Hong1d4368b2019-10-07 11:18:04 -0700227 auto ret = mapSysfsString(status, batteryHealthMap);
228 if (!ret) {
Todd Poynor752faf22013-06-12 13:25:59 -0700229 KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
Yifan Hong1d4368b2019-10-07 11:18:04 -0700230 *ret = BatteryHealth::UNKNOWN;
Todd Poynor752faf22013-06-12 13:25:59 -0700231 }
232
Yifan Hong1d4368b2019-10-07 11:18:04 -0700233 return *ret;
Todd Poynor752faf22013-06-12 13:25:59 -0700234}
235
Jack Wub57f68a2023-02-04 19:56:06 +0800236BatteryHealth getBatteryHealthStatus(int status) {
237 BatteryHealth value;
238
239 if (status == BatteryMonitor::BH_NOMINAL)
240 value = BatteryHealth::GOOD;
241 else if (status == BatteryMonitor::BH_MARGINAL)
242 value = BatteryHealth::FAIR;
243 else if (status == BatteryMonitor::BH_NEEDS_REPLACEMENT)
244 value = BatteryHealth::DEAD;
245 else if (status == BatteryMonitor::BH_FAILED)
246 value = BatteryHealth::UNSPECIFIED_FAILURE;
Jack Wucf996f32023-04-13 19:37:46 +0800247 else if (status == BatteryMonitor::BH_NOT_AVAILABLE)
248 value = BatteryHealth::NOT_AVAILABLE;
Jack Wu8231c3f2023-05-19 14:31:53 +0800249 else if (status == BatteryMonitor::BH_INCONSISTENT)
250 value = BatteryHealth::INCONSISTENT;
Jack Wub57f68a2023-02-04 19:56:06 +0800251 else
252 value = BatteryHealth::UNKNOWN;
253
254 return value;
255}
256
Jack Wue561d032022-11-24 12:19:41 +0800257BatteryChargingPolicy getBatteryChargingPolicy(const char* chargingPolicy) {
258 static SysfsStringEnumMap<BatteryChargingPolicy> batteryChargingPolicyMap[] = {
259 {"0", BatteryChargingPolicy::INVALID}, {"1", BatteryChargingPolicy::DEFAULT},
260 {"2", BatteryChargingPolicy::LONG_LIFE}, {"3", BatteryChargingPolicy::ADAPTIVE},
261 {NULL, BatteryChargingPolicy::DEFAULT},
262 };
263
264 auto ret = mapSysfsString(chargingPolicy, batteryChargingPolicyMap);
265 if (!ret) {
266 *ret = BatteryChargingPolicy::DEFAULT;
267 }
268
269 return *ret;
270}
271
272BatteryChargingState getBatteryChargingState(const char* chargingState) {
273 static SysfsStringEnumMap<BatteryChargingState> batteryChargingStateMap[] = {
274 {"0", BatteryChargingState::INVALID}, {"1", BatteryChargingState::NORMAL},
275 {"2", BatteryChargingState::TOO_COLD}, {"3", BatteryChargingState::TOO_HOT},
276 {"4", BatteryChargingState::LONG_LIFE}, {"5", BatteryChargingState::ADAPTIVE},
277 {NULL, BatteryChargingState::NORMAL},
278 };
279
280 auto ret = mapSysfsString(chargingState, batteryChargingStateMap);
281 if (!ret) {
282 *ret = BatteryChargingState::NORMAL;
283 }
284
285 return *ret;
286}
287
Bart Van Assche095c9442022-03-02 17:36:34 +0000288static int readFromFile(const String8& path, std::string* buf) {
Bart Van Assche5a7e5082022-02-24 21:40:15 +0000289 buf->clear();
Steven Moreland2aac3352017-03-10 22:31:08 -0800290 if (android::base::ReadFileToString(path.c_str(), buf)) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700291 *buf = android::base::Trim(*buf);
Todd Poynor752faf22013-06-12 13:25:59 -0700292 }
Michael Scott3217c5c2016-06-05 11:20:13 -0700293 return buf->length();
Todd Poynor752faf22013-06-12 13:25:59 -0700294}
295
Jack Wue561d032022-11-24 12:19:41 +0800296static bool writeToFile(const String8& path, int32_t in_value) {
297 return android::base::WriteStringToFile(std::to_string(in_value), path.c_str());
298}
299
Bart Van Assche095c9442022-03-02 17:36:34 +0000300static BatteryMonitor::PowerSupplyType readPowerSupplyType(const String8& path) {
Yifan Hong1d4368b2019-10-07 11:18:04 -0700301 static SysfsStringEnumMap<int> supplyTypeMap[] = {
Bart Van Assche095c9442022-03-02 17:36:34 +0000302 {"Unknown", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
303 {"Battery", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_BATTERY},
304 {"UPS", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
305 {"Mains", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
306 {"USB", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
307 {"USB_DCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
308 {"USB_HVDCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
309 {"USB_CDP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
310 {"USB_ACA", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
311 {"USB_C", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
312 {"USB_PD", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
313 {"USB_PD_DRP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
314 {"Wireless", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_WIRELESS},
315 {"Dock", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_DOCK},
Steve Kondik40c44b42016-07-28 12:17:40 -0700316 {"DASH", ANDROID_POWER_SUPPLY_TYPE_AC},
Yifan Hong1d4368b2019-10-07 11:18:04 -0700317 {NULL, 0},
Todd Poynor752faf22013-06-12 13:25:59 -0700318 };
Yifan Hong1d4368b2019-10-07 11:18:04 -0700319 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700320
Bart Van Assche095c9442022-03-02 17:36:34 +0000321 if (readFromFile(path, &buf) <= 0) {
322 return BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
323 }
Todd Poynor752faf22013-06-12 13:25:59 -0700324
Yifan Hong1d4368b2019-10-07 11:18:04 -0700325 auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
John Stultz47a6bf02019-11-06 00:23:34 +0000326 if (!ret) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700327 KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
Bart Van Assche095c9442022-03-02 17:36:34 +0000328 *ret = BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
Johan Redestig32828612016-02-03 13:45:54 +0100329 }
Todd Poynor752faf22013-06-12 13:25:59 -0700330
Yifan Hong1d4368b2019-10-07 11:18:04 -0700331 return static_cast<BatteryMonitor::PowerSupplyType>(*ret);
Todd Poynor752faf22013-06-12 13:25:59 -0700332}
333
Bart Van Assche095c9442022-03-02 17:36:34 +0000334static bool getBooleanField(const String8& path) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700335 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700336 bool value = false;
Michael Scott3217c5c2016-06-05 11:20:13 -0700337
338 if (readFromFile(path, &buf) > 0)
339 if (buf[0] != '0')
Todd Poynor752faf22013-06-12 13:25:59 -0700340 value = true;
Todd Poynor752faf22013-06-12 13:25:59 -0700341
342 return value;
343}
344
Bart Van Assche095c9442022-03-02 17:36:34 +0000345static int getIntField(const String8& path) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700346 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700347 int value = 0;
Michael Scott3217c5c2016-06-05 11:20:13 -0700348
349 if (readFromFile(path, &buf) > 0)
Elliott Hughesda46b392016-10-11 17:09:00 -0700350 android::base::ParseInt(buf, &value);
Michael Scott3217c5c2016-06-05 11:20:13 -0700351
Todd Poynor752faf22013-06-12 13:25:59 -0700352 return value;
353}
354
Bart Van Assche095c9442022-03-02 17:36:34 +0000355static bool isScopedPowerSupply(const char* name) {
Kazuhiro Inaba8e4d9822019-06-12 13:46:08 +0900356 constexpr char kScopeDevice[] = "Device";
357
358 String8 path;
359 path.appendFormat("%s/%s/scope", POWER_SUPPLY_SYSFS_PATH, name);
360 std::string scope;
361 return (readFromFile(path, &scope) > 0 && scope == kScopeDevice);
362}
363
Yifan Hong1353e702019-10-07 10:41:30 -0700364void BatteryMonitor::updateValues(void) {
Yifan Hong6cabe9b2019-11-05 17:04:50 -0800365 initHealthInfo(mHealthInfo.get());
Yifan Hong1d4368b2019-10-07 11:18:04 -0700366
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000367 if (!mHealthdConfig->batteryPresentPath.empty())
Yifan Hongb99d15c2022-03-01 12:12:34 -0800368 mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
Todd Poynor752faf22013-06-12 13:25:59 -0700369 else
Yifan Hongb99d15c2022-03-01 12:12:34 -0800370 mHealthInfo->batteryPresent = mBatteryDevicePresent;
Todd Poynor752faf22013-06-12 13:25:59 -0700371
Yifan Hongb99d15c2022-03-01 12:12:34 -0800372 mHealthInfo->batteryLevel = mBatteryFixedCapacity
373 ? mBatteryFixedCapacity
374 : getIntField(mHealthdConfig->batteryCapacityPath);
375 mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
Todd Poynorb45f1f52013-07-30 18:57:16 -0700376
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000377 if (!mHealthdConfig->batteryCurrentNowPath.empty())
Yifan Hongb99d15c2022-03-01 12:12:34 -0800378 mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
Ruchi Kandoicc338802015-08-24 13:01:16 -0700379
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000380 if (!mHealthdConfig->batteryFullChargePath.empty())
Yifan Hongb99d15c2022-03-01 12:12:34 -0800381 mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
Ruchi Kandoicc338802015-08-24 13:01:16 -0700382
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000383 if (!mHealthdConfig->batteryCycleCountPath.empty())
Yifan Hongb99d15c2022-03-01 12:12:34 -0800384 mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
Ruchi Kandoicc338802015-08-24 13:01:16 -0700385
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000386 if (!mHealthdConfig->batteryChargeCounterPath.empty())
Yifan Hongb99d15c2022-03-01 12:12:34 -0800387 mHealthInfo->batteryChargeCounterUah =
388 getIntField(mHealthdConfig->batteryChargeCounterPath);
Ruchi Kandoi3f9886b2016-04-07 12:34:40 -0700389
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000390 if (!mHealthdConfig->batteryCurrentAvgPath.empty())
Yifan Hongb99d15c2022-03-01 12:12:34 -0800391 mHealthInfo->batteryCurrentAverageMicroamps =
Yifan Hong35cb0832019-10-07 13:58:29 -0700392 getIntField(mHealthdConfig->batteryCurrentAvgPath);
393
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000394 if (!mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800395 mHealthInfo->batteryChargeTimeToFullNowSeconds =
396 getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
397
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000398 if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
Stephane Lee1c108ed2020-02-10 18:23:57 -0800399 mHealthInfo->batteryFullChargeDesignCapacityUah =
400 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
Yifan Hong35cb0832019-10-07 13:58:29 -0700401
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000402 if (!mHealthdConfig->batteryHealthStatusPath.empty())
Jack Wub57f68a2023-02-04 19:56:06 +0800403 mBatteryHealthStatus = getIntField(mHealthdConfig->batteryHealthStatusPath);
404
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000405 if (!mHealthdConfig->batteryStateOfHealthPath.empty())
AleX Pelosiff708922023-02-17 01:39:21 +0000406 mHealthInfo->batteryHealthData->batteryStateOfHealth =
407 getIntField(mHealthdConfig->batteryStateOfHealthPath);
408
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000409 if (!mHealthdConfig->batteryManufacturingDatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +0800410 mHealthInfo->batteryHealthData->batteryManufacturingDateSeconds =
411 getIntField(mHealthdConfig->batteryManufacturingDatePath);
412
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000413 if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +0800414 mHealthInfo->batteryHealthData->batteryFirstUsageSeconds =
415 getIntField(mHealthdConfig->batteryFirstUsageDatePath);
416
Yifan Hongb99d15c2022-03-01 12:12:34 -0800417 mHealthInfo->batteryTemperatureTenthsCelsius =
418 mBatteryFixedTemperature ? mBatteryFixedTemperature
419 : getIntField(mHealthdConfig->batteryTemperaturePath);
Todd Poynor752faf22013-06-12 13:25:59 -0700420
Michael Scott3217c5c2016-06-05 11:20:13 -0700421 std::string buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700422
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800423 if (readFromFile(mHealthdConfig->batteryCapacityLevelPath, &buf) > 0)
424 mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());
425
Michael Scott3217c5c2016-06-05 11:20:13 -0700426 if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
Yifan Hongb99d15c2022-03-01 12:12:34 -0800427 mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str());
Todd Poynor752faf22013-06-12 13:25:59 -0700428
Jack Wub57f68a2023-02-04 19:56:06 +0800429 // Backward compatible with android.hardware.health V1
430 if (mBatteryHealthStatus < BatteryMonitor::BH_MARGINAL) {
431 if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
432 mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str());
433 } else {
434 mHealthInfo->batteryHealth = getBatteryHealthStatus(mBatteryHealthStatus);
435 }
Todd Poynor752faf22013-06-12 13:25:59 -0700436
Michael Scott3217c5c2016-06-05 11:20:13 -0700437 if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000438 mHealthInfo->batteryTechnology = buf;
Todd Poynor752faf22013-06-12 13:25:59 -0700439
Jack Wue561d032022-11-24 12:19:41 +0800440 if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
441 mHealthInfo->chargingPolicy = getBatteryChargingPolicy(buf.c_str());
442
443 if (readFromFile(mHealthdConfig->chargingStatePath, &buf) > 0)
444 mHealthInfo->chargingState = getBatteryChargingState(buf.c_str());
445
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700446 double MaxPower = 0;
Todd Poynor752faf22013-06-12 13:25:59 -0700447
ShevT9d98a6a2018-07-26 11:47:47 +0300448 for (size_t i = 0; i < mChargerNames.size(); i++) {
Todd Poynor752faf22013-06-12 13:25:59 -0700449 String8 path;
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000450 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].c_str());
Michael Scott3217c5c2016-06-05 11:20:13 -0700451 if (getIntField(path)) {
452 path.clear();
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000453 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].c_str());
Michael Scott3217c5c2016-06-05 11:20:13 -0700454 switch(readPowerSupplyType(path)) {
455 case ANDROID_POWER_SUPPLY_TYPE_AC:
Yifan Hongb99d15c2022-03-01 12:12:34 -0800456 mHealthInfo->chargerAcOnline = true;
Michael Scott3217c5c2016-06-05 11:20:13 -0700457 break;
458 case ANDROID_POWER_SUPPLY_TYPE_USB:
Yifan Hongb99d15c2022-03-01 12:12:34 -0800459 mHealthInfo->chargerUsbOnline = true;
Michael Scott3217c5c2016-06-05 11:20:13 -0700460 break;
461 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
Yifan Hongb99d15c2022-03-01 12:12:34 -0800462 mHealthInfo->chargerWirelessOnline = true;
Michael Scott3217c5c2016-06-05 11:20:13 -0700463 break;
Jack Wu06b90412021-12-15 20:40:21 +0800464 case ANDROID_POWER_SUPPLY_TYPE_DOCK:
Yifan Hongb99d15c2022-03-01 12:12:34 -0800465 mHealthInfo->chargerDockOnline = true;
Jack Wu06b90412021-12-15 20:40:21 +0800466 break;
Michael Scott3217c5c2016-06-05 11:20:13 -0700467 default:
Jack Wu06b90412021-12-15 20:40:21 +0800468 path.clear();
469 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH,
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000470 mChargerNames[i].c_str());
471 if (access(path.c_str(), R_OK) == 0)
Yifan Hongb99d15c2022-03-01 12:12:34 -0800472 mHealthInfo->chargerDockOnline = true;
473 else
Jack Wu06b90412021-12-15 20:40:21 +0800474 KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000475 mChargerNames[i].c_str());
Michael Scott3217c5c2016-06-05 11:20:13 -0700476 }
477 path.clear();
478 path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000479 mChargerNames[i].c_str());
480 int ChargingCurrent = (access(path.c_str(), R_OK) == 0) ? getIntField(path) : 0;
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700481
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700482 path.clear();
483 path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000484 mChargerNames[i].c_str());
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700485
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700486 int ChargingVoltage =
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000487 (access(path.c_str(), R_OK) == 0) ? getIntField(path) : DEFAULT_VBUS_VOLTAGE;
Badhri Jagan Sridharan40e1df42015-10-27 10:43:53 -0700488
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700489 double power = ((double)ChargingCurrent / MILLION) *
490 ((double)ChargingVoltage / MILLION);
491 if (MaxPower < power) {
Yifan Hongb99d15c2022-03-01 12:12:34 -0800492 mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent;
493 mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage;
Dmitry Shmidt9f6b80c2016-06-20 12:58:37 -0700494 MaxPower = power;
Todd Poynor752faf22013-06-12 13:25:59 -0700495 }
496 }
497 }
Yifan Hong1353e702019-10-07 10:41:30 -0700498}
Todd Poynor752faf22013-06-12 13:25:59 -0700499
Bart Van Assche095c9442022-03-02 17:36:34 +0000500static void doLogValues(const HealthInfo& props, const struct healthd_config& healthd_config) {
Yifan Hong1353e702019-10-07 10:41:30 -0700501 char dmesgline[256];
502 size_t len;
503 if (props.batteryPresent) {
504 snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
Yifan Hongb99d15c2022-03-01 12:12:34 -0800505 props.batteryLevel, props.batteryVoltageMillivolts,
506 props.batteryTemperatureTenthsCelsius < 0 ? "-" : "",
507 abs(props.batteryTemperatureTenthsCelsius / 10),
508 abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth,
509 props.batteryStatus);
Todd Poynorb45f1f52013-07-30 18:57:16 -0700510
Yifan Hong1353e702019-10-07 10:41:30 -0700511 len = strlen(dmesgline);
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000512 if (!healthd_config.batteryCurrentNowPath.empty()) {
Yifan Hong1353e702019-10-07 10:41:30 -0700513 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
Yifan Hongb99d15c2022-03-01 12:12:34 -0800514 props.batteryCurrentMicroamps);
Todd Poynor10b235e2013-08-07 15:25:14 -0700515 }
516
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000517 if (!healthd_config.batteryFullChargePath.empty()) {
Yifan Hong1353e702019-10-07 10:41:30 -0700518 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
Yifan Hongb99d15c2022-03-01 12:12:34 -0800519 props.batteryFullChargeUah);
Yifan Hong1353e702019-10-07 10:41:30 -0700520 }
Mark Salyzynacb1ddf2015-07-23 09:22:50 -0700521
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000522 if (!healthd_config.batteryCycleCountPath.empty()) {
Yifan Hong1353e702019-10-07 10:41:30 -0700523 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
524 props.batteryCycleCount);
525 }
526 } else {
527 len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
Todd Poynorb45f1f52013-07-30 18:57:16 -0700528 }
529
Yifan Hongb99d15c2022-03-01 12:12:34 -0800530 snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s",
Yifan Hong1353e702019-10-07 10:41:30 -0700531 props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
Yifan Hongb99d15c2022-03-01 12:12:34 -0800532 props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : "");
Yifan Hong1353e702019-10-07 10:41:30 -0700533
AleX Pelosif08aede2024-02-15 18:42:11 +0000534 KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
Yifan Hong1353e702019-10-07 10:41:30 -0700535}
536
Bart Van Assche095c9442022-03-02 17:36:34 +0000537void BatteryMonitor::logValues(const HealthInfo_2_1& health_info,
538 const struct healthd_config& healthd_config) {
539 HealthInfo aidl_health_info;
540 (void)android::h2a::translate(health_info, &aidl_health_info);
541 doLogValues(aidl_health_info, healthd_config);
542}
543
544void BatteryMonitor::logValues(void) {
545 doLogValues(*mHealthInfo, *mHealthdConfig);
546}
547
Yifan Hong1353e702019-10-07 10:41:30 -0700548bool BatteryMonitor::isChargerOnline() {
Yifan Hongb99d15c2022-03-01 12:12:34 -0800549 const HealthInfo& props = *mHealthInfo;
Jack Wu06b90412021-12-15 20:40:21 +0800550 return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline |
Yifan Hongb99d15c2022-03-01 12:12:34 -0800551 props.chargerDockOnline;
Todd Poynor752faf22013-06-12 13:25:59 -0700552}
553
Yabin Cuiaedf6032016-02-19 18:03:23 -0800554int BatteryMonitor::getChargeStatus() {
Yifan Hong1d4368b2019-10-07 11:18:04 -0700555 BatteryStatus result = BatteryStatus::UNKNOWN;
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000556 if (!mHealthdConfig->batteryStatusPath.empty()) {
Michael Scott3217c5c2016-06-05 11:20:13 -0700557 std::string buf;
558 if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
559 result = getBatteryStatus(buf.c_str());
Yabin Cuiaedf6032016-02-19 18:03:23 -0800560 }
Yifan Hong1d4368b2019-10-07 11:18:04 -0700561 return static_cast<int>(result);
Yabin Cuiaedf6032016-02-19 18:03:23 -0800562}
563
Jack Wue561d032022-11-24 12:19:41 +0800564status_t BatteryMonitor::setChargingPolicy(int value) {
565 status_t ret = NAME_NOT_FOUND;
566 bool result;
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000567 if (!mHealthdConfig->chargingPolicyPath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800568 result = writeToFile(mHealthdConfig->chargingPolicyPath, value);
569 if (!result) {
570 KLOG_WARNING(LOG_TAG, "setChargingPolicy fail\n");
571 ret = BAD_VALUE;
572 } else {
573 ret = OK;
574 }
575 }
576 return ret;
577}
578
579int BatteryMonitor::getChargingPolicy() {
580 BatteryChargingPolicy result = BatteryChargingPolicy::DEFAULT;
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000581 if (!mHealthdConfig->chargingPolicyPath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800582 std::string buf;
583 if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
584 result = getBatteryChargingPolicy(buf.c_str());
585 }
586 return static_cast<int>(result);
587}
588
589int BatteryMonitor::getBatteryHealthData(int id) {
590 if (id == BATTERY_PROP_MANUFACTURING_DATE) {
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000591 if (!mHealthdConfig->batteryManufacturingDatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +0800592 return getIntField(mHealthdConfig->batteryManufacturingDatePath);
593 }
594 if (id == BATTERY_PROP_FIRST_USAGE_DATE) {
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000595 if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +0800596 return getIntField(mHealthdConfig->batteryFirstUsageDatePath);
597 }
AleX Pelosiff708922023-02-17 01:39:21 +0000598 if (id == BATTERY_PROP_STATE_OF_HEALTH) {
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000599 if (!mHealthdConfig->batteryStateOfHealthPath.empty())
AleX Pelosiff708922023-02-17 01:39:21 +0000600 return getIntField(mHealthdConfig->batteryStateOfHealthPath);
601 }
David Andersond5ed26a2023-12-08 15:12:24 -0800602 if (id == BATTERY_PROP_PART_STATUS) {
603 return static_cast<int>(BatteryPartStatus::UNSUPPORTED);
604 }
Jack Wue561d032022-11-24 12:19:41 +0800605 return 0;
606}
607
Todd Poynorc133b712013-08-14 17:39:13 -0700608status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
609 status_t ret = BAD_VALUE;
Jin Qian72adf112017-02-02 17:31:13 -0800610 std::string buf;
Todd Poynorc133b712013-08-14 17:39:13 -0700611
Todd Poynor8f132af2014-05-08 17:15:45 -0700612 val->valueInt64 = LONG_MIN;
613
Todd Poynorc133b712013-08-14 17:39:13 -0700614 switch(id) {
615 case BATTERY_PROP_CHARGE_COUNTER:
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000616 if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700617 val->valueInt64 =
Todd Poynorc133b712013-08-14 17:39:13 -0700618 getIntField(mHealthdConfig->batteryChargeCounterPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700619 ret = OK;
Todd Poynorc133b712013-08-14 17:39:13 -0700620 } else {
621 ret = NAME_NOT_FOUND;
622 }
623 break;
624
625 case BATTERY_PROP_CURRENT_NOW:
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000626 if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700627 val->valueInt64 =
Todd Poynorc133b712013-08-14 17:39:13 -0700628 getIntField(mHealthdConfig->batteryCurrentNowPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700629 ret = OK;
Todd Poynorc133b712013-08-14 17:39:13 -0700630 } else {
631 ret = NAME_NOT_FOUND;
632 }
633 break;
634
Todd Poynorbc102112013-08-27 18:11:49 -0700635 case BATTERY_PROP_CURRENT_AVG:
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000636 if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700637 val->valueInt64 =
Todd Poynorbc102112013-08-27 18:11:49 -0700638 getIntField(mHealthdConfig->batteryCurrentAvgPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700639 ret = OK;
Todd Poynorbc102112013-08-27 18:11:49 -0700640 } else {
641 ret = NAME_NOT_FOUND;
642 }
643 break;
644
Paul Lawrence347c8de2014-03-19 15:04:40 -0700645 case BATTERY_PROP_CAPACITY:
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000646 if (!mHealthdConfig->batteryCapacityPath.empty()) {
Todd Poynor8f132af2014-05-08 17:15:45 -0700647 val->valueInt64 =
Paul Lawrence347c8de2014-03-19 15:04:40 -0700648 getIntField(mHealthdConfig->batteryCapacityPath);
Elliott Hughes643268f2018-10-08 11:10:11 -0700649 ret = OK;
Paul Lawrence347c8de2014-03-19 15:04:40 -0700650 } else {
651 ret = NAME_NOT_FOUND;
652 }
653 break;
654
Todd Poynor8f132af2014-05-08 17:15:45 -0700655 case BATTERY_PROP_ENERGY_COUNTER:
Todd Poynore14b37e2014-05-20 13:54:40 -0700656 if (mHealthdConfig->energyCounter) {
657 ret = mHealthdConfig->energyCounter(&val->valueInt64);
658 } else {
659 ret = NAME_NOT_FOUND;
660 }
Todd Poynor8f132af2014-05-08 17:15:45 -0700661 break;
662
Jin Qian72adf112017-02-02 17:31:13 -0800663 case BATTERY_PROP_BATTERY_STATUS:
Todd Poynore030a102018-01-19 14:03:59 -0800664 val->valueInt64 = getChargeStatus();
Elliott Hughes643268f2018-10-08 11:10:11 -0700665 ret = OK;
Jin Qian72adf112017-02-02 17:31:13 -0800666 break;
667
Jack Wue561d032022-11-24 12:19:41 +0800668 case BATTERY_PROP_CHARGING_POLICY:
669 val->valueInt64 = getChargingPolicy();
670 ret = OK;
671 break;
672
673 case BATTERY_PROP_MANUFACTURING_DATE:
674 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_MANUFACTURING_DATE);
675 ret = OK;
676 break;
677
678 case BATTERY_PROP_FIRST_USAGE_DATE:
679 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_FIRST_USAGE_DATE);
680 ret = OK;
681 break;
682
AleX Pelosiff708922023-02-17 01:39:21 +0000683 case BATTERY_PROP_STATE_OF_HEALTH:
684 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_STATE_OF_HEALTH);
685 ret = OK;
686 break;
687
David Andersond5ed26a2023-12-08 15:12:24 -0800688 case BATTERY_PROP_PART_STATUS:
689 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_PART_STATUS);
690 ret = OK;
691 break;
692
Todd Poynorc133b712013-08-14 17:39:13 -0700693 default:
694 break;
695 }
696
Todd Poynorc133b712013-08-14 17:39:13 -0700697 return ret;
698}
699
David Andersond5ed26a2023-12-08 15:12:24 -0800700status_t BatteryMonitor::getSerialNumber(std::optional<std::string>* out) {
701 *out = std::nullopt;
702 return OK;
703}
704
Todd Poynor020369d2013-09-18 20:09:33 -0700705void BatteryMonitor::dumpState(int fd) {
706 int v;
707 char vs[128];
Yifan Hongb99d15c2022-03-01 12:12:34 -0800708 const HealthInfo& props = *mHealthInfo;
Todd Poynor020369d2013-09-18 20:09:33 -0700709
Jack Wu06b90412021-12-15 20:40:21 +0800710 snprintf(vs, sizeof(vs),
711 "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n",
712 props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline,
Yifan Hongb99d15c2022-03-01 12:12:34 -0800713 props.chargerDockOnline, props.maxChargingCurrentMicroamps,
714 props.maxChargingVoltageMicrovolts);
Todd Poynor020369d2013-09-18 20:09:33 -0700715 write(fd, vs, strlen(vs));
716 snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
717 props.batteryStatus, props.batteryHealth, props.batteryPresent);
718 write(fd, vs, strlen(vs));
Yifan Hongb99d15c2022-03-01 12:12:34 -0800719 snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel,
720 props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
Todd Poynor020369d2013-09-18 20:09:33 -0700721 write(fd, vs, strlen(vs));
722
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000723 if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
Todd Poynor020369d2013-09-18 20:09:33 -0700724 v = getIntField(mHealthdConfig->batteryCurrentNowPath);
725 snprintf(vs, sizeof(vs), "current now: %d\n", v);
726 write(fd, vs, strlen(vs));
727 }
728
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000729 if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
Todd Poynor020369d2013-09-18 20:09:33 -0700730 v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
731 snprintf(vs, sizeof(vs), "current avg: %d\n", v);
732 write(fd, vs, strlen(vs));
733 }
734
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000735 if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
Todd Poynor020369d2013-09-18 20:09:33 -0700736 v = getIntField(mHealthdConfig->batteryChargeCounterPath);
737 snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
738 write(fd, vs, strlen(vs));
739 }
Ruchi Kandoicc338802015-08-24 13:01:16 -0700740
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000741 if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
Yifan Hongb99d15c2022-03-01 12:12:34 -0800742 snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps);
Ruchi Kandoicc338802015-08-24 13:01:16 -0700743 write(fd, vs, strlen(vs));
744 }
745
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000746 if (!mHealthdConfig->batteryCycleCountPath.empty()) {
Ruchi Kandoicc338802015-08-24 13:01:16 -0700747 snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
748 write(fd, vs, strlen(vs));
749 }
750
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000751 if (!mHealthdConfig->batteryFullChargePath.empty()) {
Yifan Hongb99d15c2022-03-01 12:12:34 -0800752 snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah);
Ruchi Kandoicc338802015-08-24 13:01:16 -0700753 write(fd, vs, strlen(vs));
754 }
Todd Poynor020369d2013-09-18 20:09:33 -0700755}
756
Todd Poynorc7464c92013-09-10 12:40:00 -0700757void BatteryMonitor::init(struct healthd_config *hc) {
Todd Poynor752faf22013-06-12 13:25:59 -0700758 String8 path;
Todd Poynor3db03a52014-05-21 16:28:13 -0700759 char pval[PROPERTY_VALUE_MAX];
Todd Poynor752faf22013-06-12 13:25:59 -0700760
Todd Poynorf5d30122013-08-12 17:03:35 -0700761 mHealthdConfig = hc;
James Hawkins588a2ca2016-02-18 14:52:46 -0800762 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
Todd Poynor752faf22013-06-12 13:25:59 -0700763 if (dir == NULL) {
764 KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
765 } else {
766 struct dirent* entry;
767
James Hawkins588a2ca2016-02-18 14:52:46 -0800768 while ((entry = readdir(dir.get()))) {
Todd Poynor752faf22013-06-12 13:25:59 -0700769 const char* name = entry->d_name;
770
771 if (!strcmp(name, ".") || !strcmp(name, ".."))
772 continue;
773
Bart Van Assche25b2a8d2022-02-24 21:51:34 +0000774 std::vector<String8>::iterator itIgnoreName =
775 find(hc->ignorePowerSupplyNames.begin(), hc->ignorePowerSupplyNames.end(),
776 String8(name));
Thierry Strudelf73de6f2019-01-11 17:09:20 -0800777 if (itIgnoreName != hc->ignorePowerSupplyNames.end())
778 continue;
779
Todd Poynor752faf22013-06-12 13:25:59 -0700780 // Look for "type" file in each subdirectory
781 path.clear();
782 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
783 switch(readPowerSupplyType(path)) {
784 case ANDROID_POWER_SUPPLY_TYPE_AC:
785 case ANDROID_POWER_SUPPLY_TYPE_USB:
786 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
Jack Wu06b90412021-12-15 20:40:21 +0800787 case ANDROID_POWER_SUPPLY_TYPE_DOCK:
Todd Poynor752faf22013-06-12 13:25:59 -0700788 path.clear();
789 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000790 if (access(path.c_str(), R_OK) == 0) mChargerNames.add(String8(name));
Todd Poynor752faf22013-06-12 13:25:59 -0700791 break;
792
793 case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
Kazuhiro Inaba8e4d9822019-06-12 13:46:08 +0900794 // Some devices expose the battery status of sub-component like
795 // stylus. Such a device-scoped battery info needs to be skipped
796 // in BatteryMonitor, which is intended to report the status of
797 // the battery supplying the power to the whole system.
798 if (isScopedPowerSupply(name)) continue;
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700799 mBatteryDevicePresent = true;
800
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000801 if (mHealthdConfig->batteryStatusPath.empty()) {
Todd Poynor752faf22013-06-12 13:25:59 -0700802 path.clear();
Todd Poynorf5d30122013-08-12 17:03:35 -0700803 path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
804 name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000805 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryStatusPath = path;
Todd Poynor752faf22013-06-12 13:25:59 -0700806 }
807
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000808 if (mHealthdConfig->batteryHealthPath.empty()) {
Todd Poynor752faf22013-06-12 13:25:59 -0700809 path.clear();
Todd Poynorf5d30122013-08-12 17:03:35 -0700810 path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
811 name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000812 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryHealthPath = path;
Todd Poynor752faf22013-06-12 13:25:59 -0700813 }
814
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000815 if (mHealthdConfig->batteryPresentPath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700816 path.clear();
817 path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
818 name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000819 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryPresentPath = path;
Todd Poynorf5d30122013-08-12 17:03:35 -0700820 }
821
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000822 if (mHealthdConfig->batteryCapacityPath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700823 path.clear();
824 path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
825 name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000826 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryCapacityPath = path;
Todd Poynorf5d30122013-08-12 17:03:35 -0700827 }
828
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000829 if (mHealthdConfig->batteryVoltagePath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700830 path.clear();
831 path.appendFormat("%s/%s/voltage_now",
832 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000833 if (access(path.c_str(), R_OK) == 0) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700834 mHealthdConfig->batteryVoltagePath = path;
Todd Poynorf5d30122013-08-12 17:03:35 -0700835 }
836 }
837
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000838 if (mHealthdConfig->batteryFullChargePath.empty()) {
Ruchi Kandoicc338802015-08-24 13:01:16 -0700839 path.clear();
840 path.appendFormat("%s/%s/charge_full",
841 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000842 if (access(path.c_str(), R_OK) == 0)
Ruchi Kandoicc338802015-08-24 13:01:16 -0700843 mHealthdConfig->batteryFullChargePath = path;
844 }
845
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000846 if (mHealthdConfig->batteryCurrentNowPath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700847 path.clear();
848 path.appendFormat("%s/%s/current_now",
849 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000850 if (access(path.c_str(), R_OK) == 0)
Todd Poynorf5d30122013-08-12 17:03:35 -0700851 mHealthdConfig->batteryCurrentNowPath = path;
852 }
853
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000854 if (mHealthdConfig->batteryCycleCountPath.empty()) {
Ruchi Kandoicc338802015-08-24 13:01:16 -0700855 path.clear();
856 path.appendFormat("%s/%s/cycle_count",
857 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000858 if (access(path.c_str(), R_OK) == 0)
Ruchi Kandoicc338802015-08-24 13:01:16 -0700859 mHealthdConfig->batteryCycleCountPath = path;
860 }
861
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000862 if (mHealthdConfig->batteryCapacityLevelPath.empty()) {
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800863 path.clear();
864 path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000865 if (access(path.c_str(), R_OK) == 0) {
866 mHealthdConfig->batteryCapacityLevelPath = path;
867 }
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800868 }
869
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000870 if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty()) {
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800871 path.clear();
872 path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000873 if (access(path.c_str(), R_OK) == 0)
Stephane Lee86f9f6a2019-12-19 15:09:41 -0800874 mHealthdConfig->batteryChargeTimeToFullNowPath = path;
875 }
876
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000877 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty()) {
Stephane Lee1c108ed2020-02-10 18:23:57 -0800878 path.clear();
879 path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000880 if (access(path.c_str(), R_OK) == 0)
Stephane Lee1c108ed2020-02-10 18:23:57 -0800881 mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
882 }
883
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000884 if (mHealthdConfig->batteryCurrentAvgPath.empty()) {
Todd Poynorbc102112013-08-27 18:11:49 -0700885 path.clear();
886 path.appendFormat("%s/%s/current_avg",
887 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000888 if (access(path.c_str(), R_OK) == 0)
Todd Poynorbc102112013-08-27 18:11:49 -0700889 mHealthdConfig->batteryCurrentAvgPath = path;
890 }
891
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000892 if (mHealthdConfig->batteryChargeCounterPath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700893 path.clear();
894 path.appendFormat("%s/%s/charge_counter",
895 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000896 if (access(path.c_str(), R_OK) == 0)
Todd Poynorf5d30122013-08-12 17:03:35 -0700897 mHealthdConfig->batteryChargeCounterPath = path;
898 }
899
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000900 if (mHealthdConfig->batteryTemperaturePath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700901 path.clear();
902 path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
903 name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000904 if (access(path.c_str(), R_OK) == 0) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700905 mHealthdConfig->batteryTemperaturePath = path;
Todd Poynorf5d30122013-08-12 17:03:35 -0700906 }
907 }
908
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000909 if (mHealthdConfig->batteryTechnologyPath.empty()) {
Todd Poynorf5d30122013-08-12 17:03:35 -0700910 path.clear();
911 path.appendFormat("%s/%s/technology",
912 POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000913 if (access(path.c_str(), R_OK) == 0)
Todd Poynorf5d30122013-08-12 17:03:35 -0700914 mHealthdConfig->batteryTechnologyPath = path;
915 }
916
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000917 if (mHealthdConfig->batteryStateOfHealthPath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800918 path.clear();
919 path.appendFormat("%s/%s/state_of_health", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000920 if (access(path.c_str(), R_OK) == 0) {
Jack Wue561d032022-11-24 12:19:41 +0800921 mHealthdConfig->batteryStateOfHealthPath = path;
922 } else {
923 path.clear();
924 path.appendFormat("%s/%s/health_index", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000925 if (access(path.c_str(), R_OK) == 0)
Jack Wue561d032022-11-24 12:19:41 +0800926 mHealthdConfig->batteryStateOfHealthPath = path;
927 }
928 }
929
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000930 if (mHealthdConfig->batteryHealthStatusPath.empty()) {
Jack Wub57f68a2023-02-04 19:56:06 +0800931 path.clear();
932 path.appendFormat("%s/%s/health_status", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000933 if (access(path.c_str(), R_OK) == 0) {
934 mHealthdConfig->batteryHealthStatusPath = path;
935 }
Jack Wub57f68a2023-02-04 19:56:06 +0800936 }
937
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000938 if (mHealthdConfig->batteryManufacturingDatePath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800939 path.clear();
940 path.appendFormat("%s/%s/manufacturing_date", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000941 if (access(path.c_str(), R_OK) == 0)
Jack Wue561d032022-11-24 12:19:41 +0800942 mHealthdConfig->batteryManufacturingDatePath = path;
943 }
944
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000945 if (mHealthdConfig->batteryFirstUsageDatePath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800946 path.clear();
947 path.appendFormat("%s/%s/first_usage_date", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000948 if (access(path.c_str(), R_OK) == 0) {
949 mHealthdConfig->batteryFirstUsageDatePath = path;
950 }
Jack Wue561d032022-11-24 12:19:41 +0800951 }
952
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000953 if (mHealthdConfig->chargingStatePath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800954 path.clear();
955 path.appendFormat("%s/%s/charging_state", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000956 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingStatePath = path;
Jack Wue561d032022-11-24 12:19:41 +0800957 }
958
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000959 if (mHealthdConfig->chargingPolicyPath.empty()) {
Jack Wue561d032022-11-24 12:19:41 +0800960 path.clear();
961 path.appendFormat("%s/%s/charging_policy", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk2b1a0592023-09-12 15:26:15 +0000962 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingPolicyPath = path;
Jack Wue561d032022-11-24 12:19:41 +0800963 }
964
Todd Poynor752faf22013-06-12 13:25:59 -0700965 break;
966
967 case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
968 break;
969 }
Jack Wu06b90412021-12-15 20:40:21 +0800970
971 // Look for "is_dock" file
972 path.clear();
973 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000974 if (access(path.c_str(), R_OK) == 0) {
Jack Wu06b90412021-12-15 20:40:21 +0800975 path.clear();
976 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
Tomasz Wasilczyk18b74612023-08-10 23:29:50 +0000977 if (access(path.c_str(), R_OK) == 0) mChargerNames.add(String8(name));
Jack Wu06b90412021-12-15 20:40:21 +0800978 }
Todd Poynor752faf22013-06-12 13:25:59 -0700979 }
Todd Poynor752faf22013-06-12 13:25:59 -0700980 }
981
Ian Pedowitz585ab652015-10-12 19:01:00 -0700982 // Typically the case for devices which do not have a battery and
983 // and are always plugged into AC mains.
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700984 if (!mBatteryDevicePresent) {
Todd Poynorebeb0c02014-09-23 14:54:24 -0700985 KLOG_WARNING(LOG_TAG, "No battery devices found\n");
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700986 hc->periodic_chores_interval_fast = -1;
987 hc->periodic_chores_interval_slow = -1;
988 } else {
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000989 if (mHealthdConfig->batteryStatusPath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700990 KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000991 if (mHealthdConfig->batteryHealthPath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700992 KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000993 if (mHealthdConfig->batteryPresentPath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700994 KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000995 if (mHealthdConfig->batteryCapacityPath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700996 KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000997 if (mHealthdConfig->batteryVoltagePath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -0700998 KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +0000999 if (mHealthdConfig->batteryTemperaturePath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -07001000 KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001001 if (mHealthdConfig->batteryTechnologyPath.empty())
Todd Poynor6dcc45e2013-10-21 20:26:25 -07001002 KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001003 if (mHealthdConfig->batteryCurrentNowPath.empty())
Ruchi Kandoicc338802015-08-24 13:01:16 -07001004 KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001005 if (mHealthdConfig->batteryFullChargePath.empty())
Ruchi Kandoicc338802015-08-24 13:01:16 -07001006 KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001007 if (mHealthdConfig->batteryCycleCountPath.empty())
Ruchi Kandoicc338802015-08-24 13:01:16 -07001008 KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001009 if (mHealthdConfig->batteryCapacityLevelPath.empty())
Stephane Lee86f9f6a2019-12-19 15:09:41 -08001010 KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001011 if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
Stephane Lee86f9f6a2019-12-19 15:09:41 -08001012 KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001013 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
Stephane Lee1c108ed2020-02-10 18:23:57 -08001014 KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001015 if (mHealthdConfig->batteryStateOfHealthPath.empty())
Jack Wue561d032022-11-24 12:19:41 +08001016 KLOG_WARNING(LOG_TAG, "batteryStateOfHealthPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001017 if (mHealthdConfig->batteryHealthStatusPath.empty())
Jack Wub57f68a2023-02-04 19:56:06 +08001018 KLOG_WARNING(LOG_TAG, "batteryHealthStatusPath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001019 if (mHealthdConfig->batteryManufacturingDatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +08001020 KLOG_WARNING(LOG_TAG, "batteryManufacturingDatePath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001021 if (mHealthdConfig->batteryFirstUsageDatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +08001022 KLOG_WARNING(LOG_TAG, "batteryFirstUsageDatePath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001023 if (mHealthdConfig->chargingStatePath.empty())
Jack Wue561d032022-11-24 12:19:41 +08001024 KLOG_WARNING(LOG_TAG, "chargingStatePath not found\n");
Tomasz Wasilczykf5971292023-08-14 18:18:26 +00001025 if (mHealthdConfig->chargingPolicyPath.empty())
Jack Wue561d032022-11-24 12:19:41 +08001026 KLOG_WARNING(LOG_TAG, "chargingPolicyPath not found\n");
Todd Poynor6dcc45e2013-10-21 20:26:25 -07001027 }
Todd Poynor3db03a52014-05-21 16:28:13 -07001028
Ruchi Kandoia78fc232014-07-10 15:06:21 -07001029 if (property_get("ro.boot.fake_battery", pval, NULL) > 0
1030 && strtol(pval, NULL, 10) != 0) {
1031 mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
1032 mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
1033 }
Todd Poynor752faf22013-06-12 13:25:59 -07001034}
1035
1036}; // namespace android