Loading services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -80,7 +80,17 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t schs.fingers.clear(); for (size_t i = 0; i < mMotionAccumulator.getSlotCount(); i++) { MultiTouchMotionAccumulator::Slot slot = mMotionAccumulator.getSlot(i); if (slot.isInUse()) { if (!slot.isInUse()) { continue; } // Some touchpads continue to report contacts even after they've identified them as palms. // We want to exclude these contacts from the HardwareStates, but still need to report a // tracking ID of -1 if a finger turns into a palm. const bool isPalm = slot.getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM; if (isPalm && mFingerSlots.find(i) == mFingerSlots.end()) { continue; } FingerState& fingerState = schs.fingers.emplace_back(); fingerState = {}; fingerState.touch_major = slot.getTouchMajor(); Loading @@ -91,7 +101,11 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t fingerState.orientation = slot.getOrientation(); fingerState.position_x = slot.getX(); fingerState.position_y = slot.getY(); fingerState.tracking_id = slot.getTrackingId(); fingerState.tracking_id = isPalm ? -1 : slot.getTrackingId(); if (fingerState.tracking_id == -1) { mFingerSlots.erase(i); } else { mFingerSlots.insert(i); } } schs.state.fingers = schs.fingers.data(); Loading @@ -103,6 +117,7 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t void HardwareStateConverter::reset() { mCursorButtonAccumulator.reset(mDeviceContext); mTouchButtonAccumulator.reset(); mFingerSlots.clear(); mMscTimestamp = 0; } Loading services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <optional> #include <set> #include <utils/Timers.h> Loading Loading @@ -53,6 +54,7 @@ private: MultiTouchMotionAccumulator mMotionAccumulator; TouchButtonAccumulator mTouchButtonAccumulator; int32_t mMscTimestamp = 0; std::set<size_t> mFingerSlots; }; } // namespace android services/inputflinger/tests/HardwareStateConverter_test.cpp +62 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,68 @@ TEST_F(HardwareStateConverterTest, TwoFingers) { EXPECT_EQ(0u, finger2.flags); } TEST_F(HardwareStateConverterTest, OnePalm) { const nsecs_t time = ARBITRARY_TIME; InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); HardwareStateConverter conv(deviceContext); processAxis(conv, time, EV_ABS, ABS_MT_SLOT, 0); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); processAxis(conv, time, EV_ABS, ABS_MT_TRACKING_ID, 123); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 50); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 100); processAxis(conv, time, EV_KEY, BTN_TOUCH, 1); std::optional<SelfContainedHardwareState> schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); EXPECT_EQ(0, schs->state.finger_cnt); } TEST_F(HardwareStateConverterTest, OneFingerTurningIntoAPalm) { const nsecs_t time = ARBITRARY_TIME; InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); HardwareStateConverter conv(deviceContext); processAxis(conv, time, EV_ABS, ABS_MT_SLOT, 0); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); processAxis(conv, time, EV_ABS, ABS_MT_TRACKING_ID, 123); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 50); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 100); processAxis(conv, time, EV_KEY, BTN_TOUCH, 1); std::optional<SelfContainedHardwareState> schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); EXPECT_EQ(1, schs->state.finger_cnt); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 51); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 99); schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); ASSERT_EQ(1, schs->state.finger_cnt); EXPECT_EQ(-1, schs->state.fingers[0].tracking_id); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 53); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 97); schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); EXPECT_EQ(0, schs->state.finger_cnt); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 55); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 95); schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); ASSERT_EQ(1, schs->state.finger_cnt); const FingerState& newFinger = schs->state.fingers[0]; EXPECT_EQ(123, newFinger.tracking_id); EXPECT_NEAR(55, newFinger.position_x, EPSILON); EXPECT_NEAR(95, newFinger.position_y, EPSILON); } TEST_F(HardwareStateConverterTest, ButtonPressed) { const nsecs_t time = ARBITRARY_TIME; InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); Loading Loading
services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -80,7 +80,17 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t schs.fingers.clear(); for (size_t i = 0; i < mMotionAccumulator.getSlotCount(); i++) { MultiTouchMotionAccumulator::Slot slot = mMotionAccumulator.getSlot(i); if (slot.isInUse()) { if (!slot.isInUse()) { continue; } // Some touchpads continue to report contacts even after they've identified them as palms. // We want to exclude these contacts from the HardwareStates, but still need to report a // tracking ID of -1 if a finger turns into a palm. const bool isPalm = slot.getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM; if (isPalm && mFingerSlots.find(i) == mFingerSlots.end()) { continue; } FingerState& fingerState = schs.fingers.emplace_back(); fingerState = {}; fingerState.touch_major = slot.getTouchMajor(); Loading @@ -91,7 +101,11 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t fingerState.orientation = slot.getOrientation(); fingerState.position_x = slot.getX(); fingerState.position_y = slot.getY(); fingerState.tracking_id = slot.getTrackingId(); fingerState.tracking_id = isPalm ? -1 : slot.getTrackingId(); if (fingerState.tracking_id == -1) { mFingerSlots.erase(i); } else { mFingerSlots.insert(i); } } schs.state.fingers = schs.fingers.data(); Loading @@ -103,6 +117,7 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t void HardwareStateConverter::reset() { mCursorButtonAccumulator.reset(mDeviceContext); mTouchButtonAccumulator.reset(); mFingerSlots.clear(); mMscTimestamp = 0; } Loading
services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #pragma once #include <optional> #include <set> #include <utils/Timers.h> Loading Loading @@ -53,6 +54,7 @@ private: MultiTouchMotionAccumulator mMotionAccumulator; TouchButtonAccumulator mTouchButtonAccumulator; int32_t mMscTimestamp = 0; std::set<size_t> mFingerSlots; }; } // namespace android
services/inputflinger/tests/HardwareStateConverter_test.cpp +62 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,68 @@ TEST_F(HardwareStateConverterTest, TwoFingers) { EXPECT_EQ(0u, finger2.flags); } TEST_F(HardwareStateConverterTest, OnePalm) { const nsecs_t time = ARBITRARY_TIME; InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); HardwareStateConverter conv(deviceContext); processAxis(conv, time, EV_ABS, ABS_MT_SLOT, 0); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); processAxis(conv, time, EV_ABS, ABS_MT_TRACKING_ID, 123); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 50); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 100); processAxis(conv, time, EV_KEY, BTN_TOUCH, 1); std::optional<SelfContainedHardwareState> schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); EXPECT_EQ(0, schs->state.finger_cnt); } TEST_F(HardwareStateConverterTest, OneFingerTurningIntoAPalm) { const nsecs_t time = ARBITRARY_TIME; InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); HardwareStateConverter conv(deviceContext); processAxis(conv, time, EV_ABS, ABS_MT_SLOT, 0); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); processAxis(conv, time, EV_ABS, ABS_MT_TRACKING_ID, 123); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 50); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 100); processAxis(conv, time, EV_KEY, BTN_TOUCH, 1); std::optional<SelfContainedHardwareState> schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); EXPECT_EQ(1, schs->state.finger_cnt); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 51); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 99); schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); ASSERT_EQ(1, schs->state.finger_cnt); EXPECT_EQ(-1, schs->state.fingers[0].tracking_id); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 53); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 97); schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); EXPECT_EQ(0, schs->state.finger_cnt); processAxis(conv, time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 55); processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 95); schs = processSync(conv, time); ASSERT_TRUE(schs.has_value()); ASSERT_EQ(1, schs->state.finger_cnt); const FingerState& newFinger = schs->state.fingers[0]; EXPECT_EQ(123, newFinger.tracking_id); EXPECT_NEAR(55, newFinger.position_x, EPSILON); EXPECT_NEAR(95, newFinger.position_y, EPSILON); } TEST_F(HardwareStateConverterTest, ButtonPressed) { const nsecs_t time = ARBITRARY_TIME; InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); Loading