/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <poll.h>

#include <memory>

#include <android/keycodes.h>
#include <android/native_window.h>

#include <binder/Binder.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>

#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceControl.h>

#include <android/os/IInputFlinger.h>
#include <gui/WindowInfo.h>
#include <input/Input.h>
#include <input/InputTransport.h>

#include <ui/DisplayMode.h>
#include <ui/Rect.h>
#include <ui/Region.h>

#include <private/android_filesystem_config.h>

using android::os::IInputFlinger;

using android::hardware::graphics::common::V1_1::BufferUsage;

using android::gui::FocusRequest;
using android::gui::InputApplicationInfo;
using android::gui::TouchOcclusionMode;
using android::gui::WindowInfo;

namespace android::test {

using Transaction = SurfaceComposerClient::Transaction;

sp<IInputFlinger> getInputFlinger() {
   sp<IBinder> input(defaultServiceManager()->getService(
            String16("inputflinger")));
    if (input == nullptr) {
        ALOGE("Failed to link to input service");
    } else { ALOGE("Linked to input"); }
    return interface_cast<IInputFlinger>(input);
}

// We use the top 10 layers as a way to haphazardly place ourselves above anything else.
static const int LAYER_BASE = INT32_MAX - 10;
static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;

class InputSurface {
public:
    InputSurface(const sp<SurfaceControl> &sc, int width, int height, bool noInputChannel = false) {
        mSurfaceControl = sc;

        mInputFlinger = getInputFlinger();
        if (noInputChannel) {
            mInputInfo.setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
        } else {
            mClientChannel = std::make_shared<InputChannel>();
            mInputFlinger->createInputChannel("testchannels", mClientChannel.get());
            mInputInfo.token = mClientChannel->getConnectionToken();
            mInputConsumer = new InputConsumer(mClientChannel);
        }

        mInputInfo.name = "Test info";
        mInputInfo.dispatchingTimeout = 5s;
        mInputInfo.globalScaleFactor = 1.0;
        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));

        InputApplicationInfo aInfo;
        aInfo.token = new BBinder();
        aInfo.name = "Test app info";
        aInfo.dispatchingTimeoutMillis =
                std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
        mInputInfo.applicationInfo = aInfo;
    }

    static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient> &scc,
                                                               int width, int height) {
        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Surface"), 0 /* bufHeight */, 0 /* bufWidth */,
                                   PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eFXSurfaceEffect);
        return std::make_unique<InputSurface>(surfaceControl, width, height);
    }

    static std::unique_ptr<InputSurface> makeBufferInputSurface(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Buffer Surface"), width, height,
                                   PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
        return std::make_unique<InputSurface>(surfaceControl, width, height);
    }

    static std::unique_ptr<InputSurface> makeContainerInputSurface(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Container Surface"), 0 /* bufHeight */,
                                   0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eFXSurfaceContainer);
        return std::make_unique<InputSurface>(surfaceControl, width, height);
    }

    static std::unique_ptr<InputSurface> makeContainerInputSurfaceNoInputChannel(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Container Surface"), 100 /* height */,
                                   100 /* width */, PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eFXSurfaceContainer);
        return std::make_unique<InputSurface>(surfaceControl, width, height,
                                              true /* noInputChannel */);
    }

    static std::unique_ptr<InputSurface> makeCursorInputSurface(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Cursor Surface"), 0 /* bufHeight */,
                                   0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eCursorWindow);
        return std::make_unique<InputSurface>(surfaceControl, width, height);
    }

    InputEvent *consumeEvent(int timeoutMs = 3000) {
        waitForEventAvailable(timeoutMs);

        InputEvent *ev;
        uint32_t seqId;
        status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
        if (consumed != OK) {
            return nullptr;
        }
        status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
        EXPECT_EQ(OK, status) << "Could not send finished signal";
        return ev;
    }

    void assertFocusChange(bool hasFocus) {
        InputEvent *ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, ev->getType());
        FocusEvent *focusEvent = static_cast<FocusEvent *>(ev);
        EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
    }

    void expectTap(int x, int y) {
        InputEvent* ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        MotionEvent* mev = static_cast<MotionEvent*>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
        EXPECT_EQ(x, mev->getX(0));
        EXPECT_EQ(y, mev->getY(0));
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);

        ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        mev = static_cast<MotionEvent*>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
    }

    void expectTapWithFlag(int x, int y, int32_t flags) {
        InputEvent *ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        MotionEvent *mev = static_cast<MotionEvent *>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
        EXPECT_EQ(x, mev->getX(0));
        EXPECT_EQ(y, mev->getY(0));
        EXPECT_EQ(flags, mev->getFlags() & flags);

        ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        mev = static_cast<MotionEvent *>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
        EXPECT_EQ(flags, mev->getFlags() & flags);
    }

    void expectTapInDisplayCoordinates(int displayX, int displayY) {
        InputEvent *ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        MotionEvent *mev = static_cast<MotionEvent *>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
        const PointerCoords &coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
        EXPECT_EQ(displayX, coords.getX());
        EXPECT_EQ(displayY, coords.getY());
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);

        ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        mev = static_cast<MotionEvent *>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
    }

    void expectKey(uint32_t keycode) {
        InputEvent *ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
        KeyEvent *keyEvent = static_cast<KeyEvent *>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, keyEvent->getAction());
        EXPECT_EQ(keycode, keyEvent->getKeyCode());
        EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);

        ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
        keyEvent = static_cast<KeyEvent *>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, keyEvent->getAction());
        EXPECT_EQ(keycode, keyEvent->getKeyCode());
        EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
    }

    virtual ~InputSurface() {
        if (mClientChannel) {
            mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
        }
    }

    virtual void doTransaction(
            std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
                    transactionBody) {
        SurfaceComposerClient::Transaction t;
        transactionBody(t, mSurfaceControl);
        t.apply(true);
    }

    virtual void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
        SurfaceComposerClient::Transaction t;
        t.show(mSurfaceControl);
        t.setInputWindowInfo(mSurfaceControl, mInputInfo);
        t.setLayer(mSurfaceControl, LAYER_BASE);
        t.setPosition(mSurfaceControl, x, y);
        t.setCrop(mSurfaceControl, crop);
        t.setAlpha(mSurfaceControl, 1);
        t.apply(true);
    }

    void requestFocus(int displayId = ADISPLAY_ID_DEFAULT) {
        SurfaceComposerClient::Transaction t;
        FocusRequest request;
        request.token = mInputInfo.token;
        request.windowName = mInputInfo.name;
        request.focusedToken = nullptr;
        request.focusedWindowName = "";
        request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
        request.displayId = displayId;
        t.setFocusedWindow(request);
        t.apply(true);
    }

private:
    void waitForEventAvailable(int timeoutMs) {
        struct pollfd fd;

        fd.fd = mClientChannel->getFd();
        fd.events = POLLIN;
        poll(&fd, 1, timeoutMs);
    }

public:
    sp<SurfaceControl> mSurfaceControl;
    std::shared_ptr<InputChannel> mClientChannel;
    sp<IInputFlinger> mInputFlinger;

    WindowInfo mInputInfo;

    PreallocatedInputEventFactory mInputEventFactory;
    InputConsumer* mInputConsumer;
};

class BlastInputSurface : public InputSurface {
public:
    BlastInputSurface(const sp<SurfaceControl> &sc, const sp<SurfaceControl> &parentSc, int width,
                      int height)
          : InputSurface(sc, width, height) {
        mParentSurfaceControl = parentSc;
    }

    ~BlastInputSurface() = default;

    static std::unique_ptr<BlastInputSurface> makeBlastInputSurface(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> parentSc =
                scc->createSurface(String8("Test Parent Surface"), 0 /* bufHeight */,
                                   0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eFXSurfaceContainer);

        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Buffer Surface"), width, height,
                                   PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eFXSurfaceBufferState,
                                   parentSc->getHandle());
        return std::make_unique<BlastInputSurface>(surfaceControl, parentSc, width, height);
    }

    void doTransaction(
            std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
                    transactionBody) override {
        SurfaceComposerClient::Transaction t;
        transactionBody(t, mParentSurfaceControl);
        t.apply(true);
    }

    void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) override {
        SurfaceComposerClient::Transaction t;
        t.show(mParentSurfaceControl);
        t.setLayer(mParentSurfaceControl, LAYER_BASE);
        t.setPosition(mParentSurfaceControl, x, y);
        t.setCrop(mParentSurfaceControl, crop);

        t.show(mSurfaceControl);
        t.setInputWindowInfo(mSurfaceControl, mInputInfo);
        t.setCrop(mSurfaceControl, crop);
        t.setAlpha(mSurfaceControl, 1);
        t.apply(true);
    }

private:
    sp<SurfaceControl> mParentSurfaceControl;
};

class InputSurfacesTest : public ::testing::Test {
public:
    InputSurfacesTest() {
        ProcessState::self()->startThreadPool();
    }

    void SetUp() {
        mComposerClient = new SurfaceComposerClient;
        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
        const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
        ASSERT_FALSE(ids.empty());
        // display 0 is picked for now, can extend to support all displays if needed
        const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
        ASSERT_NE(display, nullptr);

        ui::DisplayMode mode;
        ASSERT_EQ(NO_ERROR, mComposerClient->getActiveDisplayMode(display, &mode));

        // After a new buffer is queued, SurfaceFlinger is notified and will
        // latch the new buffer on next vsync.  Let's heuristically wait for 3
        // vsyncs.
        mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
    }

    void TearDown() {
        mComposerClient->dispose();
    }

    std::unique_ptr<InputSurface> makeSurface(int width, int height) {
        return InputSurface::makeColorInputSurface(mComposerClient, width, height);
    }

    void postBuffer(const sp<SurfaceControl> &layer, int32_t w, int32_t h) {
        int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
                BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE;
        sp<GraphicBuffer> buffer =
                new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test");
        Transaction().setBuffer(layer, buffer).apply(true);
        usleep(mBufferPostDelay);
    }

    sp<SurfaceComposerClient> mComposerClient;
    int32_t mBufferPostDelay;
};

void injectTapOnDisplay(int x, int y, int displayId) {
    char *buf1, *buf2, *bufDisplayId;
    asprintf(&buf1, "%d", x);
    asprintf(&buf2, "%d", y);
    asprintf(&bufDisplayId, "%d", displayId);
    if (fork() == 0) {
        execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL);
    }
}

void injectTap(int x, int y) {
    injectTapOnDisplay(x, y, ADISPLAY_ID_DEFAULT);
}

void injectKeyOnDisplay(uint32_t keycode, int displayId) {
    char *buf1, *bufDisplayId;
    asprintf(&buf1, "%d", keycode);
    asprintf(&bufDisplayId, "%d", displayId);
    if (fork() == 0) {
        execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL);
    }
}

void injectKey(uint32_t keycode) {
    injectKeyOnDisplay(keycode, ADISPLAY_ID_NONE);
}

TEST_F(InputSurfacesTest, can_receive_input) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);

    injectTap(101, 101);

    EXPECT_NE(surface->consumeEvent(), nullptr);
}

/**
 * Set up two surfaces side-by-side. Tap each surface.
 * Next, swap the positions of the two surfaces. Inject tap into the two
 * original locations. Ensure that the tap is received by the surfaces in the
 * reverse order.
 */
TEST_F(InputSurfacesTest, input_respects_positioning) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);

    std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
    surface2->showAt(200, 200);

    injectTap(201, 201);
    surface2->expectTap(1, 1);

    injectTap(101, 101);
    surface->expectTap(1, 1);

    surface2->doTransaction([](auto &t, auto &sc) {
         t.setPosition(sc, 100, 100);
    });
    surface->doTransaction([](auto &t, auto &sc) {
         t.setPosition(sc, 200, 200);
    });

    injectTap(101, 101);
    surface2->expectTap(1, 1);

    injectTap(201, 201);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_respects_layering) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);

    surface->showAt(10, 10);
    surface2->showAt(10, 10);

    surface->doTransaction([](auto &t, auto &sc) {
         t.setLayer(sc, LAYER_BASE + 1);
    });

    injectTap(11, 11);
    surface->expectTap(1, 1);

    surface2->doTransaction([](auto &t, auto &sc) {
         t.setLayer(sc, LAYER_BASE + 1);
    });

    injectTap(11, 11);
    surface2->expectTap(1, 1);

    surface2->doTransaction([](auto &t, auto &sc) {
         t.hide(sc);
    });

    injectTap(11, 11);
    surface->expectTap(1, 1);
}

// Surface Insets are set to offset the client content and draw a border around the client surface
// (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start
// of the client content.
TEST_F(InputSurfacesTest, input_respects_surface_insets) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);

    fgSurface->mInputInfo.surfaceInset = 5;
    fgSurface->showAt(100, 100);

    injectTap(106, 106);
    fgSurface->expectTap(1, 1);

    injectTap(101, 101);
    bgSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_respects_surface_insets_with_replaceTouchableRegionWithCrop) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);

    fgSurface->mInputInfo.surfaceInset = 5;
    fgSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    fgSurface->showAt(100, 100);

    injectTap(106, 106);
    fgSurface->expectTap(1, 1);

    injectTap(101, 101);
    bgSurface->expectTap(1, 1);
}

// Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
    std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
    parentSurface->showAt(100, 100);

    childSurface->mInputInfo.surfaceInset = 10;
    childSurface->showAt(100, 100);

    childSurface->doTransaction([&](auto &t, auto &sc) {
        t.setPosition(sc, -5, -5);
        t.reparent(sc, parentSurface->mSurfaceControl);
    });

    injectTap(106, 106);
    childSurface->expectTap(1, 1);

    injectTap(101, 101);
    parentSurface->expectTap(1, 1);
}

// Ensure a surface whose insets are scaled, handles the touch offset correctly.
TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);

    fgSurface->mInputInfo.surfaceInset = 5;
    fgSurface->showAt(100, 100);

    fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });

    // expect = touch / scale - inset
    injectTap(112, 124);
    fgSurface->expectTap(1, 1);

    injectTap(101, 101);
    bgSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);

    // In case we pass the very big inset without any checking.
    fgSurface->mInputInfo.surfaceInset = INT32_MAX;
    fgSurface->showAt(100, 100);

    fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });

    // expect no crash for overflow, and inset size to be clamped to surface size
    injectTap(112, 124);
    bgSurface->expectTap(12, 24);
}

TEST_F(InputSurfacesTest, touchable_region) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);

    surface->mInputInfo.touchableRegion.set(Rect{19, 29, 21, 31});

    surface->showAt(11, 22);

    // A tap within the surface but outside the touchable region should not be sent to the surface.
    injectTap(20, 30);
    EXPECT_EQ(surface->consumeEvent(200 /*timeoutMs*/), nullptr);

    injectTap(31, 52);
    surface->expectTap(20, 30);
}

TEST_F(InputSurfacesTest, input_respects_touchable_region_offset_overflow) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);

    // Set the touchable region to the values at the limit of its corresponding type.
    // Since the surface is offset from the origin, the touchable region will be transformed into
    // display space, which would trigger an overflow or an underflow. Ensure that we are protected
    // against such a situation.
    fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});

    fgSurface->showAt(100, 100);

    // Expect no crash for overflow. The overflowed touchable region is ignored, so the background
    // surface receives touch.
    injectTap(112, 124);
    bgSurface->expectTap(12, 24);
}

TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(0, 0);

    fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
    fgSurface->showAt(0, 0);

    fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });

    // Expect no crash for overflow.
    injectTap(12, 24);
    fgSurface->expectTap(6, 12);
}

// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([](auto &t, auto &sc) {
        Region transparentRegion(Rect(0, 0, 10, 10));
        t.setTransparentRegionHint(sc, transparentRegion);
    });
    surface->showAt(100, 100);
    injectTap(101, 101);
    surface->expectTap(1, 1);
}

// TODO(b/139494112) update tests once we define expected behavior
// Ensure we still send input to the surface regardless of surface visibility changes due to the
// first buffer being submitted or alpha changes.
// Original bug ref: b/120839715
TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<BlastInputSurface> bufferSurface =
            BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);

    bgSurface->showAt(10, 10);
    bufferSurface->showAt(10, 10);

    injectTap(11, 11);
    bufferSurface->expectTap(1, 1);

    postBuffer(bufferSurface->mSurfaceControl, 100, 100);
    injectTap(11, 11);
    bufferSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<BlastInputSurface> bufferSurface =
            BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
    postBuffer(bufferSurface->mSurfaceControl, 100, 100);

    bgSurface->showAt(10, 10);
    bufferSurface->showAt(10, 10);

    injectTap(11, 11);
    bufferSurface->expectTap(1, 1);

    bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });

    injectTap(11, 11);
    bgSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);

    bgSurface->showAt(10, 10);
    fgSurface->showAt(10, 10);

    injectTap(11, 11);
    fgSurface->expectTap(1, 1);

    fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });

    injectTap(11, 11);
    fgSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);

    bgSurface->showAt(10, 10);
    containerSurface->showAt(10, 10);

    injectTap(11, 11);
    containerSurface->expectTap(1, 1);

    containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });

    injectTap(11, 11);
    bgSurface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_respects_outscreen) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(-1, -1);

    injectTap(0, 0);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> cursorSurface =
            InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);

    surface->showAt(10, 10);
    cursorSurface->showAt(10, 10);

    injectTap(11, 11);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, can_be_focused) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
    surface->requestFocus();

    surface->assertFocusChange(true);

    injectKey(AKEYCODE_V);
    surface->expectKey(AKEYCODE_V);
}

TEST_F(InputSurfacesTest, rotate_surface) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(10, 10);
    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, 0, 1, -1, 0); // 90 degrees
    });
    injectTap(8, 11);
    surface->expectTap(1, 2);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, -1, 0, 0, -1); // 180 degrees
    });
    injectTap(9, 8);
    surface->expectTap(1, 2);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, 0, -1, 1, 0); // 270 degrees
    });
    injectTap(12, 9);
    surface->expectTap(1, 2);
}

TEST_F(InputSurfacesTest, rotate_surface_with_scale) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(10, 10);
    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
    });
    injectTap(2, 12);
    surface->expectTap(1, 2);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
    });
    injectTap(8, 2);
    surface->expectTap(1, 2);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
    });
    injectTap(18, 8);
    surface->expectTap(1, 2);
}

TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->mInputInfo.surfaceInset = 5;
    surface->showAt(100, 100);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
    });
    injectTap(40, 120);
    surface->expectTap(5, 10);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
    });
    injectTap(80, 40);
    surface->expectTap(5, 10);

    surface->doTransaction([](auto &t, auto &sc) {
        t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
    });
    injectTap(160, 80);
    surface->expectTap(5, 10);
}

TEST_F(InputSurfacesTest, touch_flag_obscured) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);

    // Add non touchable window to fully cover touchable window. Window behind gets touch, but
    // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
    std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
    nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    nonTouchableSurface->mInputInfo.ownerUid = 22222;
    // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
    // the default obscured/untrusted touch filter introduced in S.
    nonTouchableSurface->mInputInfo.touchOcclusionMode = TouchOcclusionMode::ALLOW;
    nonTouchableSurface->showAt(100, 100);

    injectTap(190, 199);
    surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
}

TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);

    // Add non touchable window to cover touchable window, but parent is cropped to not cover area
    // that will be tapped. Window behind gets touch, but with flag
    // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
    std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
    nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    nonTouchableSurface->mInputInfo.ownerUid = 22222;
    parentSurface->mInputInfo.ownerUid = 22222;
    nonTouchableSurface->showAt(0, 0);
    parentSurface->showAt(100, 100);

    nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
        t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
        t.reparent(sc, parentSurface->mSurfaceControl);
    });

    injectTap(190, 199);
    surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
}

TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);

    // Add non touchable window to cover touchable window, but parent is cropped to avoid covering
    // the touchable window. Window behind gets touch with no obscured flags.
    std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
    nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    nonTouchableSurface->mInputInfo.ownerUid = 22222;
    parentSurface->mInputInfo.ownerUid = 22222;
    nonTouchableSurface->showAt(0, 0);
    parentSurface->showAt(50, 50);

    nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
        t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
        t.reparent(sc, parentSurface->mSurfaceControl);
    });

    injectTap(101, 110);
    surface->expectTap(1, 10);
}

TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);

    std::unique_ptr<InputSurface> bufferSurface =
            InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
    bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    bufferSurface->mInputInfo.ownerUid = 22222;

    surface->showAt(10, 10);
    bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);

    injectTap(11, 11);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);

    std::unique_ptr<BlastInputSurface> bufferSurface =
            BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
    bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    bufferSurface->mInputInfo.ownerUid = 22222;

    surface->showAt(10, 10);
    bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);

    injectTap(11, 11);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, strict_unobscured_input_unobscured_window) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction(
            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
    surface->showAt(100, 100);

    injectTap(101, 101);

    EXPECT_NE(surface->consumeEvent(), nullptr);
    EXPECT_NE(surface->consumeEvent(), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    surface->expectKey(AKEYCODE_V);
}

TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
        t.setMatrix(sc, 2.0, 0, 0, 2.0);
    });
    surface->showAt(100, 100);

    injectTap(101, 101);

    EXPECT_NE(surface->consumeEvent(), nullptr);
    EXPECT_NE(surface->consumeEvent(), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    surface->expectKey(AKEYCODE_V);
}

TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->mInputInfo.ownerUid = 11111;
    surface->doTransaction(
            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
    surface->showAt(100, 100);
    std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
    obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    obscuringSurface->mInputInfo.ownerUid = 22222;
    obscuringSurface->showAt(100, 100);
    injectTap(101, 101);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->mInputInfo.ownerUid = 11111;
    surface->doTransaction(
            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
    surface->showAt(100, 100);
    std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
    obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    obscuringSurface->mInputInfo.ownerUid = 22222;
    obscuringSurface->showAt(190, 190);

    injectTap(101, 101);

    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, strict_unobscured_input_alpha_window) {
    std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
    parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));

    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
        t.reparent(sc, parentSurface->mSurfaceControl);
        t.setAlpha(parentSurface->mSurfaceControl, 0.9f);
    });

    injectTap(101, 101);

    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, strict_unobscured_input_cropped_window) {
    std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
    parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));

    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
        t.reparent(sc, parentSurface->mSurfaceControl);
        t.setCrop(parentSurface->mSurfaceControl, Rect(10, 10, 100, 100));
    });
    surface->showAt(100, 100);

    injectTap(111, 111);

    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);

    std::unique_ptr<BlastInputSurface> bufferSurface =
            BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);

    surface->showAt(100, 100);
    bufferSurface->mInputInfo.touchableRegion.orSelf(Rect(0, 0, 200, 200));
    bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);

    injectTap(101, 101);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, drop_input_policy) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction(
            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
    surface->showAt(100, 100);

    injectTap(101, 101);

    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus();
    surface->assertFocusChange(true);
    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
    std::unique_ptr<InputSurface> bufferSurface =
            InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);

    bufferSurface->showAt(50, 50, Rect{0, 0, 100, 100});

    bufferSurface->requestFocus();
    bufferSurface->assertFocusChange(true);
}

/**
 * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
 * its own crop.
 */
TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
    std::unique_ptr<InputSurface> parentContainer =
            InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    containerSurface->doTransaction(
            [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
    containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
    parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
    containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));

    // Receives events inside its own crop
    injectTap(21, 21);
    containerSurface->expectTap(1, 1); // Event is in layer space

    // Does not receive events outside its crop
    injectTap(26, 26);
    EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
}

/**
 * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
 * in its parent's touchable region. The input events should be in the layer's coordinate space.
 */
TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
    std::unique_ptr<InputSurface> parentContainer =
            InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    containerSurface->doTransaction(
            [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
    containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
    parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
    containerSurface->showAt(10, 10, Rect::INVALID_RECT);

    // Receives events inside parent bounds
    injectTap(21, 21);
    containerSurface->expectTap(1, 1); // Event is in layer space

    // Does not receive events outside parent bounds
    injectTap(31, 31);
    EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
}

/**
 * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
 * layer's bounds. The input events should be in the layer's coordinate space.
 */
TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
    std::unique_ptr<InputSurface> cropLayer =
            InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
    cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));

    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    containerSurface->mInputInfo.touchableRegionCropHandle =
            cropLayer->mSurfaceControl->getHandle();
    containerSurface->showAt(10, 10, Rect::INVALID_RECT);

    // Receives events inside crop layer bounds
    injectTap(51, 51);
    containerSurface->expectTap(41, 41); // Event is in layer space

    // Does not receive events outside crop layer bounds
    injectTap(21, 21);
    injectTap(71, 71);
    EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) {
    std::unique_ptr<InputSurface> parent = makeSurface(100, 100);

    parent->showAt(100, 100);
    injectTap(101, 101);
    parent->expectTap(1, 1);

    std::unique_ptr<InputSurface> childContainerSurface =
            InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100);
    childContainerSurface->showAt(0, 0);
    childContainerSurface->doTransaction(
            [&](auto &t, auto &sc) { t.reparent(sc, parent->mSurfaceControl); });
    injectTap(101, 101);

    EXPECT_EQ(parent->consumeEvent(100), nullptr);
}

class MultiDisplayTests : public InputSurfacesTest {
public:
    MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
    void TearDown() override {
        for (auto &token : mVirtualDisplays) {
            SurfaceComposerClient::destroyDisplay(token);
        }
        InputSurfacesTest::TearDown();
    }

    void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack,
                       bool receivesInput = true, int32_t offsetX = 0, int32_t offsetY = 0) {
        sp<IGraphicBufferConsumer> consumer;
        sp<IGraphicBufferProducer> producer;
        BufferQueue::createBufferQueue(&producer, &consumer);
        consumer->setConsumerName(String8("Virtual disp consumer"));
        consumer->setDefaultBufferSize(width, height);
        mProducers.push_back(producer);

        std::string name = "VirtualDisplay";
        name += std::to_string(mVirtualDisplays.size());
        sp<IBinder> token = SurfaceComposerClient::createDisplay(String8(name.c_str()), isSecure);
        SurfaceComposerClient::Transaction t;
        t.setDisplaySurface(token, producer);
        t.setDisplayFlags(token, receivesInput ? 0x01 /* DisplayDevice::eReceivesInput */ : 0);
        t.setDisplayLayerStack(token, layerStack);
        t.setDisplayProjection(token, ui::ROTATION_0, {0, 0, width, height},
                               {offsetX, offsetY, offsetX + width, offsetY + height});
        t.apply(true);

        mVirtualDisplays.push_back(token);
    }

    std::vector<sp<IBinder>> mVirtualDisplays;
    std::vector<sp<IGraphicBufferProducer>> mProducers;
};

TEST_F(MultiDisplayTests, drop_touch_if_layer_on_invalid_display) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    // Do not create a display associated with the LayerStack.
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
    surface->showAt(100, 100);

    // Touches should be dropped if the layer is on an invalid display.
    injectTapOnDisplay(101, 101, layerStack.id);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    // However, we still let the window be focused and receive keys.
    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);

    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
    surface->expectKey(AKEYCODE_V);
}

TEST_F(MultiDisplayTests, virtual_display_receives_input) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    createDisplay(1000, 1000, false /*isSecure*/, layerStack);
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
    surface->showAt(100, 100);

    injectTapOnDisplay(101, 101, layerStack.id);
    surface->expectTap(1, 1);

    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
    surface->expectKey(AKEYCODE_V);
}

/**
 * When multiple DisplayDevices are mapped to the same layerStack, use the configuration for the
 * display that can receive input.
 */
TEST_F(MultiDisplayTests, many_to_one_display_mapping) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
                  100 /*offsetX*/, 100 /*offsetY*/);
    createDisplay(1000, 1000, false /*isSecure*/, layerStack, true /*receivesInput*/,
                  200 /*offsetX*/, 200 /*offsetY*/);
    createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
                  300 /*offsetX*/, 300 /*offsetY*/);
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
    surface->showAt(10, 10);

    // Input injection happens in logical display coordinates.
    injectTapOnDisplay(11, 11, layerStack.id);
    // Expect that the display transform for the display that receives input was used.
    surface->expectTapInDisplayCoordinates(211, 211);

    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
}

TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    createDisplay(1000, 1000, false /*isSecure*/, layerStack);
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
        t.setLayerStack(sc, layerStack);
    });
    surface->showAt(100, 100);

    injectTapOnDisplay(101, 101, layerStack.id);

    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);

    // Create the secure display as system, because only certain users can create secure displays.
    seteuid(AID_SYSTEM);
    createDisplay(1000, 1000, true /*isSecure*/, layerStack);
    // Change the uid back to root.
    seteuid(AID_ROOT);

    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
        t.setLayerStack(sc, layerStack);
    });
    surface->showAt(100, 100);

    injectTapOnDisplay(101, 101, layerStack.id);
    EXPECT_NE(surface->consumeEvent(), nullptr);
    EXPECT_NE(surface->consumeEvent(), nullptr);

    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);

    surface->expectKey(AKEYCODE_V);
}

} // namespace android::test
