Loading services/surfaceflinger/SurfaceFlinger.cpp +6 −1 Original line number Original line Diff line number Diff line Loading @@ -3570,6 +3570,10 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { }); }); } } if (transactionFlags & eInputInfoUpdateNeeded) { mUpdateInputInfo = true; } doCommitTransactions(); doCommitTransactions(); } } Loading Loading @@ -7561,8 +7565,9 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD } } status_t SurfaceFlinger::addWindowInfosListener( status_t SurfaceFlinger::addWindowInfosListener( const sp<IWindowInfosListener>& windowInfosListener) const { const sp<IWindowInfosListener>& windowInfosListener) { mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener); mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener); setTransactionFlags(eInputInfoUpdateNeeded); return NO_ERROR; return NO_ERROR; } } Loading services/surfaceflinger/SurfaceFlinger.h +3 −2 Original line number Original line Diff line number Diff line Loading @@ -162,7 +162,8 @@ enum { eDisplayTransactionNeeded = 0x04, eDisplayTransactionNeeded = 0x04, eTransformHintUpdateNeeded = 0x08, eTransformHintUpdateNeeded = 0x08, eTransactionFlushNeeded = 0x10, eTransactionFlushNeeded = 0x10, eTransactionMask = 0x1f, eInputInfoUpdateNeeded = 0x20, eTransactionMask = 0x3f, }; }; // Latch Unsignaled buffer behaviours // Latch Unsignaled buffer behaviours Loading Loading @@ -618,7 +619,7 @@ private: status_t getMaxAcquiredBufferCount(int* buffers) const; status_t getMaxAcquiredBufferCount(int* buffers) const; status_t addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener) const; status_t addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); status_t removeWindowInfosListener( status_t removeWindowInfosListener( const sp<gui::IWindowInfosListener>& windowInfosListener) const; const sp<gui::IWindowInfosListener>& windowInfosListener) const; Loading services/surfaceflinger/WindowInfosListenerInvoker.cpp +0 −1 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ #include <ftl/small_vector.h> #include <ftl/small_vector.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h> #include "SurfaceFlinger.h" #include "WindowInfosListenerInvoker.h" #include "WindowInfosListenerInvoker.h" namespace android { namespace android { Loading services/surfaceflinger/WindowInfosListenerInvoker.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ #pragma once #pragma once #include <unordered_set> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/IWindowInfosListener.h> #include <android/gui/IWindowInfosListener.h> #include <android/gui/IWindowInfosReportedListener.h> #include <android/gui/IWindowInfosReportedListener.h> Loading Loading @@ -49,8 +51,6 @@ private: static constexpr size_t kStaticCapacity = 3; static constexpr size_t kStaticCapacity = 3; ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity> ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity> mWindowInfosListeners GUARDED_BY(mListenersMutex); mWindowInfosListeners GUARDED_BY(mListenersMutex); sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener; }; }; } // namespace android } // namespace android services/surfaceflinger/tests/WindowInfosListener_test.cpp +49 −38 Original line number Original line Diff line number Diff line Loading @@ -18,61 +18,61 @@ #include <gui/SurfaceComposerClient.h> #include <gui/SurfaceComposerClient.h> #include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h> #include <future> #include <future> #include "utils/TransactionUtils.h" namespace android { namespace android { using Transaction = SurfaceComposerClient::Transaction; using Transaction = SurfaceComposerClient::Transaction; using gui::DisplayInfo; using gui::DisplayInfo; using gui::WindowInfo; using gui::WindowInfo; using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>; class WindowInfosListenerTest : public ::testing::Test { class WindowInfosListenerTest : public ::testing::Test { protected: protected: void SetUp() override { void SetUp() override { seteuid(AID_SYSTEM); seteuid(AID_SYSTEM); mClient = sp<SurfaceComposerClient>::make(); mClient = sp<SurfaceComposerClient>::make(); mWindowInfosListener = sp<SyncWindowInfosListener>::make(); mClient->addWindowInfosListener(mWindowInfosListener); } } void TearDown() override { void TearDown() override { seteuid(AID_ROOT); } mClient->removeWindowInfosListener(mWindowInfosListener); seteuid(AID_ROOT); } struct SyncWindowInfosListener : public gui::WindowInfosListener { struct WindowInfosListener : public gui::WindowInfosListener { public: public: WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise) : mPredicate(std::move(predicate)), mPromise(promise) {} void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos, void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>&) override { const std::vector<DisplayInfo>&) override { windowInfosPromise.set_value(windowInfos); if (mPredicate(windowInfos)) { mPromise.set_value(); } } std::vector<WindowInfo> waitForWindowInfos() { std::future<std::vector<WindowInfo>> windowInfosFuture = windowInfosPromise.get_future(); std::vector<WindowInfo> windowInfos = windowInfosFuture.get(); windowInfosPromise = std::promise<std::vector<WindowInfo>>(); return windowInfos; } } private: private: std::promise<std::vector<WindowInfo>> windowInfosPromise; WindowInfosPredicate mPredicate; std::promise<void>& mPromise; }; }; sp<SurfaceComposerClient> mClient; sp<SurfaceComposerClient> mClient; sp<SyncWindowInfosListener> mWindowInfosListener; bool waitForWindowInfosPredicate(WindowInfosPredicate predicate) { std::promise<void> promise; auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); mClient->addWindowInfosListener(listener); auto future = promise.get_future(); bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; mClient->removeWindowInfosListener(listener); return satisfied; } }; }; std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo, std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo, std::vector<WindowInfo> windowInfos) { std::vector<WindowInfo> windowInfos) { std::optional<WindowInfo> foundWindowInfo = std::nullopt; for (WindowInfo windowInfo : windowInfos) { for (WindowInfo windowInfo : windowInfos) { if (windowInfo.token == targetWindowInfo.token) { if (windowInfo.token == targetWindowInfo.token) { foundWindowInfo = std::make_optional<>(windowInfo); return windowInfo; break; } } } } return std::nullopt; return foundWindowInfo; } } TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { Loading @@ -92,15 +92,17 @@ TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { .setInputWindowInfo(surfaceControl, windowInfo) .setInputWindowInfo(surfaceControl, windowInfo) .apply(); .apply(); std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) { std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); return findMatchingWindowInfo(windowInfo, windowInfos).has_value(); ASSERT_NE(std::nullopt, foundWindowInfo); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent)); Transaction().reparent(surfaceControl, nullptr).apply(); Transaction().reparent(surfaceControl, nullptr).apply(); windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) { foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); return !findMatchingWindowInfo(windowInfo, windowInfos).has_value(); ASSERT_EQ(std::nullopt, foundWindowInfo); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent)); } } TEST_F(WindowInfosListenerTest, WindowInfoChanged) { TEST_F(WindowInfosListenerTest, WindowInfoChanged) { Loading @@ -121,19 +123,28 @@ TEST_F(WindowInfosListenerTest, WindowInfoChanged) { .setInputWindowInfo(surfaceControl, windowInfo) .setInputWindowInfo(surfaceControl, windowInfo) .apply(); .apply(); std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowIsPresentAndTouchableRegionEmpty = [&](const std::vector<WindowInfo>& windowInfos) { std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); ASSERT_NE(std::nullopt, foundWindowInfo); if (!foundWindowInfo) { ASSERT_TRUE(foundWindowInfo->touchableRegion.isEmpty()); return false; } return foundWindowInfo->touchableRegion.isEmpty(); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty)); Rect touchableRegions(0, 0, 50, 50); Rect touchableRegions(0, 0, 50, 50); windowInfo.addTouchableRegion(Rect(0, 0, 50, 50)); windowInfo.addTouchableRegion(Rect(0, 0, 50, 50)); Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply(); Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply(); windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowIsPresentAndTouchableRegionMatches = foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); [&](const std::vector<WindowInfo>& windowInfos) { ASSERT_NE(std::nullopt, foundWindowInfo); auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); ASSERT_TRUE(foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion)); if (!foundWindowInfo) { return false; } return foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches)); } } } // namespace android } // namespace android Loading
services/surfaceflinger/SurfaceFlinger.cpp +6 −1 Original line number Original line Diff line number Diff line Loading @@ -3570,6 +3570,10 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { }); }); } } if (transactionFlags & eInputInfoUpdateNeeded) { mUpdateInputInfo = true; } doCommitTransactions(); doCommitTransactions(); } } Loading Loading @@ -7561,8 +7565,9 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD } } status_t SurfaceFlinger::addWindowInfosListener( status_t SurfaceFlinger::addWindowInfosListener( const sp<IWindowInfosListener>& windowInfosListener) const { const sp<IWindowInfosListener>& windowInfosListener) { mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener); mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener); setTransactionFlags(eInputInfoUpdateNeeded); return NO_ERROR; return NO_ERROR; } } Loading
services/surfaceflinger/SurfaceFlinger.h +3 −2 Original line number Original line Diff line number Diff line Loading @@ -162,7 +162,8 @@ enum { eDisplayTransactionNeeded = 0x04, eDisplayTransactionNeeded = 0x04, eTransformHintUpdateNeeded = 0x08, eTransformHintUpdateNeeded = 0x08, eTransactionFlushNeeded = 0x10, eTransactionFlushNeeded = 0x10, eTransactionMask = 0x1f, eInputInfoUpdateNeeded = 0x20, eTransactionMask = 0x3f, }; }; // Latch Unsignaled buffer behaviours // Latch Unsignaled buffer behaviours Loading Loading @@ -618,7 +619,7 @@ private: status_t getMaxAcquiredBufferCount(int* buffers) const; status_t getMaxAcquiredBufferCount(int* buffers) const; status_t addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener) const; status_t addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); status_t removeWindowInfosListener( status_t removeWindowInfosListener( const sp<gui::IWindowInfosListener>& windowInfosListener) const; const sp<gui::IWindowInfosListener>& windowInfosListener) const; Loading
services/surfaceflinger/WindowInfosListenerInvoker.cpp +0 −1 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ #include <ftl/small_vector.h> #include <ftl/small_vector.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h> #include "SurfaceFlinger.h" #include "WindowInfosListenerInvoker.h" #include "WindowInfosListenerInvoker.h" namespace android { namespace android { Loading
services/surfaceflinger/WindowInfosListenerInvoker.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ #pragma once #pragma once #include <unordered_set> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/IWindowInfosListener.h> #include <android/gui/IWindowInfosListener.h> #include <android/gui/IWindowInfosReportedListener.h> #include <android/gui/IWindowInfosReportedListener.h> Loading Loading @@ -49,8 +51,6 @@ private: static constexpr size_t kStaticCapacity = 3; static constexpr size_t kStaticCapacity = 3; ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity> ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity> mWindowInfosListeners GUARDED_BY(mListenersMutex); mWindowInfosListeners GUARDED_BY(mListenersMutex); sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener; }; }; } // namespace android } // namespace android
services/surfaceflinger/tests/WindowInfosListener_test.cpp +49 −38 Original line number Original line Diff line number Diff line Loading @@ -18,61 +18,61 @@ #include <gui/SurfaceComposerClient.h> #include <gui/SurfaceComposerClient.h> #include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h> #include <future> #include <future> #include "utils/TransactionUtils.h" namespace android { namespace android { using Transaction = SurfaceComposerClient::Transaction; using Transaction = SurfaceComposerClient::Transaction; using gui::DisplayInfo; using gui::DisplayInfo; using gui::WindowInfo; using gui::WindowInfo; using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>; class WindowInfosListenerTest : public ::testing::Test { class WindowInfosListenerTest : public ::testing::Test { protected: protected: void SetUp() override { void SetUp() override { seteuid(AID_SYSTEM); seteuid(AID_SYSTEM); mClient = sp<SurfaceComposerClient>::make(); mClient = sp<SurfaceComposerClient>::make(); mWindowInfosListener = sp<SyncWindowInfosListener>::make(); mClient->addWindowInfosListener(mWindowInfosListener); } } void TearDown() override { void TearDown() override { seteuid(AID_ROOT); } mClient->removeWindowInfosListener(mWindowInfosListener); seteuid(AID_ROOT); } struct SyncWindowInfosListener : public gui::WindowInfosListener { struct WindowInfosListener : public gui::WindowInfosListener { public: public: WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise) : mPredicate(std::move(predicate)), mPromise(promise) {} void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos, void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>&) override { const std::vector<DisplayInfo>&) override { windowInfosPromise.set_value(windowInfos); if (mPredicate(windowInfos)) { mPromise.set_value(); } } std::vector<WindowInfo> waitForWindowInfos() { std::future<std::vector<WindowInfo>> windowInfosFuture = windowInfosPromise.get_future(); std::vector<WindowInfo> windowInfos = windowInfosFuture.get(); windowInfosPromise = std::promise<std::vector<WindowInfo>>(); return windowInfos; } } private: private: std::promise<std::vector<WindowInfo>> windowInfosPromise; WindowInfosPredicate mPredicate; std::promise<void>& mPromise; }; }; sp<SurfaceComposerClient> mClient; sp<SurfaceComposerClient> mClient; sp<SyncWindowInfosListener> mWindowInfosListener; bool waitForWindowInfosPredicate(WindowInfosPredicate predicate) { std::promise<void> promise; auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); mClient->addWindowInfosListener(listener); auto future = promise.get_future(); bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; mClient->removeWindowInfosListener(listener); return satisfied; } }; }; std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo, std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo, std::vector<WindowInfo> windowInfos) { std::vector<WindowInfo> windowInfos) { std::optional<WindowInfo> foundWindowInfo = std::nullopt; for (WindowInfo windowInfo : windowInfos) { for (WindowInfo windowInfo : windowInfos) { if (windowInfo.token == targetWindowInfo.token) { if (windowInfo.token == targetWindowInfo.token) { foundWindowInfo = std::make_optional<>(windowInfo); return windowInfo; break; } } } } return std::nullopt; return foundWindowInfo; } } TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { Loading @@ -92,15 +92,17 @@ TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { .setInputWindowInfo(surfaceControl, windowInfo) .setInputWindowInfo(surfaceControl, windowInfo) .apply(); .apply(); std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) { std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); return findMatchingWindowInfo(windowInfo, windowInfos).has_value(); ASSERT_NE(std::nullopt, foundWindowInfo); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent)); Transaction().reparent(surfaceControl, nullptr).apply(); Transaction().reparent(surfaceControl, nullptr).apply(); windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) { foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); return !findMatchingWindowInfo(windowInfo, windowInfos).has_value(); ASSERT_EQ(std::nullopt, foundWindowInfo); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent)); } } TEST_F(WindowInfosListenerTest, WindowInfoChanged) { TEST_F(WindowInfosListenerTest, WindowInfoChanged) { Loading @@ -121,19 +123,28 @@ TEST_F(WindowInfosListenerTest, WindowInfoChanged) { .setInputWindowInfo(surfaceControl, windowInfo) .setInputWindowInfo(surfaceControl, windowInfo) .apply(); .apply(); std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowIsPresentAndTouchableRegionEmpty = [&](const std::vector<WindowInfo>& windowInfos) { std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); ASSERT_NE(std::nullopt, foundWindowInfo); if (!foundWindowInfo) { ASSERT_TRUE(foundWindowInfo->touchableRegion.isEmpty()); return false; } return foundWindowInfo->touchableRegion.isEmpty(); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty)); Rect touchableRegions(0, 0, 50, 50); Rect touchableRegions(0, 0, 50, 50); windowInfo.addTouchableRegion(Rect(0, 0, 50, 50)); windowInfo.addTouchableRegion(Rect(0, 0, 50, 50)); Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply(); Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply(); windowInfos = mWindowInfosListener->waitForWindowInfos(); auto windowIsPresentAndTouchableRegionMatches = foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); [&](const std::vector<WindowInfo>& windowInfos) { ASSERT_NE(std::nullopt, foundWindowInfo); auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); ASSERT_TRUE(foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion)); if (!foundWindowInfo) { return false; } return foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches)); } } } // namespace android } // namespace android