diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp index b4ccc7db6b..4926b91830 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/Android.bp @@ -35,6 +35,7 @@ cc_binary { "libbinder_ndk", "libcutils", "libfmq", + "libutils", ], srcs: [ "main.cpp", diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp index 8f15663db9..64294e5229 100644 --- a/power/aidl/default/Power.cpp +++ b/power/aidl/default/Power.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace aidl { namespace android { @@ -85,10 +86,17 @@ ndk::ScopedAStatus Power::createHintSessionWithConfig( } ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) { - static AidlMessageQueue stubQueue{1, true}; + static AidlMessageQueue stubQueue{20, true}; + static std::thread stubThread([&] { + ChannelMessage data; + // This loop will only run while there is data waiting + // to be processed, and blocks on a futex all other times + while (stubQueue.readBlocking(&data, 1, 0)) { + } + }); _aidl_return->channelDescriptor = stubQueue.dupeDesc(); - _aidl_return->readFlagBitmask = 0; - _aidl_return->writeFlagBitmask = 0; + _aidl_return->readFlagBitmask = 0x01; + _aidl_return->writeFlagBitmask = 0x02; _aidl_return->eventFlagDescriptor = std::nullopt; return ndk::ScopedAStatus::ok(); } diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp index d8e73bf4b0..53fcef1a41 100644 --- a/power/aidl/vts/VtsHalPowerTargetTest.cpp +++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp @@ -30,13 +30,13 @@ #include #include #include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h" -#include "fmq/EventFlag.h" namespace aidl::android::hardware::power { namespace { using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; using ::android::AidlMessageQueue; +using ::android::hardware::EventFlag; using android::hardware::power::Boost; using android::hardware::power::ChannelConfig; using android::hardware::power::ChannelMessage; @@ -46,8 +46,12 @@ using android::hardware::power::Mode; using android::hardware::power::SessionHint; using android::hardware::power::SessionMode; using android::hardware::power::WorkDuration; +using ChannelMessageContents = ChannelMessage::ChannelMessageContents; +using ModeSetter = ChannelMessage::ChannelMessageContents::SessionModeSetter; +using MessageTag = ChannelMessage::ChannelMessageContents::Tag; using SessionMessageQueue = AidlMessageQueue; +using FlagMessageQueue = AidlMessageQueue; const std::vector kBoosts{ndk::enum_range().begin(), ndk::enum_range().end()}; @@ -139,6 +143,51 @@ class HintSessionAidl : public PowerAidl { std::shared_ptr mSession; }; +class FMQAidl : public PowerAidl { + public: + virtual void SetUp() override { + PowerAidl::SetUp(); + if (mServiceVersion < 5) { + GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond."; + } + + auto status = + power->createHintSessionWithConfig(getpid(), getuid(), kSelfTids, 16666666L, + SessionTag::OTHER, &mSessionConfig, &mSession); + ASSERT_TRUE(status.isOk()); + ASSERT_NE(nullptr, mSession); + + status = power->getSessionChannel(getpid(), getuid(), &mChannelConfig); + ASSERT_TRUE(status.isOk()); + mChannel = std::make_shared(mChannelConfig.channelDescriptor, true); + ASSERT_TRUE(mChannel->isValid()); + + if (mChannelConfig.eventFlagDescriptor.has_value()) { + mFlagChannel = + std::make_shared(*mChannelConfig.eventFlagDescriptor, true); + ASSERT_EQ(EventFlag::createEventFlag(mFlagChannel->getEventFlagWord(), &mEventFlag), + ::android::OK); + } else { + ASSERT_EQ(EventFlag::createEventFlag(mChannel->getEventFlagWord(), &mEventFlag), + ::android::OK); + } + + ASSERT_NE(mEventFlag, nullptr); + } + virtual void TearDown() { + mSession->close(); + ASSERT_TRUE(power->closeSessionChannel(getpid(), getuid()).isOk()); + } + + protected: + std::shared_ptr mSession; + std::shared_ptr mChannel; + std::shared_ptr mFlagChannel; + SessionConfig mSessionConfig; + ChannelConfig mChannelConfig; + ::android::hardware::EventFlag* mEventFlag; +}; + TEST_P(PowerAidl, setMode) { for (const auto& mode : kModes) { ASSERT_TRUE(power->setMode(mode, true).isOk()); @@ -213,16 +262,12 @@ TEST_P(PowerAidl, createHintSessionWithConfig) { ASSERT_NE(nullptr, session); } -TEST_P(PowerAidl, getAndCloseSessionChannel) { - if (mServiceVersion < 5) { - GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond."; - } - ChannelConfig config; - auto status = power->getSessionChannel(getpid(), getuid(), &config); - ASSERT_TRUE(status.isOk()); - auto messageQueue = std::make_shared(config.channelDescriptor, true); - ASSERT_TRUE(messageQueue->isValid()); - ASSERT_TRUE(power->closeSessionChannel(getpid(), getuid()).isOk()); +// FIXED_PERFORMANCE mode is required for all devices which ship on Android 11 +// or later +TEST_P(PowerAidl, hasFixedPerformance) { + bool supported; + ASSERT_TRUE(power->isModeSupported(Mode::FIXED_PERFORMANCE, &supported).isOk()); + ASSERT_TRUE(supported); } TEST_P(HintSessionAidl, createAndCloseHintSession) { @@ -295,16 +340,61 @@ TEST_P(HintSessionAidl, getSessionConfig) { ASSERT_TRUE(mSession->getSessionConfig(&config).isOk()); } -// FIXED_PERFORMANCE mode is required for all devices which ship on Android 11 -// or later -TEST_P(PowerAidl, hasFixedPerformance) { - bool supported; - ASSERT_TRUE(power->isModeSupported(Mode::FIXED_PERFORMANCE, &supported).isOk()); - ASSERT_TRUE(supported); +TEST_P(FMQAidl, getAndCloseSessionChannel) {} + +TEST_P(FMQAidl, writeItems) { + std::vector messages{ + {.sessionID = static_cast(mSessionConfig.id), + .timeStampNanos = 1000, + .data = ChannelMessageContents::make( + {.durationNanos = 1000, + .workPeriodStartTimestampNanos = 10, + .cpuDurationNanos = 900, + .gpuDurationNanos = 100})}, + {.sessionID = static_cast(mSessionConfig.id), + .timeStampNanos = 1000, + .data = ChannelMessageContents::make( + {.modeInt = SessionMode::POWER_EFFICIENCY, .enabled = true})}, + {.sessionID = static_cast(mSessionConfig.id), + .timeStampNanos = 1000, + .data = ChannelMessageContents::make( + SessionHint::CPU_LOAD_UP)}, + {.sessionID = static_cast(mSessionConfig.id), + .timeStampNanos = 1000, + .data = ChannelMessageContents::make( + 10000000 /* 10ms */)}, + }; + for (auto& message : messages) { + ASSERT_TRUE(mChannel->writeBlocking(&message, 1, mChannelConfig.readFlagBitmask, + mChannelConfig.writeFlagBitmask, 100000000, + mEventFlag)); + } + // Make sure this still works after everything else is done to check crash + ASSERT_TRUE(mSession->setThreads(kSelfTids).isOk()); +} + +TEST_P(FMQAidl, writeExcess) { + std::vector messages; + size_t channelSize = mChannel->getQuantumCount(); + for (size_t i = 0; i < channelSize; ++i) { + messages.push_back({.sessionID = static_cast(mSessionConfig.id), + .timeStampNanos = 1000, + .data = ChannelMessageContents::make( + SessionHint::CPU_LOAD_UP)}); + } + ASSERT_TRUE(mChannel->writeBlocking(messages.data(), messages.size(), + mChannelConfig.readFlagBitmask, + mChannelConfig.writeFlagBitmask, 100000000, mEventFlag)); + ASSERT_TRUE(mChannel->writeBlocking(messages.data(), messages.size(), + mChannelConfig.readFlagBitmask, + mChannelConfig.writeFlagBitmask, 1000000000, mEventFlag)); + // Make sure this still works after everything else is done to check crash + ASSERT_TRUE(mSession->setThreads(kSelfTids).isOk()); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerAidl); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HintSessionAidl); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FMQAidl); INSTANTIATE_TEST_SUITE_P(Power, PowerAidl, testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)), @@ -312,6 +402,9 @@ INSTANTIATE_TEST_SUITE_P(Power, PowerAidl, INSTANTIATE_TEST_SUITE_P(Power, HintSessionAidl, testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)), ::android::PrintInstanceNameToString); +INSTANTIATE_TEST_SUITE_P(Power, FMQAidl, + testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)), + ::android::PrintInstanceNameToString); } // namespace } // namespace aidl::android::hardware::power