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

Commit 3333a9a1 authored by Jackal Guo's avatar Jackal Guo Committed by Android (Google) Code Review
Browse files

Merge "Send all MotionEvents to InputFilter."

parents 119a40db f9696688
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -215,10 +215,6 @@ static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t poi
    return true;
}

static bool isMainDisplay(int32_t displayId) {
    return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
}

static void dumpRegion(std::string& dump, const Region& region) {
    if (region.isEmpty()) {
        dump += "<empty>";
@@ -2722,8 +2718,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
}

bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
    // TODO: support sending secondary display events to input filter
    return mInputFilterEnabled && isMainDisplay(args->displayId);
    return mInputFilterEnabled;
}

void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
+175 −11
Original line number Diff line number Diff line
@@ -48,9 +48,51 @@ protected:

public:
    FakeInputDispatcherPolicy() {
        mInputEventFiltered = false;
        mTime = -1;
        mAction = -1;
        mDisplayId = -1;
    }

    void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyMotionArgs* args) {
        ASSERT_TRUE(mInputEventFiltered)
                << "Expected filterInputEvent() to have been called.";

        ASSERT_EQ(mTime, args->eventTime)
                << "Expected time of filtered event was not matched";
        ASSERT_EQ(mAction, args->action)
                << "Expected action of filtered event was not matched";
        ASSERT_EQ(mDisplayId, args->displayId)
                << "Expected displayId of filtered event was not matched";

        reset();
    }

    void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyKeyArgs* args) {
        ASSERT_TRUE(mInputEventFiltered)
                << "Expected filterInputEvent() to have been called.";

        ASSERT_EQ(mTime, args->eventTime)
                << "Expected time of filtered event was not matched";
        ASSERT_EQ(mAction, args->action)
                << "Expected action of filtered event was not matched";
        ASSERT_EQ(mDisplayId, args->displayId)
                << "Expected displayId of filtered event was not matched";

        reset();
    }

    void assertFilterInputEventWasNotCalled() {
        ASSERT_FALSE(mInputEventFiltered)
                << "Expected filterInputEvent() to not have been called.";
    }

private:
    bool mInputEventFiltered;
    nsecs_t mTime;
    int32_t mAction;
    int32_t mDisplayId;

    virtual void notifyConfigurationChanged(nsecs_t) {
    }

@@ -70,7 +112,26 @@ private:
        *outConfig = mConfig;
    }

    virtual bool filterInputEvent(const InputEvent*, uint32_t) {
    virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
        switch (inputEvent->getType()) {
            case AINPUT_EVENT_TYPE_KEY: {
                const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
                mTime = keyEvent->getEventTime();
                mAction = keyEvent->getAction();
                mDisplayId = keyEvent->getDisplayId();
                break;
            }

            case AINPUT_EVENT_TYPE_MOTION: {
                const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
                mTime = motionEvent->getEventTime();
                mAction = motionEvent->getAction();
                mDisplayId = motionEvent->getDisplayId();
                break;
            }
        }

        mInputEventFiltered = true;
        return true;
    }

@@ -99,6 +160,13 @@ private:
    virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
        return false;
    }

    void reset() {
        mInputEventFiltered = false;
        mTime = -1;
        mAction = -1;
        mDisplayId = -1;
    }
};


@@ -404,16 +472,6 @@ public:
    void setFocus() {
        mFocused = true;
    }

    void assertNoEvents() {
        uint32_t consumeSeq;
        InputEvent* event;
        status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
            &consumeSeq, &event);
        ASSERT_NE(OK, status)
                << mName.c_str()
                << ": should not have received any events, so consume(..) should not return OK.";
    }
protected:
    virtual bool handled() {
        return true;
@@ -469,6 +527,40 @@ static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t s
            INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
}

static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
    nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
    // Define a valid key event.
    NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
            displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
            AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);

    return args;
}

static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
    PointerProperties pointerProperties[1];
    PointerCoords pointerCoords[1];

    pointerProperties[0].clear();
    pointerProperties[0].id = 0;
    pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;

    pointerCoords[0].clear();
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);

    nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
    // Define a valid motion event.
    NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
            POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
            AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
            AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1, pointerProperties,
            pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0, currentTime,
            /* videoFrames */ {});

    return args;
}

TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
    sp<FakeApplicationHandle> application = new FakeApplicationHandle();
    sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
@@ -740,4 +832,76 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
    monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
}

class InputFilterTest : public InputDispatcherTest {
protected:
    static constexpr int32_t SECOND_DISPLAY_ID = 1;

    void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
        NotifyMotionArgs motionArgs;

        motionArgs = generateMotionArgs(
                AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
        mDispatcher->notifyMotion(&motionArgs);
        motionArgs = generateMotionArgs(
                AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
        mDispatcher->notifyMotion(&motionArgs);

        if (expectToBeFiltered) {
            mFakePolicy->assertFilterInputEventWasCalledWithExpectedArgs(&motionArgs);
        } else {
            mFakePolicy->assertFilterInputEventWasNotCalled();
        }
    }

    void testNotifyKey(bool expectToBeFiltered) {
        NotifyKeyArgs keyArgs;

        keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
        mDispatcher->notifyKey(&keyArgs);
        keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
        mDispatcher->notifyKey(&keyArgs);

        if (expectToBeFiltered) {
            mFakePolicy->assertFilterInputEventWasCalledWithExpectedArgs(&keyArgs);
        } else {
            mFakePolicy->assertFilterInputEventWasNotCalled();
        }
    }
};

// Test InputFilter for MotionEvent
TEST_F(InputFilterTest, MotionEvent_InputFilter) {
    // Since the InputFilter is disabled by default, check if touch events aren't filtered.
    testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
    testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);

    // Enable InputFilter
    mDispatcher->setInputFilterEnabled(true);
    // Test touch on both primary and second display, and check if both events are filtered.
    testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
    testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);

    // Disable InputFilter
    mDispatcher->setInputFilterEnabled(false);
    // Test touch on both primary and second display, and check if both events aren't filtered.
    testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
    testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
}

// Test InputFilter for KeyEvent
TEST_F(InputFilterTest, KeyEvent_InputFilter) {
    // Since the InputFilter is disabled by default, check if key event aren't filtered.
    testNotifyKey(/*expectToBeFiltered*/ false);

    // Enable InputFilter
    mDispatcher->setInputFilterEnabled(true);
    // Send a key event, and check if it is filtered.
    testNotifyKey(/*expectToBeFiltered*/ true);

    // Disable InputFilter
    mDispatcher->setInputFilterEnabled(false);
    // Send a key event, and check if it isn't filtered.
    testNotifyKey(/*expectToBeFiltered*/ false);
}

} // namespace android