Loading healthd/Android.bp +8 −2 Original line number Diff line number Diff line Loading @@ -22,9 +22,15 @@ cc_library_static { "libutils", "libbase", // Need latest HealthInfo definition from headers of this shared // library. Clients don't need to link to this. // Need HealthInfo definition from headers of these shared // libraries. Clients don't need to link to these. "android.hardware.health@2.1", "android.hardware.health-V1-ndk", ], whole_static_libs: [ // Need to translate HIDL to AIDL to support legacy APIs in // BatteryMonitor. "android.hardware.health-translate-ndk", ], header_libs: ["libhealthd_headers"], export_header_lib_headers: ["libhealthd_headers"], Loading healthd/BatteryMonitor.cpp +128 −71 Original line number Diff line number Diff line Loading @@ -31,10 +31,12 @@ #include <memory> #include <optional> #include <aidl/android/hardware/health/HealthInfo.h> #include <android-base/file.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <android/hardware/health/2.1/types.h> #include <android/hardware/health/translate-ndk.h> #include <batteryservice/BatteryService.h> #include <cutils/klog.h> #include <cutils/properties.h> Loading @@ -52,10 +54,54 @@ using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo; using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo; using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo; using android::hardware::health::V1_0::BatteryHealth; using android::hardware::health::V1_0::BatteryStatus; using android::hardware::health::V2_1::BatteryCapacityLevel; using android::hardware::health::V2_1::Constants; using aidl::android::hardware::health::BatteryCapacityLevel; using aidl::android::hardware::health::BatteryHealth; using aidl::android::hardware::health::BatteryStatus; using aidl::android::hardware::health::HealthInfo; namespace { // Translate from AIDL back to HIDL definition for getHealthInfo_*_* calls. // Skips storageInfo and diskStats. void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in, ::android::hardware::health::V1_0::HealthInfo* out) { out->chargerAcOnline = in.chargerAcOnline; out->chargerUsbOnline = in.chargerUsbOnline; out->chargerWirelessOnline = in.chargerWirelessOnline; out->maxChargingCurrent = in.maxChargingCurrentMicroamps; out->maxChargingVoltage = in.maxChargingVoltageMicrovolts; out->batteryStatus = static_cast<::android::hardware::health::V1_0::BatteryStatus>(in.batteryStatus); out->batteryHealth = static_cast<::android::hardware::health::V1_0::BatteryHealth>(in.batteryHealth); out->batteryPresent = in.batteryPresent; out->batteryLevel = in.batteryLevel; out->batteryVoltage = in.batteryVoltageMillivolts; out->batteryTemperature = in.batteryTemperatureTenthsCelsius; out->batteryCurrent = in.batteryCurrentMicroamps; out->batteryCycleCount = in.batteryCycleCount; out->batteryFullCharge = in.batteryFullChargeUah; out->batteryChargeCounter = in.batteryChargeCounterUah; out->batteryTechnology = in.batteryTechnology; } void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in, ::android::hardware::health::V2_0::HealthInfo* out) { translateToHidl(in, &out->legacy); out->batteryCurrentAverage = in.batteryCurrentAverageMicroamps; // Skip storageInfo and diskStats } void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in, ::android::hardware::health::V2_1::HealthInfo* out) { translateToHidl(in, &out->legacy); out->batteryCapacityLevel = static_cast<android::hardware::health::V2_1::BatteryCapacityLevel>( in.batteryCapacityLevel); out->batteryChargeTimeToFullNowSeconds = in.batteryChargeTimeToFullNowSeconds; out->batteryFullChargeDesignCapacityUah = in.batteryFullChargeDesignCapacityUah; } } // namespace namespace android { Loading @@ -74,17 +120,15 @@ static std::optional<T> mapSysfsString(const char* str, SysfsStringEnumMap<T> ma return std::nullopt; } static void initHealthInfo(HealthInfo_2_1* health_info_2_1) { *health_info_2_1 = HealthInfo_2_1{}; static void initHealthInfo(HealthInfo* health_info) { *health_info = HealthInfo{}; // HIDL enum values are zero initialized, so they need to be initialized // properly. health_info_2_1->batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED; health_info_2_1->batteryChargeTimeToFullNowSeconds = (int64_t)Constants::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED; auto* props = &health_info_2_1->legacy.legacy; props->batteryStatus = BatteryStatus::UNKNOWN; props->batteryHealth = BatteryHealth::UNKNOWN; // Enum values may be zero initialized, so they need to be initialized properly. health_info->batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED; health_info->batteryChargeTimeToFullNowSeconds = (int64_t)HealthInfo::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED; health_info->batteryStatus = BatteryStatus::UNKNOWN; health_info->batteryHealth = BatteryHealth::UNKNOWN; } BatteryMonitor::BatteryMonitor() Loading @@ -92,22 +136,31 @@ BatteryMonitor::BatteryMonitor() mBatteryDevicePresent(false), mBatteryFixedCapacity(0), mBatteryFixedTemperature(0), mChargerDockOnline(false), mHealthInfo(std::make_unique<HealthInfo_2_1>()) { mHealthInfo(std::make_unique<HealthInfo>()) { initHealthInfo(mHealthInfo.get()); } BatteryMonitor::~BatteryMonitor() {} const HealthInfo_1_0& BatteryMonitor::getHealthInfo_1_0() const { return getHealthInfo_2_0().legacy; HealthInfo_1_0 BatteryMonitor::getHealthInfo_1_0() const { HealthInfo_1_0 health_info_1_0; translateToHidl(*mHealthInfo, &health_info_1_0); return health_info_1_0; } const HealthInfo_2_0& BatteryMonitor::getHealthInfo_2_0() const { return getHealthInfo_2_1().legacy; HealthInfo_2_0 BatteryMonitor::getHealthInfo_2_0() const { HealthInfo_2_0 health_info_2_0; translateToHidl(*mHealthInfo, &health_info_2_0); return health_info_2_0; } const HealthInfo_2_1& BatteryMonitor::getHealthInfo_2_1() const { HealthInfo_2_1 BatteryMonitor::getHealthInfo_2_1() const { HealthInfo_2_1 health_info_2_1; translateToHidl(*mHealthInfo, &health_info_2_1); return health_info_2_1; } const HealthInfo& BatteryMonitor::getHealthInfo() const { return *mHealthInfo; } Loading Loading @@ -247,32 +300,31 @@ bool BatteryMonitor::isScopedPowerSupply(const char* name) { void BatteryMonitor::updateValues(void) { initHealthInfo(mHealthInfo.get()); HealthInfo_1_0& props = mHealthInfo->legacy.legacy; if (!mHealthdConfig->batteryPresentPath.isEmpty()) props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); else props.batteryPresent = mBatteryDevicePresent; mHealthInfo->batteryPresent = mBatteryDevicePresent; props.batteryLevel = mBatteryFixedCapacity ? mBatteryFixedCapacity : getIntField(mHealthdConfig->batteryCapacityPath); props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000; mHealthInfo->batteryLevel = mBatteryFixedCapacity ? mBatteryFixedCapacity : getIntField(mHealthdConfig->batteryCapacityPath); mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000; if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath); mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath); if (!mHealthdConfig->batteryFullChargePath.isEmpty()) props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath); mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath); if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath); mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath); if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath); mHealthInfo->batteryChargeCounterUah = getIntField(mHealthdConfig->batteryChargeCounterPath); if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) mHealthInfo->legacy.batteryCurrentAverage = mHealthInfo->batteryCurrentAverageMicroamps = getIntField(mHealthdConfig->batteryCurrentAvgPath); if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty()) Loading @@ -283,9 +335,9 @@ void BatteryMonitor::updateValues(void) { mHealthInfo->batteryFullChargeDesignCapacityUah = getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath); props.batteryTemperature = mBatteryFixedTemperature ? mBatteryFixedTemperature : getIntField(mHealthdConfig->batteryTemperaturePath); mHealthInfo->batteryTemperatureTenthsCelsius = mBatteryFixedTemperature ? mBatteryFixedTemperature : getIntField(mHealthdConfig->batteryTemperaturePath); std::string buf; Loading @@ -293,13 +345,13 @@ void BatteryMonitor::updateValues(void) { mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str()); if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0) props.batteryStatus = getBatteryStatus(buf.c_str()); mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str()); if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0) props.batteryHealth = getBatteryHealth(buf.c_str()); mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str()); if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0) props.batteryTechnology = String8(buf.c_str()); mHealthInfo->batteryTechnology = String8(buf.c_str()); double MaxPower = 0; Loading @@ -313,30 +365,27 @@ void BatteryMonitor::updateValues(void) { mChargerNames[i].string()); switch(readPowerSupplyType(path)) { case ANDROID_POWER_SUPPLY_TYPE_AC: props.chargerAcOnline = true; mHealthInfo->chargerAcOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_USB: props.chargerUsbOnline = true; mHealthInfo->chargerUsbOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: props.chargerWirelessOnline = true; mHealthInfo->chargerWirelessOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_DOCK: mChargerDockOnline = true; mHealthInfo->chargerDockOnline = true; break; default: path.clear(); path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].string()); if (access(path.string(), R_OK) == 0) { mChargerDockOnline = true; KLOG_INFO(LOG_TAG, "%s: online\n", mChargerNames[i].string()); } else { if (access(path.string(), R_OK) == 0) mHealthInfo->chargerDockOnline = true; else KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", mChargerNames[i].string()); } } path.clear(); path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].string()); Loading @@ -354,8 +403,8 @@ void BatteryMonitor::updateValues(void) { double power = ((double)ChargingCurrent / MILLION) * ((double)ChargingVoltage / MILLION); if (MaxPower < power) { props.maxChargingCurrent = ChargingCurrent; props.maxChargingVoltage = ChargingVoltage; mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent; mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage; MaxPower = power; } } Loading @@ -366,26 +415,34 @@ void BatteryMonitor::logValues(void) { logValues(*mHealthInfo, *mHealthdConfig); } void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo& health_info, void BatteryMonitor::logValues(const HealthInfo_2_1& health_info, const struct healthd_config& healthd_config) { HealthInfo aidl_health_info; (void)android::h2a::translate(health_info, &aidl_health_info); logValues(aidl_health_info, healthd_config); } void BatteryMonitor::logValues(const HealthInfo& props, const struct healthd_config& healthd_config) { char dmesgline[256]; size_t len; const HealthInfo_1_0& props = health_info.legacy.legacy; if (props.batteryPresent) { snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d", props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "", abs(props.batteryTemperature / 10), abs(props.batteryTemperature % 10), props.batteryHealth, props.batteryStatus); props.batteryLevel, props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius < 0 ? "-" : "", abs(props.batteryTemperatureTenthsCelsius / 10), abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth, props.batteryStatus); len = strlen(dmesgline); if (!healthd_config.batteryCurrentNowPath.isEmpty()) { len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d", props.batteryCurrent); props.batteryCurrentMicroamps); } if (!healthd_config.batteryFullChargePath.isEmpty()) { len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d", props.batteryFullCharge); props.batteryFullChargeUah); } if (!healthd_config.batteryCycleCountPath.isEmpty()) { Loading @@ -396,17 +453,17 @@ void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo len = snprintf(dmesgline, sizeof(dmesgline), "battery none"); } snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s", snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s", props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "", props.chargerWirelessOnline ? "w" : ""); props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : ""); KLOG_WARNING(LOG_TAG, "%s\n", dmesgline); } bool BatteryMonitor::isChargerOnline() { const HealthInfo_1_0& props = mHealthInfo->legacy.legacy; const HealthInfo& props = *mHealthInfo; return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline | mChargerDockOnline; props.chargerDockOnline; } int BatteryMonitor::getChargeStatus() { Loading Loading @@ -489,19 +546,19 @@ status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { void BatteryMonitor::dumpState(int fd) { int v; char vs[128]; const HealthInfo_1_0& props = mHealthInfo->legacy.legacy; const HealthInfo& props = *mHealthInfo; snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n", props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline, mChargerDockOnline, props.maxChargingCurrent, props.maxChargingVoltage); props.chargerDockOnline, props.maxChargingCurrentMicroamps, props.maxChargingVoltageMicrovolts); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", props.batteryStatus, props.batteryHealth, props.batteryPresent); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel, props.batteryVoltage, props.batteryTemperature); snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel, props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius); write(fd, vs, strlen(vs)); if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { Loading @@ -523,7 +580,7 @@ void BatteryMonitor::dumpState(int fd) { } if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrent); snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps); write(fd, vs, strlen(vs)); } Loading @@ -533,7 +590,7 @@ void BatteryMonitor::dumpState(int fd) { } if (!mHealthdConfig->batteryFullChargePath.isEmpty()) { snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge); snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah); write(fd, vs, strlen(vs)); } } Loading healthd/include/healthd/BatteryMonitor.h +12 −6 Original line number Diff line number Diff line Loading @@ -25,6 +25,10 @@ #include <healthd/healthd.h> namespace aidl::android::hardware::health { class HealthInfo; } // namespace aidl::android::hardware::health namespace android { namespace hardware { namespace health { Loading Loading @@ -59,9 +63,10 @@ class BatteryMonitor { status_t getProperty(int id, struct BatteryProperty *val); void dumpState(int fd); const android::hardware::health::V1_0::HealthInfo& getHealthInfo_1_0() const; const android::hardware::health::V2_0::HealthInfo& getHealthInfo_2_0() const; const android::hardware::health::V2_1::HealthInfo& getHealthInfo_2_1() const; android::hardware::health::V1_0::HealthInfo getHealthInfo_1_0() const; android::hardware::health::V2_0::HealthInfo getHealthInfo_2_0() const; android::hardware::health::V2_1::HealthInfo getHealthInfo_2_1() const; const aidl::android::hardware::health::HealthInfo& getHealthInfo() const; void updateValues(void); void logValues(void); Loading @@ -76,15 +81,16 @@ class BatteryMonitor { bool mBatteryDevicePresent; int mBatteryFixedCapacity; int mBatteryFixedTemperature; // TODO(b/214126090): to migrate to AIDL HealthInfo bool mChargerDockOnline; std::unique_ptr<android::hardware::health::V2_1::HealthInfo> mHealthInfo; std::unique_ptr<aidl::android::hardware::health::HealthInfo> mHealthInfo; int readFromFile(const String8& path, std::string* buf); PowerSupplyType readPowerSupplyType(const String8& path); bool getBooleanField(const String8& path); int getIntField(const String8& path); bool isScopedPowerSupply(const char* name); static void logValues(const aidl::android::hardware::health::HealthInfo& health_info, const struct healthd_config& healthd_config); }; }; // namespace android Loading Loading
healthd/Android.bp +8 −2 Original line number Diff line number Diff line Loading @@ -22,9 +22,15 @@ cc_library_static { "libutils", "libbase", // Need latest HealthInfo definition from headers of this shared // library. Clients don't need to link to this. // Need HealthInfo definition from headers of these shared // libraries. Clients don't need to link to these. "android.hardware.health@2.1", "android.hardware.health-V1-ndk", ], whole_static_libs: [ // Need to translate HIDL to AIDL to support legacy APIs in // BatteryMonitor. "android.hardware.health-translate-ndk", ], header_libs: ["libhealthd_headers"], export_header_lib_headers: ["libhealthd_headers"], Loading
healthd/BatteryMonitor.cpp +128 −71 Original line number Diff line number Diff line Loading @@ -31,10 +31,12 @@ #include <memory> #include <optional> #include <aidl/android/hardware/health/HealthInfo.h> #include <android-base/file.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <android/hardware/health/2.1/types.h> #include <android/hardware/health/translate-ndk.h> #include <batteryservice/BatteryService.h> #include <cutils/klog.h> #include <cutils/properties.h> Loading @@ -52,10 +54,54 @@ using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo; using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo; using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo; using android::hardware::health::V1_0::BatteryHealth; using android::hardware::health::V1_0::BatteryStatus; using android::hardware::health::V2_1::BatteryCapacityLevel; using android::hardware::health::V2_1::Constants; using aidl::android::hardware::health::BatteryCapacityLevel; using aidl::android::hardware::health::BatteryHealth; using aidl::android::hardware::health::BatteryStatus; using aidl::android::hardware::health::HealthInfo; namespace { // Translate from AIDL back to HIDL definition for getHealthInfo_*_* calls. // Skips storageInfo and diskStats. void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in, ::android::hardware::health::V1_0::HealthInfo* out) { out->chargerAcOnline = in.chargerAcOnline; out->chargerUsbOnline = in.chargerUsbOnline; out->chargerWirelessOnline = in.chargerWirelessOnline; out->maxChargingCurrent = in.maxChargingCurrentMicroamps; out->maxChargingVoltage = in.maxChargingVoltageMicrovolts; out->batteryStatus = static_cast<::android::hardware::health::V1_0::BatteryStatus>(in.batteryStatus); out->batteryHealth = static_cast<::android::hardware::health::V1_0::BatteryHealth>(in.batteryHealth); out->batteryPresent = in.batteryPresent; out->batteryLevel = in.batteryLevel; out->batteryVoltage = in.batteryVoltageMillivolts; out->batteryTemperature = in.batteryTemperatureTenthsCelsius; out->batteryCurrent = in.batteryCurrentMicroamps; out->batteryCycleCount = in.batteryCycleCount; out->batteryFullCharge = in.batteryFullChargeUah; out->batteryChargeCounter = in.batteryChargeCounterUah; out->batteryTechnology = in.batteryTechnology; } void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in, ::android::hardware::health::V2_0::HealthInfo* out) { translateToHidl(in, &out->legacy); out->batteryCurrentAverage = in.batteryCurrentAverageMicroamps; // Skip storageInfo and diskStats } void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in, ::android::hardware::health::V2_1::HealthInfo* out) { translateToHidl(in, &out->legacy); out->batteryCapacityLevel = static_cast<android::hardware::health::V2_1::BatteryCapacityLevel>( in.batteryCapacityLevel); out->batteryChargeTimeToFullNowSeconds = in.batteryChargeTimeToFullNowSeconds; out->batteryFullChargeDesignCapacityUah = in.batteryFullChargeDesignCapacityUah; } } // namespace namespace android { Loading @@ -74,17 +120,15 @@ static std::optional<T> mapSysfsString(const char* str, SysfsStringEnumMap<T> ma return std::nullopt; } static void initHealthInfo(HealthInfo_2_1* health_info_2_1) { *health_info_2_1 = HealthInfo_2_1{}; static void initHealthInfo(HealthInfo* health_info) { *health_info = HealthInfo{}; // HIDL enum values are zero initialized, so they need to be initialized // properly. health_info_2_1->batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED; health_info_2_1->batteryChargeTimeToFullNowSeconds = (int64_t)Constants::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED; auto* props = &health_info_2_1->legacy.legacy; props->batteryStatus = BatteryStatus::UNKNOWN; props->batteryHealth = BatteryHealth::UNKNOWN; // Enum values may be zero initialized, so they need to be initialized properly. health_info->batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED; health_info->batteryChargeTimeToFullNowSeconds = (int64_t)HealthInfo::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED; health_info->batteryStatus = BatteryStatus::UNKNOWN; health_info->batteryHealth = BatteryHealth::UNKNOWN; } BatteryMonitor::BatteryMonitor() Loading @@ -92,22 +136,31 @@ BatteryMonitor::BatteryMonitor() mBatteryDevicePresent(false), mBatteryFixedCapacity(0), mBatteryFixedTemperature(0), mChargerDockOnline(false), mHealthInfo(std::make_unique<HealthInfo_2_1>()) { mHealthInfo(std::make_unique<HealthInfo>()) { initHealthInfo(mHealthInfo.get()); } BatteryMonitor::~BatteryMonitor() {} const HealthInfo_1_0& BatteryMonitor::getHealthInfo_1_0() const { return getHealthInfo_2_0().legacy; HealthInfo_1_0 BatteryMonitor::getHealthInfo_1_0() const { HealthInfo_1_0 health_info_1_0; translateToHidl(*mHealthInfo, &health_info_1_0); return health_info_1_0; } const HealthInfo_2_0& BatteryMonitor::getHealthInfo_2_0() const { return getHealthInfo_2_1().legacy; HealthInfo_2_0 BatteryMonitor::getHealthInfo_2_0() const { HealthInfo_2_0 health_info_2_0; translateToHidl(*mHealthInfo, &health_info_2_0); return health_info_2_0; } const HealthInfo_2_1& BatteryMonitor::getHealthInfo_2_1() const { HealthInfo_2_1 BatteryMonitor::getHealthInfo_2_1() const { HealthInfo_2_1 health_info_2_1; translateToHidl(*mHealthInfo, &health_info_2_1); return health_info_2_1; } const HealthInfo& BatteryMonitor::getHealthInfo() const { return *mHealthInfo; } Loading Loading @@ -247,32 +300,31 @@ bool BatteryMonitor::isScopedPowerSupply(const char* name) { void BatteryMonitor::updateValues(void) { initHealthInfo(mHealthInfo.get()); HealthInfo_1_0& props = mHealthInfo->legacy.legacy; if (!mHealthdConfig->batteryPresentPath.isEmpty()) props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); else props.batteryPresent = mBatteryDevicePresent; mHealthInfo->batteryPresent = mBatteryDevicePresent; props.batteryLevel = mBatteryFixedCapacity ? mBatteryFixedCapacity : getIntField(mHealthdConfig->batteryCapacityPath); props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000; mHealthInfo->batteryLevel = mBatteryFixedCapacity ? mBatteryFixedCapacity : getIntField(mHealthdConfig->batteryCapacityPath); mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000; if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath); mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath); if (!mHealthdConfig->batteryFullChargePath.isEmpty()) props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath); mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath); if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath); mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath); if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath); mHealthInfo->batteryChargeCounterUah = getIntField(mHealthdConfig->batteryChargeCounterPath); if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) mHealthInfo->legacy.batteryCurrentAverage = mHealthInfo->batteryCurrentAverageMicroamps = getIntField(mHealthdConfig->batteryCurrentAvgPath); if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty()) Loading @@ -283,9 +335,9 @@ void BatteryMonitor::updateValues(void) { mHealthInfo->batteryFullChargeDesignCapacityUah = getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath); props.batteryTemperature = mBatteryFixedTemperature ? mBatteryFixedTemperature : getIntField(mHealthdConfig->batteryTemperaturePath); mHealthInfo->batteryTemperatureTenthsCelsius = mBatteryFixedTemperature ? mBatteryFixedTemperature : getIntField(mHealthdConfig->batteryTemperaturePath); std::string buf; Loading @@ -293,13 +345,13 @@ void BatteryMonitor::updateValues(void) { mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str()); if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0) props.batteryStatus = getBatteryStatus(buf.c_str()); mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str()); if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0) props.batteryHealth = getBatteryHealth(buf.c_str()); mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str()); if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0) props.batteryTechnology = String8(buf.c_str()); mHealthInfo->batteryTechnology = String8(buf.c_str()); double MaxPower = 0; Loading @@ -313,30 +365,27 @@ void BatteryMonitor::updateValues(void) { mChargerNames[i].string()); switch(readPowerSupplyType(path)) { case ANDROID_POWER_SUPPLY_TYPE_AC: props.chargerAcOnline = true; mHealthInfo->chargerAcOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_USB: props.chargerUsbOnline = true; mHealthInfo->chargerUsbOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: props.chargerWirelessOnline = true; mHealthInfo->chargerWirelessOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_DOCK: mChargerDockOnline = true; mHealthInfo->chargerDockOnline = true; break; default: path.clear(); path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].string()); if (access(path.string(), R_OK) == 0) { mChargerDockOnline = true; KLOG_INFO(LOG_TAG, "%s: online\n", mChargerNames[i].string()); } else { if (access(path.string(), R_OK) == 0) mHealthInfo->chargerDockOnline = true; else KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", mChargerNames[i].string()); } } path.clear(); path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].string()); Loading @@ -354,8 +403,8 @@ void BatteryMonitor::updateValues(void) { double power = ((double)ChargingCurrent / MILLION) * ((double)ChargingVoltage / MILLION); if (MaxPower < power) { props.maxChargingCurrent = ChargingCurrent; props.maxChargingVoltage = ChargingVoltage; mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent; mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage; MaxPower = power; } } Loading @@ -366,26 +415,34 @@ void BatteryMonitor::logValues(void) { logValues(*mHealthInfo, *mHealthdConfig); } void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo& health_info, void BatteryMonitor::logValues(const HealthInfo_2_1& health_info, const struct healthd_config& healthd_config) { HealthInfo aidl_health_info; (void)android::h2a::translate(health_info, &aidl_health_info); logValues(aidl_health_info, healthd_config); } void BatteryMonitor::logValues(const HealthInfo& props, const struct healthd_config& healthd_config) { char dmesgline[256]; size_t len; const HealthInfo_1_0& props = health_info.legacy.legacy; if (props.batteryPresent) { snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d", props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "", abs(props.batteryTemperature / 10), abs(props.batteryTemperature % 10), props.batteryHealth, props.batteryStatus); props.batteryLevel, props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius < 0 ? "-" : "", abs(props.batteryTemperatureTenthsCelsius / 10), abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth, props.batteryStatus); len = strlen(dmesgline); if (!healthd_config.batteryCurrentNowPath.isEmpty()) { len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d", props.batteryCurrent); props.batteryCurrentMicroamps); } if (!healthd_config.batteryFullChargePath.isEmpty()) { len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d", props.batteryFullCharge); props.batteryFullChargeUah); } if (!healthd_config.batteryCycleCountPath.isEmpty()) { Loading @@ -396,17 +453,17 @@ void BatteryMonitor::logValues(const android::hardware::health::V2_1::HealthInfo len = snprintf(dmesgline, sizeof(dmesgline), "battery none"); } snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s", snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s", props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "", props.chargerWirelessOnline ? "w" : ""); props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : ""); KLOG_WARNING(LOG_TAG, "%s\n", dmesgline); } bool BatteryMonitor::isChargerOnline() { const HealthInfo_1_0& props = mHealthInfo->legacy.legacy; const HealthInfo& props = *mHealthInfo; return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline | mChargerDockOnline; props.chargerDockOnline; } int BatteryMonitor::getChargeStatus() { Loading Loading @@ -489,19 +546,19 @@ status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { void BatteryMonitor::dumpState(int fd) { int v; char vs[128]; const HealthInfo_1_0& props = mHealthInfo->legacy.legacy; const HealthInfo& props = *mHealthInfo; snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n", props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline, mChargerDockOnline, props.maxChargingCurrent, props.maxChargingVoltage); props.chargerDockOnline, props.maxChargingCurrentMicroamps, props.maxChargingVoltageMicrovolts); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", props.batteryStatus, props.batteryHealth, props.batteryPresent); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel, props.batteryVoltage, props.batteryTemperature); snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel, props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius); write(fd, vs, strlen(vs)); if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { Loading @@ -523,7 +580,7 @@ void BatteryMonitor::dumpState(int fd) { } if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrent); snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps); write(fd, vs, strlen(vs)); } Loading @@ -533,7 +590,7 @@ void BatteryMonitor::dumpState(int fd) { } if (!mHealthdConfig->batteryFullChargePath.isEmpty()) { snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge); snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah); write(fd, vs, strlen(vs)); } } Loading
healthd/include/healthd/BatteryMonitor.h +12 −6 Original line number Diff line number Diff line Loading @@ -25,6 +25,10 @@ #include <healthd/healthd.h> namespace aidl::android::hardware::health { class HealthInfo; } // namespace aidl::android::hardware::health namespace android { namespace hardware { namespace health { Loading Loading @@ -59,9 +63,10 @@ class BatteryMonitor { status_t getProperty(int id, struct BatteryProperty *val); void dumpState(int fd); const android::hardware::health::V1_0::HealthInfo& getHealthInfo_1_0() const; const android::hardware::health::V2_0::HealthInfo& getHealthInfo_2_0() const; const android::hardware::health::V2_1::HealthInfo& getHealthInfo_2_1() const; android::hardware::health::V1_0::HealthInfo getHealthInfo_1_0() const; android::hardware::health::V2_0::HealthInfo getHealthInfo_2_0() const; android::hardware::health::V2_1::HealthInfo getHealthInfo_2_1() const; const aidl::android::hardware::health::HealthInfo& getHealthInfo() const; void updateValues(void); void logValues(void); Loading @@ -76,15 +81,16 @@ class BatteryMonitor { bool mBatteryDevicePresent; int mBatteryFixedCapacity; int mBatteryFixedTemperature; // TODO(b/214126090): to migrate to AIDL HealthInfo bool mChargerDockOnline; std::unique_ptr<android::hardware::health::V2_1::HealthInfo> mHealthInfo; std::unique_ptr<aidl::android::hardware::health::HealthInfo> mHealthInfo; int readFromFile(const String8& path, std::string* buf); PowerSupplyType readPowerSupplyType(const String8& path); bool getBooleanField(const String8& path); int getIntField(const String8& path); bool isScopedPowerSupply(const char* name); static void logValues(const aidl::android::hardware::health::HealthInfo& health_info, const struct healthd_config& healthd_config); }; }; // namespace android Loading