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

Commit 4648ad64 authored by Vishnu Nair's avatar Vishnu Nair Committed by Automerger Merge Worker
Browse files

SurfaceFlinger: Implement drop input modes am: cbe9c105

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/16508594

Change-Id: I165587ce81cbc15030bca8c385f1e63c80ef27a3
parents f86cec5a cbe9c105
Loading
Loading
Loading
Loading
+45 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <memory>

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

#include <binder/Binder.h>
@@ -113,8 +114,8 @@ public:
        return std::make_unique<InputSurface>(surfaceControl, width, height);
    }

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

        InputEvent *ev;
        uint32_t seqId;
@@ -153,6 +154,24 @@ public:
        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);
    }

    ~InputSurface() {
        mInputFlinger->unregisterInputChannel(mServerChannel);
    }
@@ -176,12 +195,12 @@ public:
    }

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

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

    void populateInputInfo(int width, int height) {
@@ -277,6 +296,14 @@ void injectTap(int x, int y) {
    }
}

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

TEST_F(InputSurfacesTest, can_receive_input) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
@@ -561,5 +588,19 @@ TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
    injectTap(11, 11);
    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);
    surface->assertFocusChange(true);

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

    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}
}
} // namespace android
 No newline at end of file
+31 −0
Original line number Diff line number Diff line
@@ -2385,6 +2385,36 @@ bool Layer::isRemovedFromCurrentState() const {
    return mRemovedFromCurrentState;
}

gui::DropInputMode Layer::getDropInputMode() const {
    gui::DropInputMode mode = mDrawingState.dropInputMode;
    if (mode == gui::DropInputMode::ALL) {
        return mode;
    }
    sp<Layer> parent = mDrawingParent.promote();
    if (parent) {
        gui::DropInputMode parentMode = parent->getDropInputMode();
        if (parentMode != gui::DropInputMode::NONE) {
            return parentMode;
        }
    }
    return mode;
}

void Layer::handleDropInputMode(InputWindowInfo& info) const {
    if ((mDrawingState.inputInfo.inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL) ==
        InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL) {
        return;
    }

    // Check if we need to drop input unconditionally
    gui::DropInputMode dropInputMode = getDropInputMode();
    if (dropInputMode == gui::DropInputMode::ALL) {
        info.inputFeatures |= InputWindowInfo::INPUT_FEATURE_DROP_INPUT;
        ALOGV("Dropping input for %s as requested by policy.", getDebugName());
        return;
    }
}

InputWindowInfo Layer::fillInputInfo() {
    if (!hasInputInfo()) {
        mDrawingState.inputInfo.name = getName();
@@ -2458,6 +2488,7 @@ InputWindowInfo Layer::fillInputInfo() {
    // InputDispatcher, and obviously if they aren't visible they can't occlude
    // anything.
    info.visible = hasInputInfo() ? canReceiveInput() : isVisible();
    handleDropInputMode(info);

    auto cropLayer = mDrawingState.touchableRegionCrop.promote();
    if (info.replaceTouchableRegionWithCrop) {
+2 −0
Original line number Diff line number Diff line
@@ -1074,6 +1074,8 @@ private:

    void updateTreeHasFrameRateVote();
    bool isTrustedOverlay() const;
    gui::DropInputMode getDropInputMode() const;
    void handleDropInputMode(InputWindowInfo& info) const;

    // Cached properties computed from drawing state
    // Effective transform taking into account parent transforms and any parent scaling.