diff --git a/healthd/Android.bp b/healthd/Android.bp index 24777c8e6..f18000662 100644 --- a/healthd/Android.bp +++ b/healthd/Android.bp @@ -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"], diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp index 5890f9aab..18076fb23 100644 --- a/healthd/BatteryMonitor.cpp +++ b/healthd/BatteryMonitor.cpp @@ -31,10 +31,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -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( + in.batteryCapacityLevel); + out->batteryChargeTimeToFullNowSeconds = in.batteryChargeTimeToFullNowSeconds; + out->batteryFullChargeDesignCapacityUah = in.batteryFullChargeDesignCapacityUah; +} + +} // namespace namespace android { @@ -74,17 +120,15 @@ static std::optional mapSysfsString(const char* str, SysfsStringEnumMap 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() @@ -92,22 +136,31 @@ BatteryMonitor::BatteryMonitor() mBatteryDevicePresent(false), mBatteryFixedCapacity(0), mBatteryFixedTemperature(0), - mChargerDockOnline(false), - mHealthInfo(std::make_unique()) { + mHealthInfo(std::make_unique()) { 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; } @@ -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()) @@ -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; @@ -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; @@ -313,29 +365,26 @@ 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, @@ -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; } } @@ -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()) { @@ -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() { @@ -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()) { @@ -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)); } @@ -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)); } } diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h index 89c2e2575..2a7e35329 100644 --- a/healthd/include/healthd/BatteryMonitor.h +++ b/healthd/include/healthd/BatteryMonitor.h @@ -25,6 +25,10 @@ #include +namespace aidl::android::hardware::health { +class HealthInfo; +} // namespace aidl::android::hardware::health + namespace android { namespace hardware { namespace health { @@ -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); @@ -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 mHealthInfo; + std::unique_ptr 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