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

Commit 638b6f8d authored by Arthur Hung's avatar Arthur Hung Committed by Automerger Merge Worker
Browse files

Merge "Prevent processing touch after receiving an invalid tracking id" into sc-dev am: 10d57c6c

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

Change-Id: I0096a30673f62e3e67cace5ed14144b86a079593
parents 53fef3fd 10d57c6c
Loading
Loading
Loading
Loading
+15 −10
Original line number Original line Diff line number Diff line
@@ -104,36 +104,37 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
#endif
#endif
        } else {
        } else {
            Slot* slot = &mSlots[mCurrentSlot];
            Slot* slot = &mSlots[mCurrentSlot];
            // If mUsingSlotsProtocol is true, it means the raw pointer has axis info of
            // ABS_MT_TRACKING_ID and ABS_MT_SLOT, so driver should send a valid trackingId while
            // updating the slot.
            if (!mUsingSlotsProtocol) {
                slot->mInUse = true;
            }


            switch (rawEvent->code) {
            switch (rawEvent->code) {
                case ABS_MT_POSITION_X:
                case ABS_MT_POSITION_X:
                    slot->mInUse = true;
                    slot->mAbsMTPositionX = rawEvent->value;
                    slot->mAbsMTPositionX = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                    break;
                case ABS_MT_POSITION_Y:
                case ABS_MT_POSITION_Y:
                    slot->mInUse = true;
                    slot->mAbsMTPositionY = rawEvent->value;
                    slot->mAbsMTPositionY = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                    break;
                case ABS_MT_TOUCH_MAJOR:
                case ABS_MT_TOUCH_MAJOR:
                    slot->mInUse = true;
                    slot->mAbsMTTouchMajor = rawEvent->value;
                    slot->mAbsMTTouchMajor = rawEvent->value;
                    break;
                    break;
                case ABS_MT_TOUCH_MINOR:
                case ABS_MT_TOUCH_MINOR:
                    slot->mInUse = true;
                    slot->mAbsMTTouchMinor = rawEvent->value;
                    slot->mAbsMTTouchMinor = rawEvent->value;
                    slot->mHaveAbsMTTouchMinor = true;
                    slot->mHaveAbsMTTouchMinor = true;
                    break;
                    break;
                case ABS_MT_WIDTH_MAJOR:
                case ABS_MT_WIDTH_MAJOR:
                    slot->mInUse = true;
                    slot->mAbsMTWidthMajor = rawEvent->value;
                    slot->mAbsMTWidthMajor = rawEvent->value;
                    break;
                    break;
                case ABS_MT_WIDTH_MINOR:
                case ABS_MT_WIDTH_MINOR:
                    slot->mInUse = true;
                    slot->mAbsMTWidthMinor = rawEvent->value;
                    slot->mAbsMTWidthMinor = rawEvent->value;
                    slot->mHaveAbsMTWidthMinor = true;
                    slot->mHaveAbsMTWidthMinor = true;
                    break;
                    break;
                case ABS_MT_ORIENTATION:
                case ABS_MT_ORIENTATION:
                    slot->mInUse = true;
                    slot->mAbsMTOrientation = rawEvent->value;
                    slot->mAbsMTOrientation = rawEvent->value;
                    break;
                    break;
                case ABS_MT_TRACKING_ID:
                case ABS_MT_TRACKING_ID:
@@ -147,15 +148,12 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
                    }
                    }
                    break;
                    break;
                case ABS_MT_PRESSURE:
                case ABS_MT_PRESSURE:
                    slot->mInUse = true;
                    slot->mAbsMTPressure = rawEvent->value;
                    slot->mAbsMTPressure = rawEvent->value;
                    break;
                    break;
                case ABS_MT_DISTANCE:
                case ABS_MT_DISTANCE:
                    slot->mInUse = true;
                    slot->mAbsMTDistance = rawEvent->value;
                    slot->mAbsMTDistance = rawEvent->value;
                    break;
                    break;
                case ABS_MT_TOOL_TYPE:
                case ABS_MT_TOOL_TYPE:
                    slot->mInUse = true;
                    slot->mAbsMTToolType = rawEvent->value;
                    slot->mAbsMTToolType = rawEvent->value;
                    slot->mHaveAbsMTToolType = true;
                    slot->mHaveAbsMTToolType = true;
                    break;
                    break;
@@ -177,6 +175,13 @@ bool MultiTouchMotionAccumulator::hasStylus() const {
    return mHaveStylus;
    return mHaveStylus;
}
}


void MultiTouchMotionAccumulator::warnIfNotInUse(const RawEvent& event, const Slot& slot) {
    if (!slot.mInUse) {
        ALOGW("Received unexpected event (0x%0x, 0x%0x) for slot %i with tracking id %i",
              event.code, event.value, mCurrentSlot, slot.mAbsMTTrackingId);
    }
}

// --- MultiTouchMotionAccumulator::Slot ---
// --- MultiTouchMotionAccumulator::Slot ---


MultiTouchMotionAccumulator::Slot::Slot() {
MultiTouchMotionAccumulator::Slot::Slot() {
+1 −0
Original line number Original line Diff line number Diff line
@@ -87,6 +87,7 @@ private:
    bool mHaveStylus;
    bool mHaveStylus;


    void clearSlots(int32_t initialSlot);
    void clearSlots(int32_t initialSlot);
    void warnIfNotInUse(const RawEvent& event, const Slot& slot);
};
};


class MultiTouchInputMapper : public TouchInputMapper {
class MultiTouchInputMapper : public TouchInputMapper {
+7 −0
Original line number Original line Diff line number Diff line
@@ -1471,6 +1471,13 @@ void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
          next.rawPointerData.canceledIdBits.value);
          next.rawPointerData.canceledIdBits.value);
#endif
#endif


    if (!next.rawPointerData.touchingIdBits.isEmpty() &&
        !next.rawPointerData.hoveringIdBits.isEmpty() &&
        last.rawPointerData.hoveringIdBits != next.rawPointerData.hoveringIdBits) {
        ALOGI("Multi-touch contains some hovering ids 0x%08x",
              next.rawPointerData.hoveringIdBits.value);
    }

    processRawTouches(false /*timeout*/);
    processRawTouches(false /*timeout*/);
}
}


+67 −0
Original line number Original line Diff line number Diff line
@@ -2276,6 +2276,7 @@ TEST_F(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
    const Point centerPoint = mDevice->getCenterPoint();
    const Point centerPoint = mDevice->getCenterPoint();


    // ACTION_DOWN
    // ACTION_DOWN
    mDevice->sendTrackingId(FIRST_TRACKING_ID);
    mDevice->sendDown(centerPoint);
    mDevice->sendDown(centerPoint);
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
@@ -2296,6 +2297,8 @@ TEST_F(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
    const Point centerPoint = mDevice->getCenterPoint();
    const Point centerPoint = mDevice->getCenterPoint();


    // ACTION_DOWN
    // ACTION_DOWN
    mDevice->sendSlot(FIRST_SLOT);
    mDevice->sendTrackingId(FIRST_TRACKING_ID);
    mDevice->sendDown(centerPoint);
    mDevice->sendDown(centerPoint);
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
@@ -8217,6 +8220,70 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPoin
    ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
    ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
}
}


/**
 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
 * cause slot be valid again.
 */
TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);
    prepareAxes(POSITION | ID | SLOT | PRESSURE);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();

    NotifyMotionArgs motionArgs;

    constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
    // First finger down.
    processId(mapper, FIRST_TRACKING_ID);
    processPosition(mapper, x1, y1);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
    ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);

    // First finger move.
    processId(mapper, FIRST_TRACKING_ID);
    processPosition(mapper, x1 + 1, y1 + 1);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
    ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);

    // Second finger down.
    processSlot(mapper, SECOND_SLOT);
    processId(mapper, SECOND_TRACKING_ID);
    processPosition(mapper, x2, y2);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
              motionArgs.action);
    ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);

    // second finger up with some unexpected data.
    processSlot(mapper, SECOND_SLOT);
    processId(mapper, INVALID_TRACKING_ID);
    processPosition(mapper, x2, y2);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
              motionArgs.action);
    ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);

    // first finger up with some unexpected data.
    processSlot(mapper, FIRST_SLOT);
    processId(mapper, INVALID_TRACKING_ID);
    processPosition(mapper, x2, y2);
    processPressure(mapper, RAW_PRESSURE_MAX);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
    ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
}

// --- MultiTouchInputMapperTest_ExternalDevice ---
// --- MultiTouchInputMapperTest_ExternalDevice ---


class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {