Media: Update PowerStats with more test cases.
Flag: com.android.media.audioserver.power_stats
Test: atest powerstats_collector_tests
Bug: 350114693
Change-Id: I9e89e6b2598bca30eabc5e9c30592c4eb6dfeed3
diff --git a/media/psh_utils/PowerStatsProvider.cpp b/media/psh_utils/PowerStatsProvider.cpp
index 71a39e1..94df933 100644
--- a/media/psh_utils/PowerStatsProvider.cpp
+++ b/media/psh_utils/PowerStatsProvider.cpp
@@ -41,11 +41,12 @@
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;
@@ -53,7 +54,7 @@
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));
@@ -63,7 +64,7 @@
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) {
@@ -83,14 +84,15 @@
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
@@ -102,7 +104,7 @@
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;
@@ -124,7 +126,7 @@
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) {
@@ -147,7 +149,7 @@
}
return a.state_name < b.state_name;
});
- return 0;
+ return NO_ERROR;
}
} // namespace android::media::psh_utils
diff --git a/media/psh_utils/PowerStatsProvider.h b/media/psh_utils/PowerStatsProvider.h
index 367e684..2be1872 100644
--- a/media/psh_utils/PowerStatsProvider.h
+++ b/media/psh_utils/PowerStatsProvider.h
@@ -23,12 +23,12 @@
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
diff --git a/media/psh_utils/include/psh_utils/PowerStatsCollector.h b/media/psh_utils/include/psh_utils/PowerStatsCollector.h
index a3ff53c..437b93d 100644
--- a/media/psh_utils/include/psh_utils/PowerStatsCollector.h
+++ b/media/psh_utils/include/psh_utils/PowerStatsCollector.h
@@ -18,6 +18,7 @@
#include "PowerStats.h"
#include <memory>
+#include <utils/Errors.h> // status_t
namespace android::media::psh_utils {
@@ -25,7 +26,7 @@
class PowerStatsProvider {
public:
virtual ~PowerStatsProvider() = default;
- virtual int fill(PowerStats* stat) const = 0;
+ virtual status_t fill(PowerStats* stat) const = 0;
};
class PowerStatsCollector {
diff --git a/media/psh_utils/tests/powerstats_collector_tests.cpp b/media/psh_utils/tests/powerstats_collector_tests.cpp
index 6c83978..b007be3 100644
--- a/media/psh_utils/tests/powerstats_collector_tests.cpp
+++ b/media/psh_utils/tests/powerstats_collector_tests.cpp
@@ -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();
@@ -27,19 +35,108 @@
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;
- // duration follows add / subtract rules.
- android::media::psh_utils::PowerStats ps3 = ps1 + ps2;
- android::media::psh_utils::PowerStats ps4 = ps2 + ps1;
+ 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(15, ps3.metadata.duration_ms);
+ EXPECT_EQ(kDurationMs1 + kDurationMs2,
+ ps3.metadata.duration_ms);
+ EXPECT_EQ(kDurationMonotonicMs1 + kDurationMonotonicMs2,
+ ps3.metadata.duration_monotonic_ms);
- 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);
+ 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});
+
+ PowerStats ps3 = ps1 + ps2;
+ PowerStats ps4 = ps2 + ps1;
+ EXPECT_EQ(ps3, ps4);
+ EXPECT_EQ(kEnergyUws1 + kEnergyUws2,
+ ps3.rail_energy[0].energy_uws);
+
+ PowerStats ps5 = ps2 - ps1;
+ EXPECT_EQ(kEnergyUws2 - kEnergyUws1,
+ ps5.rail_energy[0].energy_uws);
}