Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb8fefeb authored by Patrick Williams's avatar Patrick Williams Committed by Automerger Merge Worker
Browse files

Merge "Fix WindowInfosListenerTest" into udc-dev am: 57ddefa7

parents 5c5a8064 57ddefa7
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -3570,6 +3570,10 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
        });
    }

    if (transactionFlags & eInputInfoUpdateNeeded) {
        mUpdateInputInfo = true;
    }

    doCommitTransactions();
}

@@ -7561,8 +7565,9 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD
}

status_t SurfaceFlinger::addWindowInfosListener(
        const sp<IWindowInfosListener>& windowInfosListener) const {
        const sp<IWindowInfosListener>& windowInfosListener) {
    mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener);
    setTransactionFlags(eInputInfoUpdateNeeded);
    return NO_ERROR;
}

+3 −2
Original line number Diff line number Diff line
@@ -162,7 +162,8 @@ enum {
    eDisplayTransactionNeeded = 0x04,
    eTransformHintUpdateNeeded = 0x08,
    eTransactionFlushNeeded = 0x10,
    eTransactionMask = 0x1f,
    eInputInfoUpdateNeeded = 0x20,
    eTransactionMask = 0x3f,
};

// Latch Unsignaled buffer behaviours
@@ -618,7 +619,7 @@ private:

    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(
            const sp<gui::IWindowInfosListener>& windowInfosListener) const;

+0 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
#include <ftl/small_vector.h>
#include <gui/ISurfaceComposer.h>

#include "SurfaceFlinger.h"
#include "WindowInfosListenerInvoker.h"

namespace android {
+2 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

#pragma once

#include <unordered_set>

#include <android/gui/BnWindowInfosReportedListener.h>
#include <android/gui/IWindowInfosListener.h>
#include <android/gui/IWindowInfosReportedListener.h>
@@ -49,8 +51,6 @@ private:
    static constexpr size_t kStaticCapacity = 3;
    ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity>
            mWindowInfosListeners GUARDED_BY(mListenersMutex);

    sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener;
};

} // namespace android
+49 −38
Original line number Diff line number Diff line
@@ -18,61 +18,61 @@
#include <gui/SurfaceComposerClient.h>
#include <private/android_filesystem_config.h>
#include <future>
#include "utils/TransactionUtils.h"

namespace android {
using Transaction = SurfaceComposerClient::Transaction;
using gui::DisplayInfo;
using gui::WindowInfo;

using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>;

class WindowInfosListenerTest : public ::testing::Test {
protected:
    void SetUp() override {
        seteuid(AID_SYSTEM);
        mClient = sp<SurfaceComposerClient>::make();
        mWindowInfosListener = sp<SyncWindowInfosListener>::make();
        mClient->addWindowInfosListener(mWindowInfosListener);
    }

    void TearDown() override {
        mClient->removeWindowInfosListener(mWindowInfosListener);
        seteuid(AID_ROOT);
    }
    void TearDown() override { seteuid(AID_ROOT); }

    struct SyncWindowInfosListener : public gui::WindowInfosListener {
    struct WindowInfosListener : public gui::WindowInfosListener {
    public:
        WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise)
              : mPredicate(std::move(predicate)), mPromise(promise) {}

        void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
                                  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:
        std::promise<std::vector<WindowInfo>> windowInfosPromise;
        WindowInfosPredicate mPredicate;
        std::promise<void>& mPromise;
    };

    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::vector<WindowInfo> windowInfos) {
    std::optional<WindowInfo> foundWindowInfo = std::nullopt;
    for (WindowInfo windowInfo : windowInfos) {
        if (windowInfo.token == targetWindowInfo.token) {
            foundWindowInfo = std::make_optional<>(windowInfo);
            break;
            return windowInfo;
        }
    }

    return foundWindowInfo;
    return std::nullopt;
}

TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
@@ -92,15 +92,17 @@ TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
            .setInputWindowInfo(surfaceControl, windowInfo)
            .apply();

    std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos();
    std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
    ASSERT_NE(std::nullopt, foundWindowInfo);
    auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) {
        return findMatchingWindowInfo(windowInfo, windowInfos).has_value();
    };
    ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent));

    Transaction().reparent(surfaceControl, nullptr).apply();

    windowInfos = mWindowInfosListener->waitForWindowInfos();
    foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
    ASSERT_EQ(std::nullopt, foundWindowInfo);
    auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) {
        return !findMatchingWindowInfo(windowInfo, windowInfos).has_value();
    };
    ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent));
}

TEST_F(WindowInfosListenerTest, WindowInfoChanged) {
@@ -121,19 +123,28 @@ TEST_F(WindowInfosListenerTest, WindowInfoChanged) {
            .setInputWindowInfo(surfaceControl, windowInfo)
            .apply();

    std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos();
    std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
    ASSERT_NE(std::nullopt, foundWindowInfo);
    ASSERT_TRUE(foundWindowInfo->touchableRegion.isEmpty());
    auto windowIsPresentAndTouchableRegionEmpty = [&](const std::vector<WindowInfo>& windowInfos) {
        auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
        if (!foundWindowInfo) {
            return false;
        }
        return foundWindowInfo->touchableRegion.isEmpty();
    };
    ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty));

    Rect touchableRegions(0, 0, 50, 50);
    windowInfo.addTouchableRegion(Rect(0, 0, 50, 50));
    Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply();

    windowInfos = mWindowInfosListener->waitForWindowInfos();
    foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
    ASSERT_NE(std::nullopt, foundWindowInfo);
    ASSERT_TRUE(foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion));
    auto windowIsPresentAndTouchableRegionMatches =
            [&](const std::vector<WindowInfo>& windowInfos) {
                auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
                if (!foundWindowInfo) {
                    return false;
                }
                return foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion);
            };
    ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches));
}

} // namespace android