xref: /aosp_15_r20/system/core/healthd/BatteryMonitor.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
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     };
135 }
136 
BatteryMonitor()137 BatteryMonitor::BatteryMonitor()
138     : mHealthdConfig(nullptr),
139       mBatteryDevicePresent(false),
140       mBatteryFixedCapacity(0),
141       mBatteryFixedTemperature(0),
142       mBatteryHealthStatus(BatteryMonitor::BH_UNKNOWN),
143       mHealthInfo(std::make_unique<HealthInfo>()) {
144     initHealthInfo(mHealthInfo.get());
145 }
146 
~BatteryMonitor()147 BatteryMonitor::~BatteryMonitor() {}
148 
getHealthInfo_1_0() const149 HealthInfo_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;
153 }
154 
getHealthInfo_2_0() const155 HealthInfo_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;
159 }
160 
getHealthInfo_2_1() const161 HealthInfo_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 
getHealthInfo() const167 const HealthInfo& BatteryMonitor::getHealthInfo() const {
168     return *mHealthInfo;
169 }
170 
getBatteryStatus(const char * status)171 BatteryStatus 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},
179     };
180 
181     auto ret = mapSysfsString(status, batteryStatusMap);
182     if (!ret) {
183         KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
184         *ret = BatteryStatus::UNKNOWN;
185     }
186 
187     return *ret;
188 }
189 
getBatteryCapacityLevel(const char * capacityLevel)190 BatteryCapacityLevel 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},
198             {NULL, BatteryCapacityLevel::UNSUPPORTED},
199     };
200 
201     auto ret = mapSysfsString(capacityLevel, batteryCapacityLevelMap);
202     if (!ret) {
203         KLOG_WARNING(LOG_TAG, "Unsupported battery capacity level '%s'\n", capacityLevel);
204         *ret = BatteryCapacityLevel::UNSUPPORTED;
205     }
206 
207     return *ret;
208 }
209 
getBatteryHealth(const char * status)210 BatteryHealth 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},
223             {"Calibration required", BatteryHealth::INCONSISTENT},
224             {NULL, BatteryHealth::UNKNOWN},
225     };
226 
227     auto ret = mapSysfsString(status, batteryHealthMap);
228     if (!ret) {
229         KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
230         *ret = BatteryHealth::UNKNOWN;
231     }
232 
233     return *ret;
234 }
235 
getBatteryHealthStatus(int status)236 BatteryHealth 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;
247     else if (status == BatteryMonitor::BH_NOT_AVAILABLE)
248         value = BatteryHealth::NOT_AVAILABLE;
249     else if (status == BatteryMonitor::BH_INCONSISTENT)
250         value = BatteryHealth::INCONSISTENT;
251     else
252         value = BatteryHealth::UNKNOWN;
253 
254     return value;
255 }
256 
getBatteryChargingPolicy(const char * chargingPolicy)257 BatteryChargingPolicy 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 
getBatteryChargingState(const char * chargingState)272 BatteryChargingState 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 
readFromFile(const String8 & path,std::string * buf)288 static int readFromFile(const String8& path, std::string* buf) {
289     buf->clear();
290     if (android::base::ReadFileToString(path.c_str(), buf)) {
291         *buf = android::base::Trim(*buf);
292     }
293     return buf->length();
294 }
295 
writeToFile(const String8 & path,int32_t in_value)296 static bool writeToFile(const String8& path, int32_t in_value) {
297     return android::base::WriteStringToFile(std::to_string(in_value), path.c_str());
298 }
299 
readPowerSupplyType(const String8 & path)300 static BatteryMonitor::PowerSupplyType readPowerSupplyType(const String8& path) {
301     static SysfsStringEnumMap<int> supplyTypeMap[] = {
302             {"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},
316             {NULL, 0},
317     };
318     std::string buf;
319 
320     if (readFromFile(path, &buf) <= 0) {
321         return BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
322     }
323 
324     auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
325     if (!ret) {
326         KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
327         *ret = BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
328     }
329 
330     return static_cast<BatteryMonitor::PowerSupplyType>(*ret);
331 }
332 
getBooleanField(const String8 & path)333 static bool getBooleanField(const String8& path) {
334     std::string buf;
335     bool value = false;
336 
337     if (readFromFile(path, &buf) > 0)
338         if (buf[0] != '0')
339             value = true;
340 
341     return value;
342 }
343 
getIntField(const String8 & path)344 static int getIntField(const String8& path) {
345     std::string buf;
346     int value = 0;
347 
348     if (readFromFile(path, &buf) > 0)
349         android::base::ParseInt(buf, &value);
350 
351     return value;
352 }
353 
isScopedPowerSupply(const char * name)354 static bool isScopedPowerSupply(const char* name) {
355     constexpr char kScopeDevice[] = "Device";
356 
357     String8 path;
358     path.appendFormat("%s/%s/scope", POWER_SUPPLY_SYSFS_PATH, name);
359     std::string scope;
360     return (readFromFile(path, &scope) > 0 && scope == kScopeDevice);
361 }
362 
updateValues(void)363 void BatteryMonitor::updateValues(void) {
364     initHealthInfo(mHealthInfo.get());
365 
366     if (!mHealthdConfig->batteryPresentPath.empty())
367         mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
368     else
369         mHealthInfo->batteryPresent = mBatteryDevicePresent;
370 
371     mHealthInfo->batteryLevel = mBatteryFixedCapacity
372                                         ? mBatteryFixedCapacity
373                                         : getIntField(mHealthdConfig->batteryCapacityPath);
374     mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
375 
376     if (!mHealthdConfig->batteryCurrentNowPath.empty())
377         mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
378 
379     if (!mHealthdConfig->batteryFullChargePath.empty())
380         mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
381 
382     if (!mHealthdConfig->batteryCycleCountPath.empty())
383         mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
384 
385     if (!mHealthdConfig->batteryChargeCounterPath.empty())
386         mHealthInfo->batteryChargeCounterUah =
387                 getIntField(mHealthdConfig->batteryChargeCounterPath);
388 
389     if (!mHealthdConfig->batteryCurrentAvgPath.empty())
390         mHealthInfo->batteryCurrentAverageMicroamps =
391                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
392 
393     if (!mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
394         mHealthInfo->batteryChargeTimeToFullNowSeconds =
395                 getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
396 
397     if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
398         mHealthInfo->batteryFullChargeDesignCapacityUah =
399                 getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
400 
401     if (!mHealthdConfig->batteryHealthStatusPath.empty())
402         mBatteryHealthStatus = getIntField(mHealthdConfig->batteryHealthStatusPath);
403 
404     if (!mHealthdConfig->batteryStateOfHealthPath.empty())
405         mHealthInfo->batteryHealthData->batteryStateOfHealth =
406                 getIntField(mHealthdConfig->batteryStateOfHealthPath);
407 
408     if (!mHealthdConfig->batteryManufacturingDatePath.empty())
409         mHealthInfo->batteryHealthData->batteryManufacturingDateSeconds =
410                 getIntField(mHealthdConfig->batteryManufacturingDatePath);
411 
412     if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
413         mHealthInfo->batteryHealthData->batteryFirstUsageSeconds =
414                 getIntField(mHealthdConfig->batteryFirstUsageDatePath);
415 
416     mHealthInfo->batteryTemperatureTenthsCelsius =
417             mBatteryFixedTemperature ? mBatteryFixedTemperature
418                                      : getIntField(mHealthdConfig->batteryTemperaturePath);
419 
420     std::string buf;
421 
422     if (readFromFile(mHealthdConfig->batteryCapacityLevelPath, &buf) > 0)
423         mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());
424 
425     if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
426         mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str());
427 
428     // Backward compatible with android.hardware.health V1
429     if (mBatteryHealthStatus < BatteryMonitor::BH_MARGINAL) {
430         if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
431             mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str());
432     } else {
433         mHealthInfo->batteryHealth = getBatteryHealthStatus(mBatteryHealthStatus);
434     }
435 
436     if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
437         mHealthInfo->batteryTechnology = buf;
438 
439     if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
440         mHealthInfo->chargingPolicy = getBatteryChargingPolicy(buf.c_str());
441 
442     if (readFromFile(mHealthdConfig->chargingStatePath, &buf) > 0)
443         mHealthInfo->chargingState = getBatteryChargingState(buf.c_str());
444 
445     double MaxPower = 0;
446 
447     for (size_t i = 0; i < mChargerNames.size(); i++) {
448         String8 path;
449         path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].c_str());
450         if (getIntField(path)) {
451             path.clear();
452             path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].c_str());
453             switch(readPowerSupplyType(path)) {
454             case ANDROID_POWER_SUPPLY_TYPE_AC:
455                 mHealthInfo->chargerAcOnline = true;
456                 break;
457             case ANDROID_POWER_SUPPLY_TYPE_USB:
458                 mHealthInfo->chargerUsbOnline = true;
459                 break;
460             case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
461                 mHealthInfo->chargerWirelessOnline = true;
462                 break;
463             case ANDROID_POWER_SUPPLY_TYPE_DOCK:
464                 mHealthInfo->chargerDockOnline = true;
465                 break;
466             default:
467                 path.clear();
468                 path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH,
469                                   mChargerNames[i].c_str());
470                 if (access(path.c_str(), R_OK) == 0)
471                     mHealthInfo->chargerDockOnline = true;
472                 else
473                     KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
474                                  mChargerNames[i].c_str());
475             }
476             path.clear();
477             path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
478                               mChargerNames[i].c_str());
479             int ChargingCurrent = (access(path.c_str(), R_OK) == 0) ? getIntField(path) : 0;
480 
481             path.clear();
482             path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
483                               mChargerNames[i].c_str());
484 
485             int ChargingVoltage =
486                     (access(path.c_str(), R_OK) == 0) ? getIntField(path) : DEFAULT_VBUS_VOLTAGE;
487 
488             double power = ((double)ChargingCurrent / MILLION) *
489                            ((double)ChargingVoltage / MILLION);
490             if (MaxPower < power) {
491                 mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent;
492                 mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage;
493                 MaxPower = power;
494             }
495         }
496     }
497 }
498 
doLogValues(const HealthInfo & props,const struct healthd_config & healthd_config)499 static void doLogValues(const HealthInfo& props, const struct healthd_config& healthd_config) {
500     char dmesgline[256];
501     size_t len;
502     if (props.batteryPresent) {
503         snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
504                  props.batteryLevel, props.batteryVoltageMillivolts,
505                  props.batteryTemperatureTenthsCelsius < 0 ? "-" : "",
506                  abs(props.batteryTemperatureTenthsCelsius / 10),
507                  abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth,
508                  props.batteryStatus);
509 
510         len = strlen(dmesgline);
511         if (!healthd_config.batteryCurrentNowPath.empty()) {
512             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
513                             props.batteryCurrentMicroamps);
514         }
515 
516         if (!healthd_config.batteryFullChargePath.empty()) {
517             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
518                             props.batteryFullChargeUah);
519         }
520 
521         if (!healthd_config.batteryCycleCountPath.empty()) {
522             len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
523                             props.batteryCycleCount);
524         }
525     } else {
526         len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
527     }
528 
529     snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s",
530              props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
531              props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : "");
532 
533     KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
534 }
535 
logValues(const HealthInfo_2_1 & health_info,const struct healthd_config & healthd_config)536 void BatteryMonitor::logValues(const HealthInfo_2_1& health_info,
537                                const struct healthd_config& healthd_config) {
538     HealthInfo aidl_health_info;
539     (void)android::h2a::translate(health_info, &aidl_health_info);
540     doLogValues(aidl_health_info, healthd_config);
541 }
542 
logValues(void)543 void BatteryMonitor::logValues(void) {
544     doLogValues(*mHealthInfo, *mHealthdConfig);
545 }
546 
isChargerOnline()547 bool BatteryMonitor::isChargerOnline() {
548     const HealthInfo& props = *mHealthInfo;
549     return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline |
550            props.chargerDockOnline;
551 }
552 
getChargeStatus()553 int BatteryMonitor::getChargeStatus() {
554     BatteryStatus result = BatteryStatus::UNKNOWN;
555     if (!mHealthdConfig->batteryStatusPath.empty()) {
556         std::string buf;
557         if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
558             result = getBatteryStatus(buf.c_str());
559     }
560     return static_cast<int>(result);
561 }
562 
setChargingPolicy(int value)563 status_t BatteryMonitor::setChargingPolicy(int value) {
564     status_t ret = NAME_NOT_FOUND;
565     bool result;
566     if (!mHealthdConfig->chargingPolicyPath.empty()) {
567         result = writeToFile(mHealthdConfig->chargingPolicyPath, value);
568         if (!result) {
569             KLOG_WARNING(LOG_TAG, "setChargingPolicy fail\n");
570             ret = BAD_VALUE;
571         } else {
572             ret = OK;
573         }
574     }
575     return ret;
576 }
577 
getChargingPolicy()578 int BatteryMonitor::getChargingPolicy() {
579     BatteryChargingPolicy result = BatteryChargingPolicy::DEFAULT;
580     if (!mHealthdConfig->chargingPolicyPath.empty()) {
581         std::string buf;
582         if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
583             result = getBatteryChargingPolicy(buf.c_str());
584     }
585     return static_cast<int>(result);
586 }
587 
getBatteryHealthData(int id)588 int BatteryMonitor::getBatteryHealthData(int id) {
589     if (id == BATTERY_PROP_MANUFACTURING_DATE) {
590         if (!mHealthdConfig->batteryManufacturingDatePath.empty())
591             return getIntField(mHealthdConfig->batteryManufacturingDatePath);
592     }
593     if (id == BATTERY_PROP_FIRST_USAGE_DATE) {
594         if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
595             return getIntField(mHealthdConfig->batteryFirstUsageDatePath);
596     }
597     if (id == BATTERY_PROP_STATE_OF_HEALTH) {
598         if (!mHealthdConfig->batteryStateOfHealthPath.empty())
599             return getIntField(mHealthdConfig->batteryStateOfHealthPath);
600     }
601     if (id == BATTERY_PROP_PART_STATUS) {
602         return static_cast<int>(BatteryPartStatus::UNSUPPORTED);
603     }
604     return 0;
605 }
606 
getProperty(int id,struct BatteryProperty * val)607 status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
608     status_t ret = BAD_VALUE;
609     std::string buf;
610 
611     val->valueInt64 = LONG_MIN;
612 
613     switch(id) {
614     case BATTERY_PROP_CHARGE_COUNTER:
615         if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
616             val->valueInt64 =
617                 getIntField(mHealthdConfig->batteryChargeCounterPath);
618             ret = OK;
619         } else {
620             ret = NAME_NOT_FOUND;
621         }
622         break;
623 
624     case BATTERY_PROP_CURRENT_NOW:
625         if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
626             val->valueInt64 =
627                 getIntField(mHealthdConfig->batteryCurrentNowPath);
628             ret = OK;
629         } else {
630             ret = NAME_NOT_FOUND;
631         }
632         break;
633 
634     case BATTERY_PROP_CURRENT_AVG:
635         if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
636             val->valueInt64 =
637                 getIntField(mHealthdConfig->batteryCurrentAvgPath);
638             ret = OK;
639         } else {
640             ret = NAME_NOT_FOUND;
641         }
642         break;
643 
644     case BATTERY_PROP_CAPACITY:
645         if (!mHealthdConfig->batteryCapacityPath.empty()) {
646             val->valueInt64 =
647                 getIntField(mHealthdConfig->batteryCapacityPath);
648             ret = OK;
649         } else {
650             ret = NAME_NOT_FOUND;
651         }
652         break;
653 
654     case BATTERY_PROP_ENERGY_COUNTER:
655         if (mHealthdConfig->energyCounter) {
656             ret = mHealthdConfig->energyCounter(&val->valueInt64);
657         } else {
658             ret = NAME_NOT_FOUND;
659         }
660         break;
661 
662     case BATTERY_PROP_BATTERY_STATUS:
663         val->valueInt64 = getChargeStatus();
664         ret = OK;
665         break;
666 
667     case BATTERY_PROP_CHARGING_POLICY:
668         val->valueInt64 = getChargingPolicy();
669         ret = OK;
670         break;
671 
672     case BATTERY_PROP_MANUFACTURING_DATE:
673         val->valueInt64 = getBatteryHealthData(BATTERY_PROP_MANUFACTURING_DATE);
674         ret = OK;
675         break;
676 
677     case BATTERY_PROP_FIRST_USAGE_DATE:
678         val->valueInt64 = getBatteryHealthData(BATTERY_PROP_FIRST_USAGE_DATE);
679         ret = OK;
680         break;
681 
682     case BATTERY_PROP_STATE_OF_HEALTH:
683         val->valueInt64 = getBatteryHealthData(BATTERY_PROP_STATE_OF_HEALTH);
684         ret = OK;
685         break;
686 
687     case BATTERY_PROP_PART_STATUS:
688         val->valueInt64 = getBatteryHealthData(BATTERY_PROP_PART_STATUS);
689         ret = OK;
690         break;
691 
692     default:
693         break;
694     }
695 
696     return ret;
697 }
698 
getSerialNumber(std::optional<std::string> * out)699 status_t BatteryMonitor::getSerialNumber(std::optional<std::string>* out) {
700     *out = std::nullopt;
701     return OK;
702 }
703 
dumpState(int fd)704 void BatteryMonitor::dumpState(int fd) {
705     int v;
706     char vs[128];
707     const HealthInfo& props = *mHealthInfo;
708 
709     snprintf(vs, sizeof(vs),
710              "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n",
711              props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline,
712              props.chargerDockOnline, props.maxChargingCurrentMicroamps,
713              props.maxChargingVoltageMicrovolts);
714     write(fd, vs, strlen(vs));
715     snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
716              props.batteryStatus, props.batteryHealth, props.batteryPresent);
717     write(fd, vs, strlen(vs));
718     snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel,
719              props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
720     write(fd, vs, strlen(vs));
721 
722     if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
723         v = getIntField(mHealthdConfig->batteryCurrentNowPath);
724         snprintf(vs, sizeof(vs), "current now: %d\n", v);
725         write(fd, vs, strlen(vs));
726     }
727 
728     if (!mHealthdConfig->batteryCurrentAvgPath.empty()) {
729         v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
730         snprintf(vs, sizeof(vs), "current avg: %d\n", v);
731         write(fd, vs, strlen(vs));
732     }
733 
734     if (!mHealthdConfig->batteryChargeCounterPath.empty()) {
735         v = getIntField(mHealthdConfig->batteryChargeCounterPath);
736         snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
737         write(fd, vs, strlen(vs));
738     }
739 
740     if (!mHealthdConfig->batteryCurrentNowPath.empty()) {
741         snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps);
742         write(fd, vs, strlen(vs));
743     }
744 
745     if (!mHealthdConfig->batteryCycleCountPath.empty()) {
746         snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
747         write(fd, vs, strlen(vs));
748     }
749 
750     if (!mHealthdConfig->batteryFullChargePath.empty()) {
751         snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah);
752         write(fd, vs, strlen(vs));
753     }
754 }
755 
init(struct healthd_config * hc)756 void BatteryMonitor::init(struct healthd_config *hc) {
757     String8 path;
758     char pval[PROPERTY_VALUE_MAX];
759 
760     mHealthdConfig = hc;
761     std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
762     if (dir == NULL) {
763         KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
764     } else {
765         struct dirent* entry;
766 
767         while ((entry = readdir(dir.get()))) {
768             const char* name = entry->d_name;
769 
770             if (!strcmp(name, ".") || !strcmp(name, ".."))
771                 continue;
772 
773             std::vector<String8>::iterator itIgnoreName =
774                     find(hc->ignorePowerSupplyNames.begin(), hc->ignorePowerSupplyNames.end(),
775                          String8(name));
776             if (itIgnoreName != hc->ignorePowerSupplyNames.end())
777                 continue;
778 
779             // Look for "type" file in each subdirectory
780             path.clear();
781             path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
782             switch(readPowerSupplyType(path)) {
783             case ANDROID_POWER_SUPPLY_TYPE_AC:
784             case ANDROID_POWER_SUPPLY_TYPE_USB:
785             case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
786             case ANDROID_POWER_SUPPLY_TYPE_DOCK:
787                 path.clear();
788                 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
789                 if (access(path.c_str(), R_OK) == 0) mChargerNames.add(String8(name));
790                 break;
791 
792             case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
793                 // Some devices expose the battery status of sub-component like
794                 // stylus. Such a device-scoped battery info needs to be skipped
795                 // in BatteryMonitor, which is intended to report the status of
796                 // the battery supplying the power to the whole system.
797                 if (isScopedPowerSupply(name)) continue;
798                 mBatteryDevicePresent = true;
799 
800                 if (mHealthdConfig->batteryStatusPath.empty()) {
801                     path.clear();
802                     path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
803                                       name);
804                     if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryStatusPath = path;
805                 }
806 
807                 if (mHealthdConfig->batteryHealthPath.empty()) {
808                     path.clear();
809                     path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
810                                       name);
811                     if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryHealthPath = path;
812                 }
813 
814                 if (mHealthdConfig->batteryPresentPath.empty()) {
815                     path.clear();
816                     path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
817                                       name);
818                     if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryPresentPath = path;
819                 }
820 
821                 if (mHealthdConfig->batteryCapacityPath.empty()) {
822                     path.clear();
823                     path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
824                                       name);
825                     if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batteryCapacityPath = path;
826                 }
827 
828                 if (mHealthdConfig->batteryVoltagePath.empty()) {
829                     path.clear();
830                     path.appendFormat("%s/%s/voltage_now",
831                                       POWER_SUPPLY_SYSFS_PATH, name);
832                     if (access(path.c_str(), R_OK) == 0) {
833                         mHealthdConfig->batteryVoltagePath = path;
834                     }
835                 }
836 
837                 if (mHealthdConfig->batteryFullChargePath.empty()) {
838                     path.clear();
839                     path.appendFormat("%s/%s/charge_full",
840                                       POWER_SUPPLY_SYSFS_PATH, name);
841                     if (access(path.c_str(), R_OK) == 0)
842                         mHealthdConfig->batteryFullChargePath = path;
843                 }
844 
845                 if (mHealthdConfig->batteryCurrentNowPath.empty()) {
846                     path.clear();
847                     path.appendFormat("%s/%s/current_now",
848                                       POWER_SUPPLY_SYSFS_PATH, name);
849                     if (access(path.c_str(), R_OK) == 0)
850                         mHealthdConfig->batteryCurrentNowPath = path;
851                 }
852 
853                 if (mHealthdConfig->batteryCycleCountPath.empty()) {
854                     path.clear();
855                     path.appendFormat("%s/%s/cycle_count",
856                                       POWER_SUPPLY_SYSFS_PATH, name);
857                     if (access(path.c_str(), R_OK) == 0)
858                         mHealthdConfig->batteryCycleCountPath = path;
859                 }
860 
861                 if (mHealthdConfig->batteryCapacityLevelPath.empty()) {
862                     path.clear();
863                     path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
864                     if (access(path.c_str(), R_OK) == 0) {
865                         mHealthdConfig->batteryCapacityLevelPath = path;
866                     }
867                 }
868 
869                 if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty()) {
870                     path.clear();
871                     path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
872                     if (access(path.c_str(), R_OK) == 0)
873                         mHealthdConfig->batteryChargeTimeToFullNowPath = path;
874                 }
875 
876                 if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty()) {
877                     path.clear();
878                     path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
879                     if (access(path.c_str(), R_OK) == 0)
880                         mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
881                 }
882 
883                 if (mHealthdConfig->batteryCurrentAvgPath.empty()) {
884                     path.clear();
885                     path.appendFormat("%s/%s/current_avg",
886                                       POWER_SUPPLY_SYSFS_PATH, name);
887                     if (access(path.c_str(), R_OK) == 0)
888                         mHealthdConfig->batteryCurrentAvgPath = path;
889                 }
890 
891                 if (mHealthdConfig->batteryChargeCounterPath.empty()) {
892                     path.clear();
893                     path.appendFormat("%s/%s/charge_counter",
894                                       POWER_SUPPLY_SYSFS_PATH, name);
895                     if (access(path.c_str(), R_OK) == 0)
896                         mHealthdConfig->batteryChargeCounterPath = path;
897                 }
898 
899                 if (mHealthdConfig->batteryTemperaturePath.empty()) {
900                     path.clear();
901                     path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
902                                       name);
903                     if (access(path.c_str(), R_OK) == 0) {
904                         mHealthdConfig->batteryTemperaturePath = path;
905                     }
906                 }
907 
908                 if (mHealthdConfig->batteryTechnologyPath.empty()) {
909                     path.clear();
910                     path.appendFormat("%s/%s/technology",
911                                       POWER_SUPPLY_SYSFS_PATH, name);
912                     if (access(path.c_str(), R_OK) == 0)
913                         mHealthdConfig->batteryTechnologyPath = path;
914                 }
915 
916                 if (mHealthdConfig->batteryStateOfHealthPath.empty()) {
917                     path.clear();
918                     path.appendFormat("%s/%s/state_of_health", POWER_SUPPLY_SYSFS_PATH, name);
919                     if (access(path.c_str(), R_OK) == 0) {
920                         mHealthdConfig->batteryStateOfHealthPath = path;
921                     } else {
922                         path.clear();
923                         path.appendFormat("%s/%s/health_index", POWER_SUPPLY_SYSFS_PATH, name);
924                         if (access(path.c_str(), R_OK) == 0)
925                             mHealthdConfig->batteryStateOfHealthPath = path;
926                     }
927                 }
928 
929                 if (mHealthdConfig->batteryHealthStatusPath.empty()) {
930                     path.clear();
931                     path.appendFormat("%s/%s/health_status", POWER_SUPPLY_SYSFS_PATH, name);
932                     if (access(path.c_str(), R_OK) == 0) {
933                         mHealthdConfig->batteryHealthStatusPath = path;
934                     }
935                 }
936 
937                 if (mHealthdConfig->batteryManufacturingDatePath.empty()) {
938                     path.clear();
939                     path.appendFormat("%s/%s/manufacturing_date", POWER_SUPPLY_SYSFS_PATH, name);
940                     if (access(path.c_str(), R_OK) == 0)
941                         mHealthdConfig->batteryManufacturingDatePath = path;
942                 }
943 
944                 if (mHealthdConfig->batteryFirstUsageDatePath.empty()) {
945                     path.clear();
946                     path.appendFormat("%s/%s/first_usage_date", POWER_SUPPLY_SYSFS_PATH, name);
947                     if (access(path.c_str(), R_OK) == 0) {
948                         mHealthdConfig->batteryFirstUsageDatePath = path;
949                     }
950                 }
951 
952                 if (mHealthdConfig->chargingStatePath.empty()) {
953                     path.clear();
954                     path.appendFormat("%s/%s/charging_state", POWER_SUPPLY_SYSFS_PATH, name);
955                     if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingStatePath = path;
956                 }
957 
958                 if (mHealthdConfig->chargingPolicyPath.empty()) {
959                     path.clear();
960                     path.appendFormat("%s/%s/charging_policy", POWER_SUPPLY_SYSFS_PATH, name);
961                     if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingPolicyPath = path;
962                 }
963 
964                 break;
965 
966             case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
967                 break;
968             }
969 
970             // Look for "is_dock" file
971             path.clear();
972             path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, name);
973             if (access(path.c_str(), R_OK) == 0) {
974                 path.clear();
975                 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
976                 if (access(path.c_str(), R_OK) == 0) mChargerNames.add(String8(name));
977             }
978         }
979     }
980 
981     // Typically the case for devices which do not have a battery and
982     // and are always plugged into AC mains.
983     if (!mBatteryDevicePresent) {
984         KLOG_WARNING(LOG_TAG, "No battery devices found\n");
985         hc->periodic_chores_interval_fast = -1;
986         hc->periodic_chores_interval_slow = -1;
987     } else {
988         if (mHealthdConfig->batteryStatusPath.empty())
989             KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
990         if (mHealthdConfig->batteryHealthPath.empty())
991             KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
992         if (mHealthdConfig->batteryPresentPath.empty())
993             KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
994         if (mHealthdConfig->batteryCapacityPath.empty())
995             KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
996         if (mHealthdConfig->batteryVoltagePath.empty())
997             KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
998         if (mHealthdConfig->batteryTemperaturePath.empty())
999             KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
1000         if (mHealthdConfig->batteryTechnologyPath.empty())
1001             KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
1002         if (mHealthdConfig->batteryCurrentNowPath.empty())
1003             KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
1004         if (mHealthdConfig->batteryFullChargePath.empty())
1005             KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
1006         if (mHealthdConfig->batteryCycleCountPath.empty())
1007             KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
1008         if (mHealthdConfig->batteryCapacityLevelPath.empty())
1009             KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
1010         if (mHealthdConfig->batteryChargeTimeToFullNowPath.empty())
1011             KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
1012         if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.empty())
1013             KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
1014         if (mHealthdConfig->batteryStateOfHealthPath.empty())
1015             KLOG_WARNING(LOG_TAG, "batteryStateOfHealthPath not found\n");
1016         if (mHealthdConfig->batteryHealthStatusPath.empty())
1017             KLOG_WARNING(LOG_TAG, "batteryHealthStatusPath not found\n");
1018         if (mHealthdConfig->batteryManufacturingDatePath.empty())
1019             KLOG_WARNING(LOG_TAG, "batteryManufacturingDatePath not found\n");
1020         if (mHealthdConfig->batteryFirstUsageDatePath.empty())
1021             KLOG_WARNING(LOG_TAG, "batteryFirstUsageDatePath not found\n");
1022         if (mHealthdConfig->chargingStatePath.empty())
1023             KLOG_WARNING(LOG_TAG, "chargingStatePath not found\n");
1024         if (mHealthdConfig->chargingPolicyPath.empty())
1025             KLOG_WARNING(LOG_TAG, "chargingPolicyPath not found\n");
1026     }
1027 
1028     if (property_get("ro.boot.fake_battery", pval, NULL) > 0
1029                                                && strtol(pval, NULL, 10) != 0) {
1030         mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
1031         mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
1032     }
1033 }
1034 
1035 }; // namespace android
1036