Loading services/inputflinger/reader/mapper/TouchInputMapper.cpp +60 −2 Original line number Diff line number Diff line Loading @@ -2156,6 +2156,53 @@ std::list<NotifyArgs> TouchInputMapper::dispatchButtonPress(nsecs_t when, nsecs_ return out; } std::list<NotifyArgs> TouchInputMapper::dispatchGestureButtonRelease(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime) { std::list<NotifyArgs> out; BitSet32 releasedButtons(mLastCookedState.buttonState & ~mCurrentCookedState.buttonState); const int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mLastCookedState.buttonState; while (!releasedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit()); buttonState &= ~actionButton; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0, metaState, buttonState, 0, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, idBits, -1, mOrientedXPrecision, mOrientedYPrecision, mPointerGesture.downTime, MotionClassification::NONE)); } return out; } std::list<NotifyArgs> TouchInputMapper::dispatchGestureButtonPress(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime) { std::list<NotifyArgs> out; BitSet32 pressedButtons(mCurrentCookedState.buttonState & ~mLastCookedState.buttonState); const int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mLastCookedState.buttonState; while (!pressedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit()); buttonState |= actionButton; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0, metaState, buttonState, 0, mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, idBits, -1, mOrientedXPrecision, mOrientedYPrecision, mPointerGesture.downTime, MotionClassification::NONE)); } return out; } const BitSet32& TouchInputMapper::findActiveIdBits(const CookedPointerData& cookedPointerData) { if (!cookedPointerData.touchingIdBits.isEmpty()) { return cookedPointerData.touchingIdBits; Loading Loading @@ -2540,8 +2587,13 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns dispatchedGestureIdBits.value & ~mPointerGesture.currentGestureIdBits.value; } while (!upGestureIdBits.isEmpty()) { uint32_t id = upGestureIdBits.clearFirstMarkedBit(); if (((mLastCookedState.buttonState & AMOTION_EVENT_BUTTON_PRIMARY) != 0 || (mLastCookedState.buttonState & AMOTION_EVENT_BUTTON_SECONDARY) != 0) && mPointerGesture.lastGestureMode == PointerGesture::Mode::BUTTON_CLICK_OR_DRAG) { out += dispatchGestureButtonRelease(when, policyFlags, dispatchedGestureIdBits, readTime); } const uint32_t id = upGestureIdBits.clearFirstMarkedBit(); out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0, flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, Loading Loading @@ -2586,6 +2638,12 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, id, 0, 0, mPointerGesture.downTime, classification)); if (((buttonState & AMOTION_EVENT_BUTTON_PRIMARY) != 0 || (buttonState & AMOTION_EVENT_BUTTON_SECONDARY) != 0) && mPointerGesture.currentGestureMode == PointerGesture::Mode::BUTTON_CLICK_OR_DRAG) { out += dispatchGestureButtonPress(when, policyFlags, dispatchedGestureIdBits, readTime); } } } Loading services/inputflinger/reader/mapper/TouchInputMapper.h +8 −0 Original line number Diff line number Diff line Loading @@ -735,6 +735,14 @@ private: uint32_t policyFlags); [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime, uint32_t policyFlags); [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonPress(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonRelease(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime); const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData); void cookPointerData(); [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime, Loading services/inputflinger/tests/InputReader_test.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -10084,6 +10084,26 @@ TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) { ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0, 0, 0, 0, 0, 0, 0, 0)); // BUTTON DOWN processKey(mapper, BTN_LEFT, 1); processSync(mapper); // touchinputmapper design sends a move before button press ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action); // BUTTON UP processKey(mapper, BTN_LEFT, 0); processSync(mapper); // touchinputmapper design sends a move after button release ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); } TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) { Loading Loading
services/inputflinger/reader/mapper/TouchInputMapper.cpp +60 −2 Original line number Diff line number Diff line Loading @@ -2156,6 +2156,53 @@ std::list<NotifyArgs> TouchInputMapper::dispatchButtonPress(nsecs_t when, nsecs_ return out; } std::list<NotifyArgs> TouchInputMapper::dispatchGestureButtonRelease(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime) { std::list<NotifyArgs> out; BitSet32 releasedButtons(mLastCookedState.buttonState & ~mCurrentCookedState.buttonState); const int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mLastCookedState.buttonState; while (!releasedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit()); buttonState &= ~actionButton; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0, metaState, buttonState, 0, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, idBits, -1, mOrientedXPrecision, mOrientedYPrecision, mPointerGesture.downTime, MotionClassification::NONE)); } return out; } std::list<NotifyArgs> TouchInputMapper::dispatchGestureButtonPress(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime) { std::list<NotifyArgs> out; BitSet32 pressedButtons(mCurrentCookedState.buttonState & ~mLastCookedState.buttonState); const int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mLastCookedState.buttonState; while (!pressedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit()); buttonState |= actionButton; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0, metaState, buttonState, 0, mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, idBits, -1, mOrientedXPrecision, mOrientedYPrecision, mPointerGesture.downTime, MotionClassification::NONE)); } return out; } const BitSet32& TouchInputMapper::findActiveIdBits(const CookedPointerData& cookedPointerData) { if (!cookedPointerData.touchingIdBits.isEmpty()) { return cookedPointerData.touchingIdBits; Loading Loading @@ -2540,8 +2587,13 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns dispatchedGestureIdBits.value & ~mPointerGesture.currentGestureIdBits.value; } while (!upGestureIdBits.isEmpty()) { uint32_t id = upGestureIdBits.clearFirstMarkedBit(); if (((mLastCookedState.buttonState & AMOTION_EVENT_BUTTON_PRIMARY) != 0 || (mLastCookedState.buttonState & AMOTION_EVENT_BUTTON_SECONDARY) != 0) && mPointerGesture.lastGestureMode == PointerGesture::Mode::BUTTON_CLICK_OR_DRAG) { out += dispatchGestureButtonRelease(when, policyFlags, dispatchedGestureIdBits, readTime); } const uint32_t id = upGestureIdBits.clearFirstMarkedBit(); out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0, flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, Loading Loading @@ -2586,6 +2638,12 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, id, 0, 0, mPointerGesture.downTime, classification)); if (((buttonState & AMOTION_EVENT_BUTTON_PRIMARY) != 0 || (buttonState & AMOTION_EVENT_BUTTON_SECONDARY) != 0) && mPointerGesture.currentGestureMode == PointerGesture::Mode::BUTTON_CLICK_OR_DRAG) { out += dispatchGestureButtonPress(when, policyFlags, dispatchedGestureIdBits, readTime); } } } Loading
services/inputflinger/reader/mapper/TouchInputMapper.h +8 −0 Original line number Diff line number Diff line Loading @@ -735,6 +735,14 @@ private: uint32_t policyFlags); [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime, uint32_t policyFlags); [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonPress(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonRelease(nsecs_t when, uint32_t policyFlags, BitSet32 idBits, nsecs_t readTime); const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData); void cookPointerData(); [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime, Loading
services/inputflinger/tests/InputReader_test.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -10084,6 +10084,26 @@ TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) { ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0, 0, 0, 0, 0, 0, 0, 0)); // BUTTON DOWN processKey(mapper, BTN_LEFT, 1); processSync(mapper); // touchinputmapper design sends a move before button press ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action); // BUTTON UP processKey(mapper, BTN_LEFT, 0); processSync(mapper); // touchinputmapper design sends a move after button release ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); } TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) { Loading