Loading services/inputflinger/reader/mapper/TouchpadInputMapper.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -256,8 +256,9 @@ std::list<NotifyArgs> TouchpadInputMapper::configure(nsecs_t when, std::list<NotifyArgs> TouchpadInputMapper::reset(nsecs_t when) { mStateConverter.reset(); mGestureConverter.reset(); return InputMapper::reset(when); std::list<NotifyArgs> out = mGestureConverter.reset(when); out += InputMapper::reset(when); return out; } std::list<NotifyArgs> TouchpadInputMapper::process(const RawEvent* rawEvent) { Loading services/inputflinger/reader/mapper/gestures/GestureConverter.cpp +85 −19 Original line number Diff line number Diff line Loading @@ -72,8 +72,32 @@ std::string GestureConverter::dump() const { return out.str(); } void GestureConverter::reset() { mButtonState = 0; std::list<NotifyArgs> GestureConverter::reset(nsecs_t when) { std::list<NotifyArgs> out; switch (mCurrentClassification) { case MotionClassification::TWO_FINGER_SWIPE: out.push_back(endScroll(when, when)); break; case MotionClassification::MULTI_FINGER_SWIPE: out += handleMultiFingerSwipeLift(when, when); break; case MotionClassification::PINCH: out += endPinch(when, when); break; case MotionClassification::NONE: // When a button is pressed, the Gestures library always ends the current gesture, // so we don't have to worry about the case where buttons need to be lifted during a // pinch or swipe. if (mButtonState) { out += releaseAllButtons(when, when); } break; default: break; } mCurrentClassification = MotionClassification::NONE; mDownTime = 0; return out; } void GestureConverter::populateMotionRanges(InputDeviceInfo& info) const { Loading Loading @@ -219,6 +243,39 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ return out; } std::list<NotifyArgs> GestureConverter::releaseAllButtons(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); PointerCoords coords; coords.clear(); coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition); coords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0); coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0); const bool pointerDown = isPointerDown(mButtonState); coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerDown ? 1.0f : 0.0f); uint32_t newButtonState = mButtonState; for (uint32_t button = AMOTION_EVENT_BUTTON_PRIMARY; button <= AMOTION_EVENT_BUTTON_FORWARD; button <<= 1) { if (mButtonState & button) { newButtonState &= ~button; out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_BUTTON_RELEASE, button, newButtonState, /*pointerCount=*/1, mFingerProps.data(), &coords, xCursorPosition, yCursorPosition)); } } if (pointerDown) { coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /*actionButton=*/0, newButtonState, /*pointerCount=*/1, mFingerProps.data(), &coords, xCursorPosition, yCursorPosition)); } mButtonState = 0; return out; } std::list<NotifyArgs> GestureConverter::handleScroll(nsecs_t when, nsecs_t readTime, const Gesture& gesture) { std::list<NotifyArgs> out; Loading Loading @@ -264,6 +321,10 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G return {}; } return endScroll(when, readTime); } NotifyArgs GestureConverter::endScroll(nsecs_t when, nsecs_t readTime) { const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, 0); mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, 0); Loading Loading @@ -366,8 +427,6 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G [[nodiscard]] std::list<NotifyArgs> GestureConverter::handlePinch(nsecs_t when, nsecs_t readTime, const Gesture& gesture) { std::list<NotifyArgs> out; const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); // Pinch gesture phases are reported a little differently from others, in that the same details Loading @@ -391,6 +450,7 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); mDownTime = when; std::list<NotifyArgs> out; out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN, /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, Loading @@ -405,19 +465,7 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G } if (gesture.details.pinch.zoom_state == GESTURES_ZOOM_END) { mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT, /* actionButton= */ 0, mButtonState, /* pointerCount= */ 2, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); mCurrentClassification = MotionClassification::NONE; mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 0); return out; return endPinch(when, readTime); } mPinchFingerSeparation *= gesture.details.pinch.dz; Loading @@ -429,9 +477,27 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition + mPinchFingerSeparation / 2); mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /* actionButton= */ 0, return {makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /*actionButton=*/0, mButtonState, /*pointerCount=*/2, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)}; } std::list<NotifyArgs> GestureConverter::endPinch(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT, /*actionButton=*/0, mButtonState, /*pointerCount=*/2, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /*actionButton=*/0, mButtonState, /*pointerCount=*/1, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); mCurrentClassification = MotionClassification::NONE; mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 0); return out; } Loading services/inputflinger/reader/mapper/gestures/GestureConverter.h +5 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public: std::string dump() const; void setOrientation(ui::Rotation orientation) { mOrientation = orientation; } void reset(); [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when); void populateMotionRanges(InputDeviceInfo& info) const; Loading @@ -55,15 +55,19 @@ private: [[nodiscard]] NotifyArgs handleMove(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] std::list<NotifyArgs> handleButtonsChange(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] std::list<NotifyArgs> releaseAllButtons(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> handleScroll(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] NotifyArgs handleFling(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] NotifyArgs endScroll(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipe(nsecs_t when, nsecs_t readTime, uint32_t fingerCount, float dx, float dy); [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipeLift(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> handlePinch(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] std::list<NotifyArgs> endPinch(nsecs_t when, nsecs_t readTime); NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action, int32_t actionButton, int32_t buttonState, Loading services/inputflinger/tests/GestureConverter_test.cpp +103 −0 Original line number Diff line number Diff line Loading @@ -785,4 +785,107 @@ TEST_F(GestureConverterTest, Pinch_ClearsClassificationAndScaleFactorAfterGestur WithGesturePinchScaleFactor(0, EPSILON))); } TEST_F(GestureConverterTest, ResetWithButtonPressed) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT, /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(3u, args.size()); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY), WithCoords(POINTER_X, POINTER_Y), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0), WithCoords(POINTER_X, POINTER_Y), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0), WithCoords(POINTER_X, POINTER_Y), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } TEST_F(GestureConverterTest, ResetDuringScroll) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(1u, args.size()); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y - 10), WithGestureScrollDistance(0, 0, EPSILON), WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE))); } TEST_F(GestureConverterTest, ResetDuringThreeFingerSwipe) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0, /*dy=*/10); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(3u, args.size()); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE), WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE), WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON), WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE), WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } TEST_F(GestureConverterTest, ResetDuringPinch) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1, GESTURES_ZOOM_START); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(2u, args.size()); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithMotionClassification(MotionClassification::PINCH), WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithMotionClassification(MotionClassification::PINCH), WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } } // namespace android Loading
services/inputflinger/reader/mapper/TouchpadInputMapper.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -256,8 +256,9 @@ std::list<NotifyArgs> TouchpadInputMapper::configure(nsecs_t when, std::list<NotifyArgs> TouchpadInputMapper::reset(nsecs_t when) { mStateConverter.reset(); mGestureConverter.reset(); return InputMapper::reset(when); std::list<NotifyArgs> out = mGestureConverter.reset(when); out += InputMapper::reset(when); return out; } std::list<NotifyArgs> TouchpadInputMapper::process(const RawEvent* rawEvent) { Loading
services/inputflinger/reader/mapper/gestures/GestureConverter.cpp +85 −19 Original line number Diff line number Diff line Loading @@ -72,8 +72,32 @@ std::string GestureConverter::dump() const { return out.str(); } void GestureConverter::reset() { mButtonState = 0; std::list<NotifyArgs> GestureConverter::reset(nsecs_t when) { std::list<NotifyArgs> out; switch (mCurrentClassification) { case MotionClassification::TWO_FINGER_SWIPE: out.push_back(endScroll(when, when)); break; case MotionClassification::MULTI_FINGER_SWIPE: out += handleMultiFingerSwipeLift(when, when); break; case MotionClassification::PINCH: out += endPinch(when, when); break; case MotionClassification::NONE: // When a button is pressed, the Gestures library always ends the current gesture, // so we don't have to worry about the case where buttons need to be lifted during a // pinch or swipe. if (mButtonState) { out += releaseAllButtons(when, when); } break; default: break; } mCurrentClassification = MotionClassification::NONE; mDownTime = 0; return out; } void GestureConverter::populateMotionRanges(InputDeviceInfo& info) const { Loading Loading @@ -219,6 +243,39 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ return out; } std::list<NotifyArgs> GestureConverter::releaseAllButtons(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); PointerCoords coords; coords.clear(); coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition); coords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0); coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0); const bool pointerDown = isPointerDown(mButtonState); coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerDown ? 1.0f : 0.0f); uint32_t newButtonState = mButtonState; for (uint32_t button = AMOTION_EVENT_BUTTON_PRIMARY; button <= AMOTION_EVENT_BUTTON_FORWARD; button <<= 1) { if (mButtonState & button) { newButtonState &= ~button; out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_BUTTON_RELEASE, button, newButtonState, /*pointerCount=*/1, mFingerProps.data(), &coords, xCursorPosition, yCursorPosition)); } } if (pointerDown) { coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /*actionButton=*/0, newButtonState, /*pointerCount=*/1, mFingerProps.data(), &coords, xCursorPosition, yCursorPosition)); } mButtonState = 0; return out; } std::list<NotifyArgs> GestureConverter::handleScroll(nsecs_t when, nsecs_t readTime, const Gesture& gesture) { std::list<NotifyArgs> out; Loading Loading @@ -264,6 +321,10 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G return {}; } return endScroll(when, readTime); } NotifyArgs GestureConverter::endScroll(nsecs_t when, nsecs_t readTime) { const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, 0); mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, 0); Loading Loading @@ -366,8 +427,6 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G [[nodiscard]] std::list<NotifyArgs> GestureConverter::handlePinch(nsecs_t when, nsecs_t readTime, const Gesture& gesture) { std::list<NotifyArgs> out; const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); // Pinch gesture phases are reported a little differently from others, in that the same details Loading @@ -391,6 +450,7 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); mDownTime = when; std::list<NotifyArgs> out; out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN, /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, Loading @@ -405,19 +465,7 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G } if (gesture.details.pinch.zoom_state == GESTURES_ZOOM_END) { mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT, /* actionButton= */ 0, mButtonState, /* pointerCount= */ 2, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); mCurrentClassification = MotionClassification::NONE; mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 0); return out; return endPinch(when, readTime); } mPinchFingerSeparation *= gesture.details.pinch.dz; Loading @@ -429,9 +477,27 @@ NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const G mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition + mPinchFingerSeparation / 2); mFakeFingerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /* actionButton= */ 0, return {makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /*actionButton=*/0, mButtonState, /*pointerCount=*/2, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)}; } std::list<NotifyArgs> GestureConverter::endPinch(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition(); mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 1.0); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT, /*actionButton=*/0, mButtonState, /*pointerCount=*/2, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP, /*actionButton=*/0, mButtonState, /*pointerCount=*/1, mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition, yCursorPosition)); mCurrentClassification = MotionClassification::NONE; mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR, 0); return out; } Loading
services/inputflinger/reader/mapper/gestures/GestureConverter.h +5 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ public: std::string dump() const; void setOrientation(ui::Rotation orientation) { mOrientation = orientation; } void reset(); [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when); void populateMotionRanges(InputDeviceInfo& info) const; Loading @@ -55,15 +55,19 @@ private: [[nodiscard]] NotifyArgs handleMove(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] std::list<NotifyArgs> handleButtonsChange(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] std::list<NotifyArgs> releaseAllButtons(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> handleScroll(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] NotifyArgs handleFling(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] NotifyArgs endScroll(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipe(nsecs_t when, nsecs_t readTime, uint32_t fingerCount, float dx, float dy); [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipeLift(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> handlePinch(nsecs_t when, nsecs_t readTime, const Gesture& gesture); [[nodiscard]] std::list<NotifyArgs> endPinch(nsecs_t when, nsecs_t readTime); NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action, int32_t actionButton, int32_t buttonState, Loading
services/inputflinger/tests/GestureConverter_test.cpp +103 −0 Original line number Diff line number Diff line Loading @@ -785,4 +785,107 @@ TEST_F(GestureConverterTest, Pinch_ClearsClassificationAndScaleFactorAfterGestur WithGesturePinchScaleFactor(0, EPSILON))); } TEST_F(GestureConverterTest, ResetWithButtonPressed) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT, /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(3u, args.size()); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY), WithCoords(POINTER_X, POINTER_Y), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0), WithCoords(POINTER_X, POINTER_Y), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0), WithCoords(POINTER_X, POINTER_Y), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } TEST_F(GestureConverterTest, ResetDuringScroll) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(1u, args.size()); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y - 10), WithGestureScrollDistance(0, 0, EPSILON), WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE))); } TEST_F(GestureConverterTest, ResetDuringThreeFingerSwipe) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0, /*dy=*/10); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(3u, args.size()); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE), WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE), WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON), WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE), WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } TEST_F(GestureConverterTest, ResetDuringPinch) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1, GESTURES_ZOOM_START); (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME); ASSERT_EQ(2u, args.size()); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithMotionClassification(MotionClassification::PINCH), WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); args.pop_front(); EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithMotionClassification(MotionClassification::PINCH), WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } } // namespace android