1 /*
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
19 #include <healthd/healthd.h>
20 #include <healthd/BatteryMonitor.h>
21
22 #include <dirent.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29
30 #include <algorithm>
31 #include <memory>
32 #include <optional>
33
34 #include <aidl/android/hardware/health/HealthInfo.h>
35 #include <android-base/file.h>
36 #include <android-base/parseint.h>
37 #include <android-base/strings.h>
38 #include <android/hardware/health/2.1/types.h>
39 #include <android/hardware/health/translate-ndk.h>
40 #include <batteryservice/BatteryService.h>
41 #include <cutils/klog.h>
42 #include <cutils/properties.h>
43 #include <utils/Errors.h>
44 #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
49 #define FAKE_BATTERY_CAPACITY 42
50 #define FAKE_BATTERY_TEMPERATURE 424
51 #define MILLION 1.0e6
52 #define DEFAULT_VBUS_VOLTAGE 5000000
53
54 using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
55 using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo;
56 using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
57 using aidl::android::hardware::health::BatteryCapacityLevel;
58 using aidl::android::hardware::health::BatteryChargingPolicy;
59 using aidl::android::hardware::health::BatteryChargingState;
60 using aidl::android::hardware::health::BatteryHealth;
61 using aidl::android::hardware::health::BatteryHealthData;
62 using aidl::android::hardware::health::BatteryPartStatus;
63 using aidl::android::hardware::health::BatteryStatus;
64 using aidl::android::hardware::health::HealthInfo;
65
66 namespace {
67
68 // Translate from AIDL back to HIDL definition for getHealthInfo_*_* calls.
69 // Skips storageInfo and diskStats.
translateToHidl(const::aidl::android::hardware::health::HealthInfo & in,::android::hardware::health::V1_0::HealthInfo * out)70 void 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
translateToHidl(const::aidl::android::hardware::health::HealthInfo & in,::android::hardware::health::V2_0::HealthInfo * out)92 void 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
translateToHidl(const::aidl::android::hardware::health::HealthInfo & in,::android::hardware::health::V2_1::HealthInfo * out)99 void 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
109
110 namespace android {
111
112 template <typename T>
113 struct SysfsStringEnumMap {
114 const char* s;
115 T val;
116 };
117
118 template <typename T>
mapSysfsString(const char * str,SysfsStringEnumMap<T> map[])119 static std::optional<T> mapSysfsString(const char* str, SysfsStringEnumMap<T> map[]) {
120 for (int i = 0; map[i].s; i++)
121 if (!strcmp(str, map[i].s))
122 return map[i].val;
123
124 return std::nullopt;
125 }
126
initHealthInfo(HealthInfo * health_info)127 static void initHealthInfo(HealthInfo* health_info) {
128 *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 .batteryHealthData = std::nullopt,
135 };
136 }
137
BatteryMonitor()138 BatteryMonitor::BatteryMonitor()
139 : mHealthdConfig(nullptr),
140 mBatteryDevicePresent(false),
141 mBatteryFixedCapacity(0),
142 mBatteryFixedTemperature(0),
143 mBatteryHealthStatus(BatteryMonitor::BH_UNKNOWN),
144 mHealthInfo(std::make_unique<HealthInfo>()) {
145 initHealthInfo(mHealthInfo.get());
146 }
147
~BatteryMonitor()148 BatteryMonitor::~BatteryMonitor() {}
149
getHealthInfo_1_0() const150 HealthInfo_1_0 BatteryMonitor::getHealthInfo_1_0() const {
151 HealthInfo_1_0 health_info_1_0;
152 translateToHidl(*mHealthInfo, &health_info_1_0);
153 return health_info_1_0;
154 }
155
getHealthInfo_2_0() const156 HealthInfo_2_0 BatteryMonitor::getHealthInfo_2_0() const {
157 HealthInfo_2_0 health_info_2_0;
158 translateToHidl(*mHealthInfo, &health_info_2_0);
159 return health_info_2_0;
160 }
161
getHealthInfo_2_1() const162 HealthInfo_2_1 BatteryMonitor::getHealthInfo_2_1() const {
163 HealthInfo_2_1 health_info_2_1;
164 translateToHidl(*mHealthInfo, &health_info_2_1);
165 return health_info_2_1;
166 }
167
getHealthInfo() const168 const HealthInfo& BatteryMonitor::getHealthInfo() const {
169 return *mHealthInfo;
170 }
171
getBatteryStatus(const char * status)172 BatteryStatus getBatteryStatus(const char* status) {
173 static SysfsStringEnumMap<BatteryStatus> batteryStatusMap[] = {
174 {"Unknown", BatteryStatus::UNKNOWN},
175 {"Charging", BatteryStatus::CHARGING},
176 {"Discharging", BatteryStatus::DISCHARGING},
177 {"Not charging", BatteryStatus::NOT_CHARGING},
178 {"Full", BatteryStatus::FULL},
179 {NULL, BatteryStatus::UNKNOWN},
180 };
181
182 auto ret = mapSysfsString(status, batteryStatusMap);
183 if (!ret) {
184 KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
185 *ret = BatteryStatus::UNKNOWN;
186 }
187
188 return *ret;
189 }
190
getBatteryCapacityLevel(const char * capacityLevel)191 BatteryCapacityLevel getBatteryCapacityLevel(const char* capacityLevel) {
192 static SysfsStringEnumMap<BatteryCapacityLevel> batteryCapacityLevelMap[] = {
193 {"Unknown", BatteryCapacityLevel::UNKNOWN},
194 {"Critical", BatteryCapacityLevel::CRITICAL},
195 {"Low", BatteryCapacityLevel::LOW},
196 {"Normal", BatteryCapacityLevel::NORMAL},
197 {"High", BatteryCapacityLevel::HIGH},
198 {"Full", BatteryCapacityLevel::FULL},
199 {NULL, BatteryCapacityLevel::UNSUPPORTED},
200 };
201
202 auto ret = mapSysfsString(capacityLevel, batteryCapacityLevelMap);
203 if (!ret) {
204 KLOG_WARNING(LOG_TAG, "Unsupported battery capacity level '%s'\n", capacityLevel);
205 *ret = BatteryCapacityLevel::UNSUPPORTED;
206 }
207
208 return *ret;
209 }
210
getBatteryHealth(const char * status)211 BatteryHealth getBatteryHealth(const char* status) {
212 static SysfsStringEnumMap<BatteryHealth> batteryHealthMap[] = {
213 {"Unknown", BatteryHealth::UNKNOWN},
214 {"Good", BatteryHealth::GOOD},
215 {"Overheat", BatteryHealth::OVERHEAT},
216 {"Dead", BatteryHealth::DEAD},
217 {"Over voltage", BatteryHealth::OVER_VOLTAGE},
218 {"Unspecified failure", BatteryHealth::UNSPECIFIED_FAILURE},
219 {"Cold", BatteryHealth::COLD},
220 // battery health values from JEITA spec
221 {"Warm", BatteryHealth::GOOD},
222 {"Cool", BatteryHealth::GOOD},
223 {"Hot", BatteryHealth::OVERHEAT},
224 {"Calibration required", BatteryHealth::INCONSISTENT},
225 {NULL, BatteryHealth::UNKNOWN},
226 };
227
228 auto ret = mapSysfsString(status, batteryHealthMap);
229 if (!ret) {
230 KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
231 *ret = BatteryHealth::UNKNOWN;
232 }
233
234 return *ret;
235 }
236
getBatteryHealthStatus(int status)237 BatteryHealth getBatteryHealthStatus(int status) {
238 BatteryHealth value;
239
240 if (status == BatteryMonitor::BH_NOMINAL)
241 value = BatteryHealth::GOOD;
242 else if (status == BatteryMonitor::BH_MARGINAL)
243 value = BatteryHealth::FAIR;
244 else if (status == BatteryMonitor::BH_NEEDS_REPLACEMENT)
245 value = BatteryHealth::DEAD;
246 else if (status == BatteryMonitor::BH_FAILED)
247 value = BatteryHealth::UNSPECIFIED_FAILURE;
248 else if (status == BatteryMonitor::BH_NOT_AVAILABLE)
249 value = BatteryHealth::NOT_AVAILABLE;
250 else if (status == BatteryMonitor::BH_INCONSISTENT)
251 value = BatteryHealth::INCONSISTENT;
252 else
253 value = BatteryHealth::UNKNOWN;
254
255 return value;
256 }
257
getBatteryChargingPolicy(const char * chargingPolicy)258 BatteryChargingPolicy getBatteryChargingPolicy(const char* chargingPolicy) {
259 static SysfsStringEnumMap<BatteryChargingPolicy> batteryChargingPolicyMap[] = {
260 {"0", BatteryChargingPolicy::INVALID}, {"1", BatteryChargingPolicy::DEFAULT},
261 {"2", BatteryChargingPolicy::LONG_LIFE}, {"3", BatteryChargingPolicy::ADAPTIVE},
262 {NULL, BatteryChargingPolicy::DEFAULT},
263 };
264
265 auto ret = mapSysfsString(chargingPolicy, batteryChargingPolicyMap);
266 if (!ret) {
267 *ret = BatteryChargingPolicy::DEFAULT;
268 }
269
270 return *ret;
271 }
272
getBatteryChargingState(const char * chargingState)273 BatteryChargingState getBatteryChargingState(const char* chargingState) {
274 static SysfsStringEnumMap<BatteryChargingState> batteryChargingStateMap[] = {
275 {"0", BatteryChargingState::INVALID}, {"1", BatteryChargingState::NORMAL},
276 {"2", BatteryChargingState::TOO_COLD}, {"3", BatteryChargingState::TOO_HOT},
277 {"4", BatteryChargingState::LONG_LIFE}, {"5", BatteryChargingState::ADAPTIVE},
278 {NULL, BatteryChargingState::NORMAL},
279 };
280
281 auto ret = mapSysfsString(chargingState, batteryChargingStateMap);
282 if (!ret) {
283 *ret = BatteryChargingState::NORMAL;
284 }
285
286 return *ret;
287 }
288
readFromFile(const String8 & path,std::string * buf)289 static int readFromFile(const String8& path, std::string* buf) {
290 buf->clear();
291 if (android::base::ReadFileToString(path.c_str(), buf)) {
292 *buf = android::base::Trim(*buf);
293 }
294 return buf->length();
295 }
296
writeToFile(const String8 & path,int32_t in_value)297 static bool writeToFile(const String8& path, int32_t in_value) {
298 return android::base::WriteStringToFile(std::to_string(in_value), path.c_str());
299 }
300
readPowerSupplyType(const String8 & path)301 static BatteryMonitor::PowerSupplyType readPowerSupplyType(const String8& path) {
302 static SysfsStringEnumMap<int> supplyTypeMap[] = {
303 {"Unknown", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
304 {"Battery", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_BATTERY},
305 {"UPS", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
306 {"Mains", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
307 {"USB", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
308 {"USB_DCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
309 {"USB_HVDCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
310 {"USB_CDP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
311 {"USB_ACA", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
312 {"USB_C", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
313 {"USB_PD", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
314 {"USB_PD_DRP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
315 {"Wireless", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_WIRELESS},
316 {"Dock", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_DOCK},
317 {NULL, 0},
318 };
319 std::string buf;
320
321 if (readFromFile(path, &buf) <= 0) {
322 return BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
323 }
324
325 auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
326 if (!ret) {
327 KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
328 *ret = BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
329 }
330
331 return static_cast<BatteryMonitor::PowerSupplyType>(*ret);
332 }
333
getBooleanField(const String8 & path)334 static bool getBooleanField(const String8& path) {
335 std::string buf;
336 bool value = false;
337
338 if (readFromFile(path, &buf) > 0)
339 if (buf[0] != '0')
340 value = true;
341
342 return value;
343 }
344
345 template <typename T = int>
getIntField(const String8 & path)346 static T getIntField(const String8& path) {
347 std::string buf;
348 T value = 0;
349
350 if (readFromFile(path, &buf) > 0)
351 android::base::ParseInt(buf, &value);
352
353 return value;
354 }
355
isScopedPowerSupply(const char * name)356 static bool isScopedPowerSupply(const char* name) {
357 constexpr char kScopeDevice[] = "Device";
358
359 String8 path;
360 path.appendFormat("%s/%s/scope", POWER_SUPPLY_SYSFS_PATH, name);
361 std::string scope;
362 return (readFromFile(path, &scope) > 0 && scope == kScopeDevice);
363 }
364
ensureBatteryHealthData(HealthInfo * info)365 static BatteryHealthData *ensureBatteryHealthData(HealthInfo *info) {
366 if (!info->batteryHealthData.has_value()) {
367 return &info->batteryHealthData.emplace();
368 }
369
370 return &info->batteryHealthData.value();
371 }
372
updateValues(void)373 void BatteryMonitor::updateValues(void) {
374 initHealthInfo(mHealthInfo.get());
375
376 if (!mHealthdConfig->batteryPresentPath.empty())
377 mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
378 else
379 mHealthInfo->batteryPresent = mBatteryDevicePresent;
380
381 mHealthInfo->batteryLevel = mBatteryFixedCapacity
382 ? mBatteryFixedCapacity
383 : getIntField(mHealthdConfig->batteryCapacityPath);
384 mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
385
386 if (!mHealthdConfig->batteryCurrentNowPath.empty())
387 mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
388
389 if (!mHealthdConfig->batteryFullChargePath.empty())
390 mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
391
392 if (!mHealthdConfig->batteryCycleCountPath.empty())
393 mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
394
395 if (!mHealthdConfig->batteryChargeCounterPath.empty())
396 mHealthInfo->batteryChargeCounterUah =
397 getIntField(mHealthdConfig->batteryChargeCounterPath);
398
399 if (!mHealthdConfig->batteryCurrentAvgPath.empty())
400 mHealthInfo->batteryCurrentAverageMicroamps =
401 getIntField(mHealthdConfig->batteryCurrentAvgPath);
402
403 if (!mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
404 mHealthInfo->batteryChargeTimeToFullNowSeconds =
405 getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
406
407 if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
408 mHealthInfo->batteryFullChargeDesignCapacityUah =
409 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
410
411 if (!mHealthdConfig->batteryHealthStatusPath.empty())
412 mBatteryHealthStatus = getIntField(mHealthdConfig->batteryHealthStatusPath);
413
414 if (!mHealthdConfig->batteryStateOfHealthPath.empty())
415 ensureBatteryHealthData(mHealthInfo.get())->batteryStateOfHealth =
416 getIntField(mHealthdConfig->batteryStateOfHealthPath);
417
418 if (!mHealthdConfig->batteryManufacturingDatePath.empty())
419 ensureBatteryHealthData(mHealthInfo.get())->batteryManufacturingDateSeconds =
420 getIntField<int64_t>(mHealthdConfig->batteryManufacturingDatePath);
421
422 if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
423 ensureBatteryHealthData(mHealthInfo.get())->batteryFirstUsageSeconds =
424 getIntField<int64_t>(mHealthdConfig->batteryFirstUsageDatePath);
425
426 mHealthInfo->batteryTemperatureTenthsCelsius =
427 mBatteryFixedTemperature ? mBatteryFixedTemperature
428 : getIntField(mHealthdConfig->batteryTemperaturePath);
429
430 std::string buf;
431
432 if (readFromFile(mHealthdConfig->batteryCapacityLevelPath, &buf) > 0)
433 mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());
434
435 if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
436 mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str());
437
438 // Backward compatible with android.hardware.health V1
439 if (mBatteryHealthStatus < BatteryMonitor::BH_MARGINAL) {
440 if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
441 mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str());
442 } else {
443 mHealthInfo->batteryHealth = getBatteryHealthStatus(mBatteryHealthStatus);
444 }
445
446 if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
447 mHealthInfo->batteryTechnology = buf;
448
449 if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
450 mHealthInfo->chargingPolicy = getBatteryChargingPolicy(buf.c_str());
451
452 if (readFromFile(mHealthdConfig->chargingStatePath, &buf) > 0)
453 mHealthInfo->chargingState = getBatteryChargingState(buf.c_str());
454
455 double MaxPower = 0;
456
457 for (size_t i = 0; i < mChargerNames.size(); i++) {
458 String8 path;
459 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].c_str());
460 if (getIntField(path)) {
461 path.clear();
462 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].c_str());
463 switch(readPowerSupplyType(path)) {
464 case ANDROID_POWER_SUPPLY_TYPE_AC:
465 mHealthInfo->chargerAcOnline = true;
466 break;
467 case ANDROID_POWER_SUPPLY_TYPE_USB:
468 mHealthInfo->chargerUsbOnline = true;
469 break;
470 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
471 mHealthInfo->chargerWirelessOnline = true;
472 break;
473 case ANDROID_POWER_SUPPLY_TYPE_DOCK:
474 mHealthInfo->chargerDockOnline = true;
475 break;
476 default:
477 path.clear();
478 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH,
479 mChargerNames[i].c_str());
480 if (access(path.c_str(), R_OK) == 0)
481 mHealthInfo->chargerDockOnline = true;
482 else
483 KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
484 mChargerNames[i].c_str());
485 }
486 path.clear();
487 path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
488 mChargerNames[i].c_str());
489 int ChargingCurrent = (access(path.c_str(), R_OK) == 0) ? getIntField(path) : 0;
490
491 path.clear();
492 path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
493 mChargerNames[i].c_str());
494
495 int ChargingVoltage =
496 (access(path.c_str(), R_OK) == 0) ? getIntField(path) : DEFAULT_VBUS_VOLTAGE;
497
498 double power = ((double)ChargingCurrent / MILLION) *
499 ((double)ChargingVoltage / MILLION);
500 if (MaxPower < power) {
501 mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent;
502 mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage;
503 MaxPower = power;
504 }
505 }
506 }
507 }
508
doLogValues(const HealthInfo & props,const struct healthd_config & healthd_config)509 static void doLogValues(const HealthInfo& props, const struct healthd_config& healthd_config) {
510 char dmesgline[256];
511 size_t len;
512 if (props.batteryPresent) {
513 snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
514 props.batteryLevel, props.batteryVoltageMillivolts,
515 props.batteryTemperatureTenthsCelsius < 0 ? "-" : "",
516 abs(props.batteryTemperatureTenthsCelsius / 10),
517 abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth,
518 props.batteryStatus);
519
520 len = strlen(dmesgline);
521 if (!healthd_config.batteryCurrentNowPath.empty()) {
522 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
523 props.batteryCurrentMicroamps);
524 }
525
526 if (!healthd_config.batteryFullChargePath.empty()) {
527 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
528 props.batteryFullChargeUah);
529 }
530
531 if (!healthd_config.batteryCycleCountPath.empty()) {
532 len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
533 props.batteryCycleCount);
534 }
535 } else {
536 len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
537 }
538
539 snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s",
540 props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
541 props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : "");
542
543 KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
544 }
545
logValues(const HealthInfo_2_1 & health_info,const struct healthd_config & healthd_config)546 void BatteryMonitor::logValues(const HealthInfo_2_1& health_info,
547 const struct healthd_config& healthd_config) {
548 HealthInfo aidl_health_info;
549 (void)android::h2a::translate(health_info, &aidl_health_info);
550 doLogValues(aidl_health_info, healthd_config);
551 }
552
logValues(void)553 void BatteryMonitor::logValues(void) {
554 doLogValues(*mHealthInfo, *mHealthdConfig);
555 }
556
isChargerOnline()557 bool BatteryMonitor::isChargerOnline() {
558 const HealthInfo& props = *mHealthInfo;
559 return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline |
560 props.chargerDockOnline;
561 }
562
getChargeStatus()563 int BatteryMonitor::getChargeStatus() {
564 BatteryStatus result = BatteryStatus::UNKNOWN;
565 if (!mHealthdConfig->batteryStatusPath.empty()) {
566 std::string buf;
567 if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
568 result = getBatteryStatus(buf.c_str());
569 }
570 return static_cast<int>(result);
571 }
572
setChargingPolicy(int value)573 status_t BatteryMonitor::setChargingPolicy(int value) {
574 status_t ret = NAME_NOT_FOUND;
575 bool result;
576 if (!mHealthdConfig->chargingPolicyPath.empty()) {
577 result = writeToFile(mHealthdConfig->chargingPolicyPath, value);
578 if (!result) {
579 KLOG_WARNING(LOG_TAG, "setChargingPolicy fail\n");
580 ret = BAD_VALUE;
581 } else {
582 ret = OK;
583 }
584 }
585 return ret;
586 }
587
getChargingPolicy()588 int BatteryMonitor::getChargingPolicy() {
589 BatteryChargingPolicy result = BatteryChargingPolicy::DEFAULT;
590 if (!mHealthdConfig->chargingPolicyPath.empty()) {
591 std::string buf;
592 if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
593 result = getBatteryChargingPolicy(buf.c_str());
594 }
595 return static_cast<int>(result);
596 }
597
getBatteryHealthData(int id)598 int BatteryMonitor::getBatteryHealthData(int id) {
599 if (id == BATTERY_PROP_MANUFACTURING_DATE) {
600 if (!mHealthdConfig->batteryManufacturingDatePath.empty())
601 return getIntField(mHealthdConfig->batteryManufacturingDatePath);
602 }
603 if (id == BATTERY_PROP_FIRST_USAGE_DATE) {
604 if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
605 return getIntField(mHealthdConfig->batteryFirstUsageDatePath);
606 }
607 if (id == BATTERY_PROP_STATE_OF_HEALTH) {
608 if (!mHealthdConfig->batteryStateOfHealthPath.empty())
609 return getIntField(mHealthdConfig->batteryStateOfHealthPath);
610 }
611 if (id == BATTERY_PROP_PART_STATUS) {
612 return static_cast<int>(BatteryPartStatus::UNSUPPORTED);
613 }
614 return 0;
615 }
616
getProperty(int id,struct BatteryProperty * val)617 status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
618 status_t ret = BAD_VALUE;
619 std::string buf;
620
621 val->valueInt64 = LONG_MIN;
622
623 switch(id) {
624 case BATTERY_PROP_CHARGE_COUNTER:
625 if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
626 val->valueInt64 =
627 getIntField(mHealthdConfig->batteryChargeCounterPath);
628 ret = OK;
629 } else {
630 ret = NAME_NOT_FOUND;
631 }
632 break;
633
634 case BATTERY_PROP_CURRENT_NOW:
635 if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
636 val->valueInt64 =
637 getIntField(mHealthdConfig->batteryCurrentNowPath);
638 ret = OK;
639 } else {
640 ret = NAME_NOT_FOUND;
641 }
642 break;
643
644 case BATTERY_PROP_CURRENT_AVG:
645 if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
646 val->valueInt64 =
647 getIntField(mHealthdConfig->batteryCurrentAvgPath);
648 ret = OK;
649 } else {
650 ret = NAME_NOT_FOUND;
651 }
652 break;
653
654 case BATTERY_PROP_CAPACITY:
655 if (!mHealthdConfig->batteryCapacityPath.empty()) {
656 val->valueInt64 =
657 getIntField(mHealthdConfig->batteryCapacityPath);
658 ret = OK;
659 } else {
660 ret = NAME_NOT_FOUND;
661 }
662 break;
663
664 case BATTERY_PROP_ENERGY_COUNTER:
665 if (mHealthdConfig->energyCounter) {
666 ret = mHealthdConfig->energyCounter(&val->valueInt64);
667 } else {
668 ret = NAME_NOT_FOUND;
669 }
670 break;
671
672 case BATTERY_PROP_BATTERY_STATUS:
673 val->valueInt64 = getChargeStatus();
674 ret = OK;
675 break;
676
677 case BATTERY_PROP_CHARGING_POLICY:
678 val->valueInt64 = getChargingPolicy();
679 ret = OK;
680 break;
681
682 case BATTERY_PROP_MANUFACTURING_DATE:
683 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_MANUFACTURING_DATE);
684 ret = OK;
685 break;
686
687 case BATTERY_PROP_FIRST_USAGE_DATE:
688 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_FIRST_USAGE_DATE);
689 ret = OK;
690 break;
691
692 case BATTERY_PROP_STATE_OF_HEALTH:
693 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_STATE_OF_HEALTH);
694 ret = OK;
695 break;
696
697 case BATTERY_PROP_PART_STATUS:
698 val->valueInt64 = getBatteryHealthData(BATTERY_PROP_PART_STATUS);
699 ret = OK;
700 break;
701
702 default:
703 break;
704 }
705
706 return ret;
707 }
708
getSerialNumber(std::optional<std::string> * out)709 status_t BatteryMonitor::getSerialNumber(std::optional<std::string>* out) {
710 *out = std::nullopt;
711 return OK;
712 }
713
dumpState(int fd)714 void BatteryMonitor::dumpState(int fd) {
715 int v;
716 char vs[128];
717 const HealthInfo& props = *mHealthInfo;
718
719 snprintf(vs, sizeof(vs), "Cached HealthInfo:\n");
720 write(fd, vs, strlen(vs));
721 snprintf(vs, sizeof(vs),
722 " ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n",
723 props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline,
724 props.chargerDockOnline, props.maxChargingCurrentMicroamps,
725 props.maxChargingVoltageMicrovolts);
726 write(fd, vs, strlen(vs));
727 snprintf(vs, sizeof(vs), " status: %d health: %d present: %d\n",
728 props.batteryStatus, props.batteryHealth, props.batteryPresent);
729 write(fd, vs, strlen(vs));
730 snprintf(vs, sizeof(vs), " level: %d voltage: %d temp: %d\n", props.batteryLevel,
731 props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
732 write(fd, vs, strlen(vs));
733
734 if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
735 snprintf(vs, sizeof(vs), " current now: %d\n", props.batteryCurrentMicroamps);
736 write(fd, vs, strlen(vs));
737 }
738
739 if (!mHealthdConfig->batteryCycleCountPath.empty()) {
740 snprintf(vs, sizeof(vs), " cycle count: %d\n", props.batteryCycleCount);
741 write(fd, vs, strlen(vs));
742 }
743
744 if (!mHealthdConfig->batteryFullChargePath.empty()) {
745 snprintf(vs, sizeof(vs), " Full charge: %d\n", props.batteryFullChargeUah);
746 write(fd, vs, strlen(vs));
747 }
748
749 snprintf(vs, sizeof(vs), "Real-time Values:\n");
750 write(fd, vs, strlen(vs));
751
752 if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
753 v = getIntField(mHealthdConfig->batteryCurrentNowPath);
754 snprintf(vs, sizeof(vs), " current now: %d\n", v);
755 write(fd, vs, strlen(vs));
756 }
757
758 if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
759 v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
760 snprintf(vs, sizeof(vs), " current avg: %d\n", v);
761 write(fd, vs, strlen(vs));
762 }
763
764 if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
765 v = getIntField(mHealthdConfig->batteryChargeCounterPath);
766 snprintf(vs, sizeof(vs), " charge counter: %d\n", v);
767 write(fd, vs, strlen(vs));
768 }
769 }
770
init(struct healthd_config * hc)771 void BatteryMonitor::init(struct healthd_config *hc) {
772 String8 path;
773 char pval[PROPERTY_VALUE_MAX];
774
775 mHealthdConfig = hc;
776 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
777 if (dir == NULL) {
778 KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
779 } else {
780 struct dirent* entry;
781
782 while ((entry = readdir(dir.get()))) {
783 const char* name = entry->d_name;
784
785 if (!strcmp(name, ".") || !strcmp(name, ".."))
786 continue;
787
788 std::vector<String8>::iterator itIgnoreName =
789 find(hc->ignorePowerSupplyNames.begin(), hc->ignorePowerSupplyNames.end(),
790 String8(name));
791 if (itIgnoreName != hc->ignorePowerSupplyNames.end())
792 continue;
793
794 // Look for "type" file in each subdirectory
795 path.clear();
796 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
797 switch(readPowerSupplyType(path)) {
798 case ANDROID_POWER_SUPPLY_TYPE_AC:
799 case ANDROID_POWER_SUPPLY_TYPE_USB:
800 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
801 case ANDROID_POWER_SUPPLY_TYPE_DOCK:
802 path.clear();
803 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
804 if (access(path.c_str(), R_OK) == 0) mChargerNames.add(String8(name));
805 break;
806
807 case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
808 // Some devices expose the battery status of sub-component like
809 // stylus. Such a device-scoped battery info needs to be skipped
810 // in BatteryMonitor, which is intended to report the status of
811 // the battery supplying the power to the whole system.
812 if (isScopedPowerSupply(name)) continue;
813 mBatteryDevicePresent = true;
814
815 if (mHealthdConfig->batteryStatusPath.empty()) {
816 path.clear();
817 path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
818 name);
819 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryStatusPath = path;
820 }
821
822 if (mHealthdConfig->batteryHealthPath.empty()) {
823 path.clear();
824 path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
825 name);
826 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryHealthPath = path;
827 }
828
829 if (mHealthdConfig->batteryPresentPath.empty()) {
830 path.clear();
831 path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
832 name);
833 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryPresentPath = path;
834 }
835
836 if (mHealthdConfig->batteryCapacityPath.empty()) {
837 path.clear();
838 path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
839 name);
840 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryCapacityPath = path;
841 }
842
843 if (mHealthdConfig->batteryVoltagePath.empty()) {
844 path.clear();
845 path.appendFormat("%s/%s/voltage_now",
846 POWER_SUPPLY_SYSFS_PATH, name);
847 if (access(path.c_str(), R_OK) == 0) {
848 mHealthdConfig->batteryVoltagePath = path;
849 }
850 }
851
852 if (mHealthdConfig->batteryFullChargePath.empty()) {
853 path.clear();
854 path.appendFormat("%s/%s/charge_full",
855 POWER_SUPPLY_SYSFS_PATH, name);
856 if (access(path.c_str(), R_OK) == 0)
857 mHealthdConfig->batteryFullChargePath = path;
858 }
859
860 if (mHealthdConfig->batteryCurrentNowPath.empty()) {
861 path.clear();
862 path.appendFormat("%s/%s/current_now",
863 POWER_SUPPLY_SYSFS_PATH, name);
864 if (access(path.c_str(), R_OK) == 0)
865 mHealthdConfig->batteryCurrentNowPath = path;
866 }
867
868 if (mHealthdConfig->batteryCycleCountPath.empty()) {
869 path.clear();
870 path.appendFormat("%s/%s/cycle_count",
871 POWER_SUPPLY_SYSFS_PATH, name);
872 if (access(path.c_str(), R_OK) == 0)
873 mHealthdConfig->batteryCycleCountPath = path;
874 }
875
876 if (mHealthdConfig->batteryCapacityLevelPath.empty()) {
877 path.clear();
878 path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
879 if (access(path.c_str(), R_OK) == 0) {
880 mHealthdConfig->batteryCapacityLevelPath = path;
881 }
882 }
883
884 if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty()) {
885 path.clear();
886 path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
887 if (access(path.c_str(), R_OK) == 0)
888 mHealthdConfig->batteryChargeTimeToFullNowPath = path;
889 }
890
891 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty()) {
892 path.clear();
893 path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
894 if (access(path.c_str(), R_OK) == 0)
895 mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
896 }
897
898 if (mHealthdConfig->batteryCurrentAvgPath.empty()) {
899 path.clear();
900 path.appendFormat("%s/%s/current_avg",
901 POWER_SUPPLY_SYSFS_PATH, name);
902 if (access(path.c_str(), R_OK) == 0)
903 mHealthdConfig->batteryCurrentAvgPath = path;
904 }
905
906 if (mHealthdConfig->batteryChargeCounterPath.empty()) {
907 path.clear();
908 path.appendFormat("%s/%s/charge_counter",
909 POWER_SUPPLY_SYSFS_PATH, name);
910 if (access(path.c_str(), R_OK) == 0)
911 mHealthdConfig->batteryChargeCounterPath = path;
912 }
913
914 if (mHealthdConfig->batteryTemperaturePath.empty()) {
915 path.clear();
916 path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
917 name);
918 if (access(path.c_str(), R_OK) == 0) {
919 mHealthdConfig->batteryTemperaturePath = path;
920 }
921 }
922
923 if (mHealthdConfig->batteryTechnologyPath.empty()) {
924 path.clear();
925 path.appendFormat("%s/%s/technology",
926 POWER_SUPPLY_SYSFS_PATH, name);
927 if (access(path.c_str(), R_OK) == 0)
928 mHealthdConfig->batteryTechnologyPath = path;
929 }
930
931 if (mHealthdConfig->batteryStateOfHealthPath.empty()) {
932 path.clear();
933 path.appendFormat("%s/%s/state_of_health", POWER_SUPPLY_SYSFS_PATH, name);
934 if (access(path.c_str(), R_OK) == 0) {
935 mHealthdConfig->batteryStateOfHealthPath = path;
936 } else {
937 path.clear();
938 path.appendFormat("%s/%s/health_index", POWER_SUPPLY_SYSFS_PATH, name);
939 if (access(path.c_str(), R_OK) == 0)
940 mHealthdConfig->batteryStateOfHealthPath = path;
941 }
942 }
943
944 if (mHealthdConfig->batteryHealthStatusPath.empty()) {
945 path.clear();
946 path.appendFormat("%s/%s/health_status", POWER_SUPPLY_SYSFS_PATH, name);
947 if (access(path.c_str(), R_OK) == 0) {
948 mHealthdConfig->batteryHealthStatusPath = path;
949 }
950 }
951
952 if (mHealthdConfig->batteryManufacturingDatePath.empty()) {
953 path.clear();
954 path.appendFormat("%s/%s/manufacturing_date", POWER_SUPPLY_SYSFS_PATH, name);
955 if (access(path.c_str(), R_OK) == 0)
956 mHealthdConfig->batteryManufacturingDatePath = path;
957 }
958
959 if (mHealthdConfig->batteryFirstUsageDatePath.empty()) {
960 path.clear();
961 path.appendFormat("%s/%s/first_usage_date", POWER_SUPPLY_SYSFS_PATH, name);
962 if (access(path.c_str(), R_OK) == 0) {
963 mHealthdConfig->batteryFirstUsageDatePath = path;
964 }
965 }
966
967 if (mHealthdConfig->chargingStatePath.empty()) {
968 path.clear();
969 path.appendFormat("%s/%s/charging_state", POWER_SUPPLY_SYSFS_PATH, name);
970 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingStatePath = path;
971 }
972
973 if (mHealthdConfig->chargingPolicyPath.empty()) {
974 path.clear();
975 path.appendFormat("%s/%s/charging_policy", POWER_SUPPLY_SYSFS_PATH, name);
976 if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingPolicyPath = path;
977 }
978
979 break;
980
981 case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
982 break;
983 }
984
985 // Look for "is_dock" file
986 path.clear();
987 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, name);
988 if (access(path.c_str(), R_OK) == 0) {
989 path.clear();
990 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
991 if (access(path.c_str(), R_OK) == 0) mChargerNames.add(String8(name));
992 }
993 }
994 }
995
996 // Typically the case for devices which do not have a battery and
997 // and are always plugged into AC mains.
998 if (!mBatteryDevicePresent) {
999 KLOG_WARNING(LOG_TAG, "No battery devices found\n");
1000 hc->periodic_chores_interval_fast = -1;
1001 hc->periodic_chores_interval_slow = -1;
1002 } else {
1003 if (mHealthdConfig->batteryStatusPath.empty())
1004 KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
1005 if (mHealthdConfig->batteryHealthPath.empty())
1006 KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
1007 if (mHealthdConfig->batteryPresentPath.empty())
1008 KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
1009 if (mHealthdConfig->batteryCapacityPath.empty())
1010 KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
1011 if (mHealthdConfig->batteryVoltagePath.empty())
1012 KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
1013 if (mHealthdConfig->batteryTemperaturePath.empty())
1014 KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
1015 if (mHealthdConfig->batteryTechnologyPath.empty())
1016 KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
1017 if (mHealthdConfig->batteryCurrentNowPath.empty())
1018 KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
1019 if (mHealthdConfig->batteryFullChargePath.empty())
1020 KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
1021 if (mHealthdConfig->batteryCycleCountPath.empty())
1022 KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
1023 if (mHealthdConfig->batteryCapacityLevelPath.empty())
1024 KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
1025 if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
1026 KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
1027 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
1028 KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
1029 if (mHealthdConfig->batteryStateOfHealthPath.empty())
1030 KLOG_WARNING(LOG_TAG, "batteryStateOfHealthPath not found\n");
1031 if (mHealthdConfig->batteryHealthStatusPath.empty())
1032 KLOG_WARNING(LOG_TAG, "batteryHealthStatusPath not found\n");
1033 if (mHealthdConfig->batteryManufacturingDatePath.empty())
1034 KLOG_WARNING(LOG_TAG, "batteryManufacturingDatePath not found\n");
1035 if (mHealthdConfig->batteryFirstUsageDatePath.empty())
1036 KLOG_WARNING(LOG_TAG, "batteryFirstUsageDatePath not found\n");
1037 if (mHealthdConfig->chargingStatePath.empty())
1038 KLOG_WARNING(LOG_TAG, "chargingStatePath not found\n");
1039 if (mHealthdConfig->chargingPolicyPath.empty())
1040 KLOG_WARNING(LOG_TAG, "chargingPolicyPath not found\n");
1041 }
1042
1043 if (property_get("ro.boot.fake_battery", pval, NULL) > 0
1044 && strtol(pval, NULL, 10) != 0) {
1045 mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
1046 mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
1047 }
1048 }
1049
1050 }; // namespace android
1051