Loading media/psh_utils/PowerStatsProvider.cpp +12 −10 Original line number Diff line number Diff line Loading @@ -41,11 +41,12 @@ static auto getPowerStatsService() { return powerStats; } int RailEnergyDataProvider::fill(PowerStats *stat) const { status_t RailEnergyDataProvider::fill(PowerStats *stat) const { if (stat == nullptr) return BAD_VALUE; auto powerStatsService = getPowerStatsService(); if (powerStatsService == nullptr) { LOG(ERROR) << "unable to get power.stats AIDL service"; return 1; return NO_INIT; } std::unordered_map<int32_t, ::aidl::android::hardware::power::stats::Channel> channelMap; Loading @@ -53,7 +54,7 @@ int RailEnergyDataProvider::fill(PowerStats *stat) const { std::vector<::aidl::android::hardware::power::stats::Channel> channels; if (!powerStatsService->getEnergyMeterInfo(&channels).isOk()) { LOG(ERROR) << "unable to get energy meter info"; return 1; return INVALID_OPERATION; } for (auto& channel : channels) { channelMap.emplace(channel.id, std::move(channel)); Loading @@ -63,7 +64,7 @@ int RailEnergyDataProvider::fill(PowerStats *stat) const { std::vector<::aidl::android::hardware::power::stats::EnergyMeasurement> measurements; if (!powerStatsService->readEnergyMeter({}, &measurements).isOk()) { LOG(ERROR) << "unable to get energy measurements"; return 1; return INVALID_OPERATION; } for (const auto& measurement : measurements) { Loading @@ -83,14 +84,15 @@ int RailEnergyDataProvider::fill(PowerStats *stat) const { return a.rail_name < b.rail_name; }); return 0; return NO_ERROR; } int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { status_t PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { if (stat == nullptr) return BAD_VALUE; auto powerStatsService = getPowerStatsService(); if (powerStatsService == nullptr) { LOG(ERROR) << "unable to get power.stats AIDL service"; return 1; return NO_INIT; } // these are based on entityId Loading @@ -102,7 +104,7 @@ int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { std::vector<::aidl::android::hardware::power::stats::PowerEntity> entities; if (!powerStatsService->getPowerEntityInfo(&entities).isOk()) { LOG(ERROR) << __func__ << ": unable to get entity info"; return 1; return INVALID_OPERATION; } std::vector<std::string> powerEntityNames; Loading @@ -124,7 +126,7 @@ int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { std::vector<::aidl::android::hardware::power::stats::StateResidencyResult> results; if (!powerStatsService->getStateResidency(powerEntityIds, &results).isOk()) { LOG(ERROR) << __func__ << ": Unable to get state residency"; return 1; return INVALID_OPERATION; } for (const auto& result : results) { Loading @@ -147,7 +149,7 @@ int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { } return a.state_name < b.state_name; }); return 0; return NO_ERROR; } } // namespace android::media::psh_utils media/psh_utils/PowerStatsProvider.h +2 −2 Original line number Diff line number Diff line Loading @@ -23,12 +23,12 @@ namespace android::media::psh_utils { class RailEnergyDataProvider : public PowerStatsProvider { public: int fill(PowerStats* stat) const override; status_t fill(PowerStats* stat) const override; }; class PowerEntityResidencyDataProvider : public PowerStatsProvider { public: int fill(PowerStats* stat) const override; status_t fill(PowerStats* stat) const override; }; } // namespace android::media::psh_utils media/psh_utils/include/psh_utils/PowerStatsCollector.h +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "PowerStats.h" #include <memory> #include <utils/Errors.h> // status_t namespace android::media::psh_utils { Loading @@ -25,7 +26,7 @@ namespace android::media::psh_utils { class PowerStatsProvider { public: virtual ~PowerStatsProvider() = default; virtual int fill(PowerStats* stat) const = 0; virtual status_t fill(PowerStats* stat) const = 0; }; class PowerStatsCollector { Loading media/psh_utils/tests/powerstats_collector_tests.cpp +110 −13 Original line number Diff line number Diff line Loading @@ -18,8 +18,16 @@ #include <gtest/gtest.h> #include <utils/Log.h> using namespace android::media::psh_utils; template <typename T> void inRange(const T& a, const T& b, const T& c) { ASSERT_GE(a, std::min(b, c)); ASSERT_LE(a, std::max(b, c)); } TEST(powerstat_collector_tests, basic) { const auto& psc = android::media::psh_utils::PowerStatsCollector::getCollector(); const auto& psc = PowerStatsCollector::getCollector(); // This test is used for debugging the string through logcat, we validate a non-empty string. auto powerStats = psc.getStats(); Loading @@ -27,19 +35,108 @@ TEST(powerstat_collector_tests, basic) { EXPECT_FALSE(powerStats->toString().empty()); } TEST(powerstat_collector_tests, arithmetic) { android::media::psh_utils::PowerStats ps1, ps2; ps1.metadata.duration_ms = 5; ps2.metadata.duration_ms = 10; TEST(powerstat_collector_tests, metadata) { PowerStats ps1, ps2; constexpr uint64_t kDurationMs1 = 5; constexpr uint64_t kDurationMs2 = 10; ps1.metadata.duration_ms = kDurationMs1; ps2.metadata.duration_ms = kDurationMs2; constexpr uint64_t kDurationMonotonicMs1 = 3; constexpr uint64_t kDurationMonotonicMs2 = 9; ps1.metadata.duration_monotonic_ms = kDurationMonotonicMs1; ps2.metadata.duration_monotonic_ms = kDurationMonotonicMs2; constexpr uint64_t kStartTimeSinceBootMs1 = 1616; constexpr uint64_t kStartTimeEpochMs1 = 1121; constexpr uint64_t kStartTimeMonotonicMs1 = 1525; constexpr uint64_t kStartTimeSinceBootMs2 = 2616; constexpr uint64_t kStartTimeEpochMs2 = 2121; constexpr uint64_t kStartTimeMonotonicMs2 = 2525; ps1.metadata.start_time_since_boot_ms = kStartTimeSinceBootMs1; ps1.metadata.start_time_epoch_ms = kStartTimeEpochMs1; ps1.metadata.start_time_monotonic_ms = kStartTimeMonotonicMs1; ps2.metadata.start_time_since_boot_ms = kStartTimeSinceBootMs2; ps2.metadata.start_time_epoch_ms = kStartTimeEpochMs2; ps2.metadata.start_time_monotonic_ms = kStartTimeMonotonicMs2; PowerStats ps3 = ps1 + ps2; PowerStats ps4 = ps2 + ps1; EXPECT_EQ(ps3, ps4); EXPECT_EQ(kDurationMs1 + kDurationMs2, ps3.metadata.duration_ms); EXPECT_EQ(kDurationMonotonicMs1 + kDurationMonotonicMs2, ps3.metadata.duration_monotonic_ms); EXPECT_NO_FATAL_FAILURE(inRange(ps3.metadata.start_time_since_boot_ms, kStartTimeSinceBootMs1, kStartTimeSinceBootMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps3.metadata.start_time_epoch_ms, kStartTimeEpochMs1, kStartTimeEpochMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps3.metadata.start_time_monotonic_ms, kStartTimeMonotonicMs1, kStartTimeMonotonicMs2)); PowerStats ps5 = ps2 - ps1; EXPECT_EQ(kDurationMs2 - kDurationMs1, ps5.metadata.duration_ms); EXPECT_EQ(kDurationMonotonicMs2 - kDurationMonotonicMs1, ps5.metadata.duration_monotonic_ms); EXPECT_NO_FATAL_FAILURE(inRange(ps5.metadata.start_time_since_boot_ms, kStartTimeSinceBootMs1, kStartTimeSinceBootMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps5.metadata.start_time_epoch_ms, kStartTimeEpochMs1, kStartTimeEpochMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps5.metadata.start_time_monotonic_ms, kStartTimeMonotonicMs1, kStartTimeMonotonicMs2)); } TEST(powerstat_collector_tests, state_residency) { PowerStats ps1, ps2; constexpr uint64_t kTimeMs1 = 5; constexpr uint64_t kTimeMs2 = 10; constexpr uint64_t kEntryCount1 = 15; constexpr uint64_t kEntryCount2 = 18; ps1.power_entity_state_residency.emplace_back( PowerStats::StateResidency{"", "", kTimeMs1, kEntryCount1}); ps2.power_entity_state_residency.emplace_back( PowerStats::StateResidency{"", "", kTimeMs2, kEntryCount2}); PowerStats ps3 = ps1 + ps2; PowerStats ps4 = ps2 + ps1; EXPECT_EQ(ps3, ps4); EXPECT_EQ(kTimeMs1 + kTimeMs2, ps3.power_entity_state_residency[0].time_ms); EXPECT_EQ(kEntryCount1 + kEntryCount2, ps3.power_entity_state_residency[0].entry_count); PowerStats ps5 = ps2 - ps1; EXPECT_EQ(kTimeMs2 - kTimeMs1, ps5.power_entity_state_residency[0].time_ms); EXPECT_EQ(kEntryCount2 - kEntryCount1, ps5.power_entity_state_residency[0].entry_count); } TEST(powerstat_collector_tests, rail_energy) { PowerStats ps1, ps2; constexpr uint64_t kEnergyUws1 = 5; constexpr uint64_t kEnergyUws2 = 10; ps1.rail_energy.emplace_back( PowerStats::RailEnergy{"", "", kEnergyUws1}); ps2.rail_energy.emplace_back( PowerStats::RailEnergy{"", "", kEnergyUws2}); // duration follows add / subtract rules. android::media::psh_utils::PowerStats ps3 = ps1 + ps2; android::media::psh_utils::PowerStats ps4 = ps2 + ps1; PowerStats ps3 = ps1 + ps2; PowerStats ps4 = ps2 + ps1; EXPECT_EQ(ps3, ps4); EXPECT_EQ(15, ps3.metadata.duration_ms); EXPECT_EQ(kEnergyUws1 + kEnergyUws2, ps3.rail_energy[0].energy_uws); android::media::psh_utils::PowerStats ps5 = ps2 - ps1; android::media::psh_utils::PowerStats ps6 = ps5 + ps1; EXPECT_EQ(ps6, ps2); EXPECT_EQ(5, ps5.metadata.duration_ms); PowerStats ps5 = ps2 - ps1; EXPECT_EQ(kEnergyUws2 - kEnergyUws1, ps5.rail_energy[0].energy_uws); } Loading
media/psh_utils/PowerStatsProvider.cpp +12 −10 Original line number Diff line number Diff line Loading @@ -41,11 +41,12 @@ static auto getPowerStatsService() { return powerStats; } int RailEnergyDataProvider::fill(PowerStats *stat) const { status_t RailEnergyDataProvider::fill(PowerStats *stat) const { if (stat == nullptr) return BAD_VALUE; auto powerStatsService = getPowerStatsService(); if (powerStatsService == nullptr) { LOG(ERROR) << "unable to get power.stats AIDL service"; return 1; return NO_INIT; } std::unordered_map<int32_t, ::aidl::android::hardware::power::stats::Channel> channelMap; Loading @@ -53,7 +54,7 @@ int RailEnergyDataProvider::fill(PowerStats *stat) const { std::vector<::aidl::android::hardware::power::stats::Channel> channels; if (!powerStatsService->getEnergyMeterInfo(&channels).isOk()) { LOG(ERROR) << "unable to get energy meter info"; return 1; return INVALID_OPERATION; } for (auto& channel : channels) { channelMap.emplace(channel.id, std::move(channel)); Loading @@ -63,7 +64,7 @@ int RailEnergyDataProvider::fill(PowerStats *stat) const { std::vector<::aidl::android::hardware::power::stats::EnergyMeasurement> measurements; if (!powerStatsService->readEnergyMeter({}, &measurements).isOk()) { LOG(ERROR) << "unable to get energy measurements"; return 1; return INVALID_OPERATION; } for (const auto& measurement : measurements) { Loading @@ -83,14 +84,15 @@ int RailEnergyDataProvider::fill(PowerStats *stat) const { return a.rail_name < b.rail_name; }); return 0; return NO_ERROR; } int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { status_t PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { if (stat == nullptr) return BAD_VALUE; auto powerStatsService = getPowerStatsService(); if (powerStatsService == nullptr) { LOG(ERROR) << "unable to get power.stats AIDL service"; return 1; return NO_INIT; } // these are based on entityId Loading @@ -102,7 +104,7 @@ int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { std::vector<::aidl::android::hardware::power::stats::PowerEntity> entities; if (!powerStatsService->getPowerEntityInfo(&entities).isOk()) { LOG(ERROR) << __func__ << ": unable to get entity info"; return 1; return INVALID_OPERATION; } std::vector<std::string> powerEntityNames; Loading @@ -124,7 +126,7 @@ int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { std::vector<::aidl::android::hardware::power::stats::StateResidencyResult> results; if (!powerStatsService->getStateResidency(powerEntityIds, &results).isOk()) { LOG(ERROR) << __func__ << ": Unable to get state residency"; return 1; return INVALID_OPERATION; } for (const auto& result : results) { Loading @@ -147,7 +149,7 @@ int PowerEntityResidencyDataProvider::fill(PowerStats* stat) const { } return a.state_name < b.state_name; }); return 0; return NO_ERROR; } } // namespace android::media::psh_utils
media/psh_utils/PowerStatsProvider.h +2 −2 Original line number Diff line number Diff line Loading @@ -23,12 +23,12 @@ namespace android::media::psh_utils { class RailEnergyDataProvider : public PowerStatsProvider { public: int fill(PowerStats* stat) const override; status_t fill(PowerStats* stat) const override; }; class PowerEntityResidencyDataProvider : public PowerStatsProvider { public: int fill(PowerStats* stat) const override; status_t fill(PowerStats* stat) const override; }; } // namespace android::media::psh_utils
media/psh_utils/include/psh_utils/PowerStatsCollector.h +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include "PowerStats.h" #include <memory> #include <utils/Errors.h> // status_t namespace android::media::psh_utils { Loading @@ -25,7 +26,7 @@ namespace android::media::psh_utils { class PowerStatsProvider { public: virtual ~PowerStatsProvider() = default; virtual int fill(PowerStats* stat) const = 0; virtual status_t fill(PowerStats* stat) const = 0; }; class PowerStatsCollector { Loading
media/psh_utils/tests/powerstats_collector_tests.cpp +110 −13 Original line number Diff line number Diff line Loading @@ -18,8 +18,16 @@ #include <gtest/gtest.h> #include <utils/Log.h> using namespace android::media::psh_utils; template <typename T> void inRange(const T& a, const T& b, const T& c) { ASSERT_GE(a, std::min(b, c)); ASSERT_LE(a, std::max(b, c)); } TEST(powerstat_collector_tests, basic) { const auto& psc = android::media::psh_utils::PowerStatsCollector::getCollector(); const auto& psc = PowerStatsCollector::getCollector(); // This test is used for debugging the string through logcat, we validate a non-empty string. auto powerStats = psc.getStats(); Loading @@ -27,19 +35,108 @@ TEST(powerstat_collector_tests, basic) { EXPECT_FALSE(powerStats->toString().empty()); } TEST(powerstat_collector_tests, arithmetic) { android::media::psh_utils::PowerStats ps1, ps2; ps1.metadata.duration_ms = 5; ps2.metadata.duration_ms = 10; TEST(powerstat_collector_tests, metadata) { PowerStats ps1, ps2; constexpr uint64_t kDurationMs1 = 5; constexpr uint64_t kDurationMs2 = 10; ps1.metadata.duration_ms = kDurationMs1; ps2.metadata.duration_ms = kDurationMs2; constexpr uint64_t kDurationMonotonicMs1 = 3; constexpr uint64_t kDurationMonotonicMs2 = 9; ps1.metadata.duration_monotonic_ms = kDurationMonotonicMs1; ps2.metadata.duration_monotonic_ms = kDurationMonotonicMs2; constexpr uint64_t kStartTimeSinceBootMs1 = 1616; constexpr uint64_t kStartTimeEpochMs1 = 1121; constexpr uint64_t kStartTimeMonotonicMs1 = 1525; constexpr uint64_t kStartTimeSinceBootMs2 = 2616; constexpr uint64_t kStartTimeEpochMs2 = 2121; constexpr uint64_t kStartTimeMonotonicMs2 = 2525; ps1.metadata.start_time_since_boot_ms = kStartTimeSinceBootMs1; ps1.metadata.start_time_epoch_ms = kStartTimeEpochMs1; ps1.metadata.start_time_monotonic_ms = kStartTimeMonotonicMs1; ps2.metadata.start_time_since_boot_ms = kStartTimeSinceBootMs2; ps2.metadata.start_time_epoch_ms = kStartTimeEpochMs2; ps2.metadata.start_time_monotonic_ms = kStartTimeMonotonicMs2; PowerStats ps3 = ps1 + ps2; PowerStats ps4 = ps2 + ps1; EXPECT_EQ(ps3, ps4); EXPECT_EQ(kDurationMs1 + kDurationMs2, ps3.metadata.duration_ms); EXPECT_EQ(kDurationMonotonicMs1 + kDurationMonotonicMs2, ps3.metadata.duration_monotonic_ms); EXPECT_NO_FATAL_FAILURE(inRange(ps3.metadata.start_time_since_boot_ms, kStartTimeSinceBootMs1, kStartTimeSinceBootMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps3.metadata.start_time_epoch_ms, kStartTimeEpochMs1, kStartTimeEpochMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps3.metadata.start_time_monotonic_ms, kStartTimeMonotonicMs1, kStartTimeMonotonicMs2)); PowerStats ps5 = ps2 - ps1; EXPECT_EQ(kDurationMs2 - kDurationMs1, ps5.metadata.duration_ms); EXPECT_EQ(kDurationMonotonicMs2 - kDurationMonotonicMs1, ps5.metadata.duration_monotonic_ms); EXPECT_NO_FATAL_FAILURE(inRange(ps5.metadata.start_time_since_boot_ms, kStartTimeSinceBootMs1, kStartTimeSinceBootMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps5.metadata.start_time_epoch_ms, kStartTimeEpochMs1, kStartTimeEpochMs2)); EXPECT_NO_FATAL_FAILURE(inRange(ps5.metadata.start_time_monotonic_ms, kStartTimeMonotonicMs1, kStartTimeMonotonicMs2)); } TEST(powerstat_collector_tests, state_residency) { PowerStats ps1, ps2; constexpr uint64_t kTimeMs1 = 5; constexpr uint64_t kTimeMs2 = 10; constexpr uint64_t kEntryCount1 = 15; constexpr uint64_t kEntryCount2 = 18; ps1.power_entity_state_residency.emplace_back( PowerStats::StateResidency{"", "", kTimeMs1, kEntryCount1}); ps2.power_entity_state_residency.emplace_back( PowerStats::StateResidency{"", "", kTimeMs2, kEntryCount2}); PowerStats ps3 = ps1 + ps2; PowerStats ps4 = ps2 + ps1; EXPECT_EQ(ps3, ps4); EXPECT_EQ(kTimeMs1 + kTimeMs2, ps3.power_entity_state_residency[0].time_ms); EXPECT_EQ(kEntryCount1 + kEntryCount2, ps3.power_entity_state_residency[0].entry_count); PowerStats ps5 = ps2 - ps1; EXPECT_EQ(kTimeMs2 - kTimeMs1, ps5.power_entity_state_residency[0].time_ms); EXPECT_EQ(kEntryCount2 - kEntryCount1, ps5.power_entity_state_residency[0].entry_count); } TEST(powerstat_collector_tests, rail_energy) { PowerStats ps1, ps2; constexpr uint64_t kEnergyUws1 = 5; constexpr uint64_t kEnergyUws2 = 10; ps1.rail_energy.emplace_back( PowerStats::RailEnergy{"", "", kEnergyUws1}); ps2.rail_energy.emplace_back( PowerStats::RailEnergy{"", "", kEnergyUws2}); // duration follows add / subtract rules. android::media::psh_utils::PowerStats ps3 = ps1 + ps2; android::media::psh_utils::PowerStats ps4 = ps2 + ps1; PowerStats ps3 = ps1 + ps2; PowerStats ps4 = ps2 + ps1; EXPECT_EQ(ps3, ps4); EXPECT_EQ(15, ps3.metadata.duration_ms); EXPECT_EQ(kEnergyUws1 + kEnergyUws2, ps3.rail_energy[0].energy_uws); android::media::psh_utils::PowerStats ps5 = ps2 - ps1; android::media::psh_utils::PowerStats ps6 = ps5 + ps1; EXPECT_EQ(ps6, ps2); EXPECT_EQ(5, ps5.metadata.duration_ms); PowerStats ps5 = ps2 - ps1; EXPECT_EQ(kEnergyUws2 - kEnergyUws1, ps5.rail_energy[0].energy_uws); }