diff options
author | Matt Buckley <mattbuckley@google.com> | 2024-04-16 21:09:01 +0000 |
---|---|---|
committer | Android Build Cherrypicker Worker <android-build-cherrypicker-worker@google.com> | 2024-04-16 21:09:01 +0000 |
commit | 6e495a7ca78d6f4f80b921051e8106f55abe9d6c (patch) | |
tree | da5f38788423eed440519a80b09d22f956202757 | |
parent | eaeac94025790b026f230a4377df06d239d3a8f9 (diff) | |
download | native-6e495a7ca78d6f4f80b921051e8106f55abe9d6c.tar.gz |
Fix flaky notifyPowerBoostNotifiesTouchEvent test
This patch fixes the flaky notifyPowerBoostNotifiesTouchEvent test by
forcing all operations to happen in a deterministic order, avoiding
races.
Bug: 332875603
Test: atest libsurfaceflinger_unittest:DisplayTransactionTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0fd347a02ea101c3557083ccb935342e42bc977c)
Merged-In: I882c8cce57f071ec0c4c4e59f1b00dcca090c650
Change-Id: I882c8cce57f071ec0c4c4e59f1b00dcca090c650
-rw-r--r-- | services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp | 37 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableScheduler.h | 17 |
2 files changed, 43 insertions, 11 deletions
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp index 22b72f98e5..f2e2c8a76f 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp @@ -33,24 +33,45 @@ using aidl::android::hardware::power::Boost; TEST_F(DisplayTransactionTest, notifyPowerBoostNotifiesTouchEvent) { using namespace std::chrono_literals; + std::mutex timerMutex; + std::condition_variable cv; + injectDefaultInternalDisplay([](FakeDisplayDeviceInjector&) {}); - mFlinger.scheduler()->replaceTouchTimer(100); - std::this_thread::sleep_for(10ms); // wait for callback to be triggered + std::unique_lock lock(timerMutex); + bool didReset = false; // keeps track of what the most recent call was + + auto waitForTimerReset = [&] { cv.wait_for(lock, 100ms, [&] { return didReset; }); }; + auto waitForTimerExpired = [&] { cv.wait_for(lock, 100ms, [&] { return !didReset; }); }; + + // Add extra logic to unblock the test when the timer callbacks get called + mFlinger.scheduler()->replaceTouchTimer(10, [&](bool isReset) { + { + std::unique_lock lock(timerMutex); // guarantee we're waiting on the cv + didReset = isReset; + } + cv.notify_one(); // wake the cv + std::unique_lock lock(timerMutex); // guarantee we finished the cv logic + }); + + waitForTimerReset(); EXPECT_TRUE(mFlinger.scheduler()->isTouchActive()); // Starting timer activates touch - std::this_thread::sleep_for(110ms); // wait for reset touch timer to expire and trigger callback - EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); + waitForTimerExpired(); + EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); // Stopping timer deactivates touch EXPECT_EQ(NO_ERROR, mFlinger.notifyPowerBoost(static_cast<int32_t>(Boost::CAMERA_SHOT))); - std::this_thread::sleep_for(10ms); // wait for callback to maybe be triggered - EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); - std::this_thread::sleep_for(110ms); // wait for reset touch timer to expire and trigger callback + EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); + // Wait for the timer to start just in case + waitForTimerReset(); + EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); + // Wait for the timer to stop, again just in case + waitForTimerExpired(); EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); EXPECT_EQ(NO_ERROR, mFlinger.notifyPowerBoost(static_cast<int32_t>(Boost::INTERACTION))); - std::this_thread::sleep_for(10ms); // wait for callback to be triggered. + waitForTimerReset(); EXPECT_TRUE(mFlinger.scheduler()->isTouchActive()); } diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h index 2a1b88e6fa..c0255d3e98 100644 --- a/services/surfaceflinger/tests/unittests/TestableScheduler.h +++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h @@ -136,14 +136,25 @@ public: return mLayerHistory.mActiveLayerInfos.size(); } - void replaceTouchTimer(int64_t millis) { + void replaceTouchTimer(int64_t millis, + std::function<void(bool isReset)>&& testCallback = nullptr) { if (mTouchTimer) { mTouchTimer.reset(); } mTouchTimer.emplace( "Testable Touch timer", std::chrono::milliseconds(millis), - [this] { touchTimerCallback(TimerState::Reset); }, - [this] { touchTimerCallback(TimerState::Expired); }); + [this, testCallback] { + touchTimerCallback(TimerState::Reset); + if (testCallback != nullptr) { + testCallback(true); + } + }, + [this, testCallback] { + touchTimerCallback(TimerState::Expired); + if (testCallback != nullptr) { + testCallback(false); + } + }); mTouchTimer->start(); } |