diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp index 97704bf0ab..c44416520f 100644 --- a/health/2.0/Android.bp +++ b/health/2.0/Android.bp @@ -18,6 +18,7 @@ hidl_interface { types: [ "Result", "DiskStats", + "HealthInfo", "StorageAttribute", "StorageInfo", ], diff --git a/health/2.0/IHealth.hal b/health/2.0/IHealth.hal index fbcc89f93f..230b5d095d 100644 --- a/health/2.0/IHealth.hal +++ b/health/2.0/IHealth.hal @@ -160,4 +160,15 @@ interface IHealth { * The mapping is index 0->sda, 1->sdb and so on. */ getDiskStats() generates (Result result, vec value); + + /** + * Get Health Information. + * + * @return result SUCCESS if successful, + * NOT_SUPPORTED if this API is not supported, + * UNKNOWN for other errors. + * @return value Health information, to be ignored if result is not + * SUCCESS. + */ + getHealthInfo() generates (Result result, @2.0::HealthInfo value); }; diff --git a/health/2.0/IHealthInfoCallback.hal b/health/2.0/IHealthInfoCallback.hal index 8e17bb96bc..737ea72da5 100644 --- a/health/2.0/IHealthInfoCallback.hal +++ b/health/2.0/IHealthInfoCallback.hal @@ -28,5 +28,5 @@ interface IHealthInfoCallback { * registered callbacks after health info changes. * @param info the updated HealthInfo */ - oneway healthInfoChanged(HealthInfo info); + oneway healthInfoChanged(@1.0::HealthInfo info); }; diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp index e67cdb4fd1..b1227a3b2d 100644 --- a/health/2.0/default/Health.cpp +++ b/health/2.0/default/Health.cpp @@ -18,6 +18,7 @@ #include +#include #include extern void healthd_battery_update_internal(bool); @@ -199,6 +200,39 @@ Return Health::getDiskStats(getDiskStats_cb _hidl_cb) { return Void(); } +Return Health::getHealthInfo(getHealthInfo_cb _hidl_cb) { + using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo; + + update(); + struct android::BatteryProperties p = getBatteryProperties(battery_monitor_.get()); + + V1_0::HealthInfo batteryInfo; + convertToHealthInfo(&p, batteryInfo); + + std::vector info; + get_storage_info(info); + + std::vector stats; + get_disk_stats(stats); + + int32_t currentAvg = 0; + + struct BatteryProperty prop; + status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop); + if (ret == OK) { + currentAvg = static_cast(prop.valueInt64); + } + + V2_0::HealthInfo healthInfo = {}; + healthInfo.legacy = std::move(batteryInfo); + healthInfo.batteryCurrentAverage = currentAvg; + healthInfo.diskStats = stats; + healthInfo.storageInfos = info; + + _hidl_cb(Result::SUCCESS, healthInfo); + return Void(); +} + void Health::serviceDied(uint64_t /* cookie */, const wp& who) { (void)unregisterCallbackInternal(who.promote()); } diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h index 41ba9e9054..fc867893d7 100644 --- a/health/2.0/default/include/health2/Health.h +++ b/health/2.0/default/include/health2/Health.h @@ -52,6 +52,7 @@ struct Health : public IHealth, hidl_death_recipient { Return getChargeStatus(getChargeStatus_cb _hidl_cb) override; Return getStorageInfo(getStorageInfo_cb _hidl_cb) override; Return getDiskStats(getDiskStats_cb _hidl_cb) override; + Return getHealthInfo(getHealthInfo_cb _hidl_cb) override; // Methods from ::android::hidl::base::V1_0::IBase follow. Return debug(const hidl_handle& fd, const hidl_vec& args) override; diff --git a/health/2.0/types.hal b/health/2.0/types.hal index 4e7a0814cb..c74076e545 100644 --- a/health/2.0/types.hal +++ b/health/2.0/types.hal @@ -124,3 +124,31 @@ struct DiskStats { */ StorageAttribute attr; }; + +/** + * Combined Health Information. + */ +struct HealthInfo { + /** + * V1.0 HealthInfo. + * If a member is unsupported, it is filled with: + * - 0 (for integers); + * - false (for booleans); + * - empty string (for strings); + * - UNKNOWN (for BatteryStatus and BatteryHealth). + */ + @1.0::HealthInfo legacy; + /** + * Average battery current in uA. Will be 0 if unsupported. + */ + int64_t batteryCurrentAverage; + /** + * Disk Statistics. Will be an empty vector if unsupported. + */ + vec diskStats; + /** + * Information on storage devices. Will be an empty vector if + * unsupported. + */ + vec storageInfos; +}; diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp index b2c6160d77..85dab44c6f 100644 --- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp +++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp @@ -35,7 +35,6 @@ namespace health { namespace V2_0 { using V1_0::BatteryStatus; -using V1_0::HealthInfo; // Test environment for graphics.composer class HealthHidlEnvironment : public VtsHalHidlTargetTestEnvBase { @@ -69,7 +68,7 @@ class HealthHidlTest : public ::testing::VtsHalHidlTargetTestBase { class Callback : public IHealthInfoCallback { public: - Return healthInfoChanged(const HealthInfo&) override { + Return healthInfoChanged(const V1_0::HealthInfo&) override { std::lock_guard lock(mMutex); mInvoked = true; mInvokedNotify.notify_all(); @@ -203,6 +202,43 @@ bool verifyDiskStats(const hidl_vec& stats) { return true; } +template +bool verifyEnum(T value) { + for (auto it : hidl_enum_iterator()) { + if (it == value) { + return true; + } + } + + return false; +} + +bool verifyHealthInfo(const HealthInfo& health_info) { + if (!verifyStorageInfo(health_info.storageInfos) || !verifyDiskStats(health_info.diskStats)) { + return false; + } + + using V1_0::BatteryStatus; + using V1_0::BatteryHealth; + + if (!((health_info.legacy.batteryChargeCounter > 0) && + (health_info.legacy.batteryCurrent != INT32_MIN) && + (0 <= health_info.legacy.batteryLevel && health_info.legacy.batteryLevel <= 100) && + verifyEnum(health_info.legacy.batteryHealth) && + (health_info.legacy.batteryStatus != BatteryStatus::UNKNOWN) && + verifyEnum(health_info.legacy.batteryStatus))) { + return false; + } + + return true; +} + +/* + * Tests the values returned by getChargeCounter(), + * getCurrentNow(), getCurrentAverage(), getCapacity(), getEnergyCounter(), + * getChargeStatus(), getStorageInfo(), getDiskStats() and getHealthInfo() from + * interface IHealth. + */ TEST_F(HealthHidlTest, Properties) { EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) { EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0); @@ -222,15 +258,17 @@ TEST_F(HealthHidlTest, Properties) { EXPECT_OK(mHealth->getChargeStatus([](auto result, auto value) { EXPECT_VALID_OR_UNSUPPORTED_PROP( result, toString(value), - value == BatteryStatus::CHARGING || value == BatteryStatus::DISCHARGING || - value == BatteryStatus::NOT_CHARGING || value == BatteryStatus::FULL); + value != BatteryStatus::UNKNOWN && verifyEnum(value)); })); EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) { - EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), (verifyStorageInfo(value))); + EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyStorageInfo(value)); })); EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) { EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyDiskStats(value)); })); + EXPECT_OK(mHealth->getHealthInfo([](auto result, auto& value) { + EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyHealthInfo(value)); + })); } } // namespace V2_0