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

Commit 57ddefa7 authored by Patrick Williams's avatar Patrick Williams Committed by Android (Google) Code Review
Browse files

Merge "Fix WindowInfosListenerTest" into udc-dev

parents 54f85e0c af06b797
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -3570,6 +3570,10 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
        });
        });
    }
    }


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

    doCommitTransactions();
    doCommitTransactions();
}
}


@@ -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;
}
}


+3 −2
Original line number Original line Diff line number Diff line
@@ -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
@@ -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;


+0 −1
Original line number Original line Diff line number Diff line
@@ -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 {
+2 −2
Original line number Original line Diff line number Diff line
@@ -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>
@@ -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
+49 −38
Original line number Original line Diff line number Diff line
@@ -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) {
@@ -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) {
@@ -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