From 1d4368b4943bd4348415ce3702bf95bb68f8fb09 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Mon, 7 Oct 2019 11:18:04 -0700 Subject: [PATCH] [REFACTOR] healthd: BatteryMonitor use health 2.1 types ... instead of BatteryProperties. HealthInfo contains much more information and is easy for health HAL impl to use it. Also add getHealthInfo* functions for health HAL implentations to use. Test: health VTS 2.0 test Bug: 142260281 Change-Id: I188276788fd8f11e69f8e046b91a873afaa23457 --- healthd/Android.bp | 4 + healthd/BatteryMonitor.cpp | 167 ++++++++++++----------- healthd/include/healthd/BatteryMonitor.h | 25 +++- 3 files changed, 109 insertions(+), 87 deletions(-) diff --git a/healthd/Android.bp b/healthd/Android.bp index 4f89bfb62..e04f70f72 100644 --- a/healthd/Android.bp +++ b/healthd/Android.bp @@ -17,6 +17,10 @@ cc_library_static { shared_libs: [ "libutils", "libbase", + + // Need latest HealthInfo definition from headers of this shared + // library. Clients don't need to link to this. + "android.hardware.health@2.1", ], header_libs: ["libhealthd_headers"], export_header_lib_headers: ["libhealthd_headers"], diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp index 57ed362b2..cdc2e5d28 100644 --- a/healthd/BatteryMonitor.cpp +++ b/healthd/BatteryMonitor.cpp @@ -29,10 +29,12 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -47,97 +49,92 @@ #define MILLION 1.0e6 #define DEFAULT_VBUS_VOLTAGE 5000000 +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; + namespace android { -struct sysfsStringEnumMap { +template +struct SysfsStringEnumMap { const char* s; - int val; + T val; }; -static int mapSysfsString(const char* str, - struct sysfsStringEnumMap map[]) { +template +static std::optional mapSysfsString(const char* str, SysfsStringEnumMap map[]) { for (int i = 0; map[i].s; i++) if (!strcmp(str, map[i].s)) return map[i].val; - return -1; -} - -static void initBatteryProperties(BatteryProperties* props) { - props->chargerAcOnline = false; - props->chargerUsbOnline = false; - props->chargerWirelessOnline = false; - props->maxChargingCurrent = 0; - props->maxChargingVoltage = 0; - props->batteryStatus = BATTERY_STATUS_UNKNOWN; - props->batteryHealth = BATTERY_HEALTH_UNKNOWN; - props->batteryPresent = false; - props->batteryLevel = 0; - props->batteryVoltage = 0; - props->batteryTemperature = 0; - props->batteryCurrent = 0; - props->batteryCycleCount = 0; - props->batteryFullCharge = 0; - props->batteryChargeCounter = 0; - props->batteryTechnology.clear(); + return std::nullopt; } BatteryMonitor::BatteryMonitor() : mHealthdConfig(nullptr), mBatteryDevicePresent(false), mBatteryFixedCapacity(0), - mBatteryFixedTemperature(0) { - initBatteryProperties(&props); + mBatteryFixedTemperature(0), + mHealthInfo(std::make_unique()) {} + +BatteryMonitor::~BatteryMonitor() {} + +const HealthInfo_1_0& BatteryMonitor::getHealthInfo_1_0() const { + return getHealthInfo_2_0().legacy; } -struct BatteryProperties getBatteryProperties(BatteryMonitor* batteryMonitor) { - return batteryMonitor->props; +const HealthInfo_2_0& BatteryMonitor::getHealthInfo_2_0() const { + return getHealthInfo_2_1().legacy; } -int BatteryMonitor::getBatteryStatus(const char* status) { - int ret; - struct sysfsStringEnumMap batteryStatusMap[] = { - { "Unknown", BATTERY_STATUS_UNKNOWN }, - { "Charging", BATTERY_STATUS_CHARGING }, - { "Discharging", BATTERY_STATUS_DISCHARGING }, - { "Not charging", BATTERY_STATUS_NOT_CHARGING }, - { "Full", BATTERY_STATUS_FULL }, - { NULL, 0 }, +const HealthInfo_2_1& BatteryMonitor::getHealthInfo_2_1() const { + return *mHealthInfo; +} + +BatteryStatus getBatteryStatus(const char* status) { + static SysfsStringEnumMap batteryStatusMap[] = { + {"Unknown", BatteryStatus::UNKNOWN}, + {"Charging", BatteryStatus::CHARGING}, + {"Discharging", BatteryStatus::DISCHARGING}, + {"Not charging", BatteryStatus::NOT_CHARGING}, + {"Full", BatteryStatus::FULL}, + {NULL, BatteryStatus::UNKNOWN}, }; - ret = mapSysfsString(status, batteryStatusMap); - if (ret < 0) { + auto ret = mapSysfsString(status, batteryStatusMap); + if (!ret) { KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status); - ret = BATTERY_STATUS_UNKNOWN; + *ret = BatteryStatus::UNKNOWN; } - return ret; + return *ret; } -int BatteryMonitor::getBatteryHealth(const char* status) { - int ret; - struct sysfsStringEnumMap batteryHealthMap[] = { - { "Unknown", BATTERY_HEALTH_UNKNOWN }, - { "Good", BATTERY_HEALTH_GOOD }, - { "Overheat", BATTERY_HEALTH_OVERHEAT }, - { "Dead", BATTERY_HEALTH_DEAD }, - { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE }, - { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE }, - { "Cold", BATTERY_HEALTH_COLD }, - // battery health values from JEITA spec - { "Warm", BATTERY_HEALTH_GOOD }, - { "Cool", BATTERY_HEALTH_GOOD }, - { "Hot", BATTERY_HEALTH_OVERHEAT }, - { NULL, 0 }, +BatteryHealth getBatteryHealth(const char* status) { + static SysfsStringEnumMap batteryHealthMap[] = { + {"Unknown", BatteryHealth::UNKNOWN}, + {"Good", BatteryHealth::GOOD}, + {"Overheat", BatteryHealth::OVERHEAT}, + {"Dead", BatteryHealth::DEAD}, + {"Over voltage", BatteryHealth::OVER_VOLTAGE}, + {"Unspecified failure", BatteryHealth::UNSPECIFIED_FAILURE}, + {"Cold", BatteryHealth::COLD}, + // battery health values from JEITA spec + {"Warm", BatteryHealth::GOOD}, + {"Cool", BatteryHealth::GOOD}, + {"Hot", BatteryHealth::OVERHEAT}, + {NULL, BatteryHealth::UNKNOWN}, }; - ret = mapSysfsString(status, batteryHealthMap); - if (ret < 0) { + auto ret = mapSysfsString(status, batteryHealthMap); + if (!ret) { KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status); - ret = BATTERY_HEALTH_UNKNOWN; + *ret = BatteryHealth::UNKNOWN; } - return ret; + return *ret; } int BatteryMonitor::readFromFile(const String8& path, std::string* buf) { @@ -148,35 +145,34 @@ int BatteryMonitor::readFromFile(const String8& path, std::string* buf) { } BatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) { - std::string buf; - int ret; - struct sysfsStringEnumMap supplyTypeMap[] = { - { "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN }, - { "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY }, - { "UPS", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "Mains", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB", ANDROID_POWER_SUPPLY_TYPE_USB }, - { "USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_C", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB }, - { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, - { NULL, 0 }, + static SysfsStringEnumMap supplyTypeMap[] = { + {"Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN}, + {"Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY}, + {"UPS", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"Mains", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB", ANDROID_POWER_SUPPLY_TYPE_USB}, + {"USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB_C", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC}, + {"USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB}, + {"Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS}, + {NULL, 0}, }; + std::string buf; if (readFromFile(path, &buf) <= 0) return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; - ret = mapSysfsString(buf.c_str(), supplyTypeMap); + auto ret = mapSysfsString(buf.c_str(), supplyTypeMap); if (ret < 0) { KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str()); - ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; + *ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; } - return static_cast(ret); + return static_cast(*ret); } bool BatteryMonitor::getBooleanField(const String8& path) { @@ -201,7 +197,9 @@ int BatteryMonitor::getIntField(const String8& path) { } void BatteryMonitor::updateValues(void) { - initBatteryProperties(&props); + *mHealthInfo = HealthInfo_2_1{}; + + HealthInfo_1_0& props = mHealthInfo->legacy.legacy; if (!mHealthdConfig->batteryPresentPath.isEmpty()) props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); @@ -292,6 +290,7 @@ void BatteryMonitor::updateValues(void) { void BatteryMonitor::logValues(void) { char dmesgline[256]; size_t len; + const HealthInfo_1_0& props = mHealthInfo->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 ? "-" : "", @@ -325,18 +324,19 @@ void BatteryMonitor::logValues(void) { } bool BatteryMonitor::isChargerOnline() { + const HealthInfo_1_0& props = mHealthInfo->legacy.legacy; return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline; } int BatteryMonitor::getChargeStatus() { - int result = BATTERY_STATUS_UNKNOWN; + BatteryStatus result = BatteryStatus::UNKNOWN; if (!mHealthdConfig->batteryStatusPath.isEmpty()) { std::string buf; if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0) result = getBatteryStatus(buf.c_str()); } - return result; + return static_cast(result); } status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { @@ -409,6 +409,7 @@ 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; snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d voltage_max: %d\n", props.chargerAcOnline, props.chargerUsbOnline, diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h index 0fd382412..d41a374a6 100644 --- a/healthd/include/healthd/BatteryMonitor.h +++ b/healthd/include/healthd/BatteryMonitor.h @@ -17,6 +17,8 @@ #ifndef HEALTHD_BATTERYMONITOR_H #define HEALTHD_BATTERYMONITOR_H +#include + #include #include #include @@ -24,6 +26,19 @@ #include namespace android { +namespace hardware { +namespace health { +namespace V1_0 { +struct HealthInfo; +} // namespace V1_0 +namespace V2_0 { +struct HealthInfo; +} // namespace V2_0 +namespace V2_1 { +struct HealthInfo; +} // namespace V2_1 +} // namespace health +} // namespace hardware class BatteryMonitor { public: @@ -37,11 +52,15 @@ class BatteryMonitor { }; BatteryMonitor(); + ~BatteryMonitor(); void init(struct healthd_config *hc); int getChargeStatus(); status_t getProperty(int id, struct BatteryProperty *val); void dumpState(int fd); - friend struct BatteryProperties getBatteryProperties(BatteryMonitor* batteryMonitor); + + 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; void updateValues(void); void logValues(void); @@ -53,10 +72,8 @@ class BatteryMonitor { bool mBatteryDevicePresent; int mBatteryFixedCapacity; int mBatteryFixedTemperature; - struct BatteryProperties props; + std::unique_ptr mHealthInfo; - int getBatteryStatus(const char* status); - int getBatteryHealth(const char* status); int readFromFile(const String8& path, std::string* buf); PowerSupplyType readPowerSupplyType(const String8& path); bool getBooleanField(const String8& path);