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

Commit 4bb0bd5e authored by Arpit Singh's avatar Arpit Singh
Browse files

Revert "InputReader: Clear the multi-touch state when the device is reset"

This reverts commit f8d9e440.

Reason for revert: b/316593362

Test: atest inputflinger_tests
Bug: b/316593362

Change-Id: Idfbf2091febba12c0e92a39bedb56b1058b85047
parent 4357b669
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -35,10 +35,12 @@ MultiTouchInputMapper::MultiTouchInputMapper(InputDeviceContext& deviceContext,
MultiTouchInputMapper::~MultiTouchInputMapper() {}

std::list<NotifyArgs> MultiTouchInputMapper::reset(nsecs_t when) {
    // TODO(b/291626046): Sync the MT state with the kernel using EVIOCGMTSLOTS.
    mMultiTouchMotionAccumulator.reset(getDeviceContext());
    mPointerIdBits.clear();

    // The evdev multi-touch protocol does not allow userspace applications to query the initial or
    // current state of the pointers at any time. This means if we clear our accumulated state when
    // resetting the input mapper, there's no way to rebuild the full initial state of the pointers.
    // We can only wait for updates to all the pointers and axes. Rather than clearing the state and
    // rebuilding the state from scratch, we work around this kernel API limitation by never
    // fully clearing any state specific to the multi-touch protocol.
    return TouchInputMapper::reset(when);
}

+16 −22
Original line number Diff line number Diff line
@@ -30,16 +30,9 @@ void MultiTouchMotionAccumulator::configure(const InputDeviceContext& deviceCont
                                            size_t slotCount, bool usingSlotsProtocol) {
    mUsingSlotsProtocol = usingSlotsProtocol;
    mSlots = std::vector<Slot>(slotCount);
    reset(deviceContext);
}

void MultiTouchMotionAccumulator::reset(const InputDeviceContext& deviceContext) {
    resetSlots();

    if (!mUsingSlotsProtocol) {
        return;
    }

    mCurrentSlot = -1;
    if (mUsingSlotsProtocol) {
        // Query the driver for the current slot index and use it as the initial slot before we
        // start reading events from the device.  It is possible that the current slot index will
        // not be the same as it was when the first event was written into the evdev buffer, which
@@ -55,6 +48,7 @@ void MultiTouchMotionAccumulator::reset(const InputDeviceContext& deviceContext)
            ALOGD("Could not retrieve current multi-touch slot index. status=%d", status);
        }
    }
}

void MultiTouchMotionAccumulator::resetSlots() {
    for (Slot& slot : mSlots) {
+0 −1
Original line number Diff line number Diff line
@@ -83,7 +83,6 @@ public:
        LOG_ALWAYS_FATAL_IF(index < 0 || index >= mSlots.size(), "Invalid index: %zu", index);
        return mSlots[index];
    }
    void reset(const InputDeviceContext& deviceContext);

private:
    int32_t mCurrentSlot;
+8 −79
Original line number Diff line number Diff line
@@ -10971,7 +10971,7 @@ TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
    ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
}
TEST_F(MultiTouchInputMapperTest, ResetClearsTouchState) {
TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(ui::ROTATION_0);
    prepareAxes(POSITION | ID | SLOT | PRESSURE);
@@ -10994,36 +10994,25 @@ TEST_F(MultiTouchInputMapperTest, ResetClearsTouchState) {
    ASSERT_NO_FATAL_FAILURE(
            mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
    // Reset the mapper. When the mapper is reset, the touch state is also cleared.
    // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
    // preserved. Resetting should cancel the ongoing gesture.
    resetMapper(mapper, ARBITRARY_TIME);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
    // Move the second slot pointer, and ensure there are no events, because the touch state was
    // cleared and no slots should be in use.
    // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
    // the existing touch state to generate a down event.
    processPosition(mapper, 301, 302);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
    // Release both fingers.
    processId(mapper, INVALID_TRACKING_ID);
    processSlot(mapper, FIRST_SLOT);
    processId(mapper, INVALID_TRACKING_ID);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
    // Start a new gesture, and ensure we get a DOWN event for it.
    processId(mapper, FIRST_TRACKING_ID);
    processPosition(mapper, 200, 300);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(MultiTouchInputMapperTest, ResetClearsTouchStateWithNoPointersDown) {
TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(ui::ROTATION_0);
    prepareAxes(POSITION | ID | SLOT | PRESSURE);
@@ -11151,66 +11140,6 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenConfigDisabled_ShouldNotShowDirect
    ASSERT_FALSE(fakePointerController->isPointerShown());
}
TEST_F(MultiTouchInputMapperTest, SimulateKernelBufferOverflow) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(ui::ROTATION_0);
    prepareAxes(POSITION | ID | SLOT | PRESSURE);
    MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
    // First finger down.
    processId(mapper, FIRST_TRACKING_ID);
    processPosition(mapper, 100, 200);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
    // Assume the kernel buffer overflows, and we get a SYN_DROPPED event.
    // This will reset the mapper, and thus also reset the touch state.
    process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_DROPPED, 0);
    resetMapper(mapper, ARBITRARY_TIME);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
    // Since the touch state was reset, it doesn't know which slots are active, so any movements
    // are ignored.
    processPosition(mapper, 101, 201);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
    // Second finger goes down. This is the first active finger, so we get a DOWN event.
    processSlot(mapper, SECOND_SLOT);
    processId(mapper, SECOND_TRACKING_ID);
    processPosition(mapper, 400, 500);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
    // First slot is still ignored, only the second one is active.
    processSlot(mapper, FIRST_SLOT);
    processPosition(mapper, 102, 202);
    processSlot(mapper, SECOND_SLOT);
    processPosition(mapper, 401, 501);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
    // Both slots up, so we get the UP event for the active pointer.
    processSlot(mapper, FIRST_SLOT);
    processId(mapper, INVALID_TRACKING_ID);
    processSlot(mapper, SECOND_SLOT);
    processId(mapper, INVALID_TRACKING_ID);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(
            mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
// --- MultiTouchInputMapperTest_ExternalDevice ---
class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {