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

Commit ef400b26 authored by Harry Cutts's avatar Harry Cutts
Browse files

Report two-finger touchpad swipes

Bug: 251196347
Test: try out two-finger scroll gestures with an Apple Magic Trackpad 2
Test: atest inputflinger_tests
Change-Id: I9e693350873b90bd50605ab348821224ae1121a8
parent 2e2c00f8
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -786,6 +786,19 @@ enum {
     * The same as {@link AMOTION_EVENT_AXIS_GESTURE_X_OFFSET}, but for the Y axis.
     */
    AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET = 49,
    /**
     * Axis constant: X scroll distance axis of a motion event.
     *
     * - For a touch pad, reports the distance that should be scrolled in the X axis as a result of
     *   the user's two-finger scroll gesture, in display pixels.
     */
    AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE = 50,
    /**
     * Axis constant: Y scroll distance axis of a motion event.
     *
     * The same as {@link AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE}, but for the Y axis.
     */
    AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE = 51,

    /**
     * Note: This is not an "Axis constant". It does not represent any axis, nor should it be used
@@ -793,7 +806,7 @@ enum {
     * to make some computations (like iterating through all possible axes) cleaner.
     * Please update the value accordingly if you add a new axis.
     */
    AMOTION_EVENT_MAXIMUM_VALID_AXIS_VALUE = AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET,
    AMOTION_EVENT_MAXIMUM_VALID_AXIS_VALUE = AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE,

    // NOTE: If you add a new axis here you must also add it to several other files.
    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+3 −1
Original line number Diff line number Diff line
@@ -394,7 +394,9 @@ namespace android {
    DEFINE_AXIS(GENERIC_15), \
    DEFINE_AXIS(GENERIC_16), \
    DEFINE_AXIS(GESTURE_X_OFFSET), \
    DEFINE_AXIS(GESTURE_Y_OFFSET)
    DEFINE_AXIS(GESTURE_Y_OFFSET), \
    DEFINE_AXIS(GESTURE_SCROLL_X_DISTANCE), \
    DEFINE_AXIS(GESTURE_SCROLL_Y_DISTANCE)

// NOTE: If you add new LEDs here, you must also add them to Input.h
#define LEDS_SEQUENCE \
+2 −2
Original line number Diff line number Diff line
@@ -263,11 +263,11 @@ static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_13) == common
static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_14) == common::Axis::GENERIC_14);
static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_15) == common::Axis::GENERIC_15);
static_assert(static_cast<common::Axis>(AMOTION_EVENT_AXIS_GENERIC_16) == common::Axis::GENERIC_16);
// TODO(hcutts): add GESTURE_X_OFFSET and GESTURE_Y_OFFSET.
// TODO(b/251196347): add GESTURE_{X,Y}_OFFSET and GESTURE_SCROLL_{X,Y}_DISTANCE.
// If you added a new axis, consider whether this should also be exposed as a HAL axis. Update the
// static_assert below and add the new axis here, or leave a comment summarizing your decision.
static_assert(static_cast<common::Axis>(AMOTION_EVENT_MAXIMUM_VALID_AXIS_VALUE) ==
              static_cast<common::Axis>(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
              static_cast<common::Axis>(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE));

static common::VideoFrame getHalVideoFrame(const TouchVideoFrame& frame) {
    common::VideoFrame out;
+57 −0
Original line number Diff line number Diff line
@@ -65,6 +65,10 @@ std::list<NotifyArgs> GestureConverter::handleGesture(nsecs_t when, nsecs_t read
            return {handleMove(when, readTime, gesture)};
        case kGestureTypeButtonsChange:
            return handleButtonsChange(when, readTime, gesture);
        case kGestureTypeScroll:
            return handleScroll(when, readTime, gesture);
        case kGestureTypeFling:
            return {handleFling(when, readTime, gesture)};
        case kGestureTypeSwipe:
            return handleMultiFingerSwipe(when, readTime, 3, gesture.details.swipe.dx,
                                          gesture.details.swipe.dy);
@@ -175,6 +179,59 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_
    return out;
}

std::list<NotifyArgs> GestureConverter::handleScroll(nsecs_t when, nsecs_t readTime,
                                                     const Gesture& gesture) {
    std::list<NotifyArgs> out;
    PointerCoords& coords = mFakeFingerCoords[0];
    float xCursorPosition, yCursorPosition;
    mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
    if (mCurrentClassification != MotionClassification::TWO_FINGER_SWIPE) {
        mCurrentClassification = MotionClassification::TWO_FINGER_SWIPE;
        coords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
        coords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
        coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
        mDownTime = when;
        out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN,
                                     /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1,
                                     mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
                                     yCursorPosition));
    }
    float deltaX = gesture.details.scroll.dx;
    float deltaY = gesture.details.scroll.dy;
    rotateDelta(mOrientation, &deltaX, &deltaY);

    coords.setAxisValue(AMOTION_EVENT_AXIS_X, coords.getAxisValue(AMOTION_EVENT_AXIS_X) - deltaX);
    coords.setAxisValue(AMOTION_EVENT_AXIS_Y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y) - deltaY);
    // TODO(b/262876643): set AXIS_GESTURE_{X,Y}_OFFSET.
    coords.setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, gesture.details.scroll.dx);
    coords.setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, gesture.details.scroll.dy);
    out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, /* actionButton= */ 0,
                                 mButtonState, /* pointerCount= */ 1, mFingerProps.data(),
                                 mFakeFingerCoords.data(), xCursorPosition, yCursorPosition));
    return out;
}

NotifyArgs GestureConverter::handleFling(nsecs_t when, nsecs_t readTime, const Gesture& gesture) {
    // We don't actually want to use the gestures library's fling velocity values (to ensure
    // consistency between touchscreen and touchpad flings), so we're just using the "start fling"
    // gestures as a marker for the end of a two-finger scroll gesture.
    if (gesture.details.fling.fling_state != GESTURES_FLING_START ||
        mCurrentClassification != MotionClassification::TWO_FINGER_SWIPE) {
        return {};
    }

    float xCursorPosition, yCursorPosition;
    mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
    mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE, 0);
    mFakeFingerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE, 0);
    NotifyArgs args = makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_UP,
                                     /* actionButton= */ 0, mButtonState, /* pointerCount= */ 1,
                                     mFingerProps.data(), mFakeFingerCoords.data(), xCursorPosition,
                                     yCursorPosition);
    mCurrentClassification = MotionClassification::NONE;
    return args;
}

[[nodiscard]] std::list<NotifyArgs> GestureConverter::handleMultiFingerSwipe(nsecs_t when,
                                                                             nsecs_t readTime,
                                                                             uint32_t fingerCount,
+4 −1
Original line number Diff line number Diff line
@@ -47,9 +47,12 @@ public:
                                                      const Gesture& gesture);

private:
    NotifyArgs handleMove(nsecs_t when, nsecs_t readTime, const Gesture& gesture);
    [[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> handleScroll(nsecs_t when, nsecs_t readTime,
                                                     const Gesture& gesture);
    [[nodiscard]] NotifyArgs handleFling(nsecs_t when, nsecs_t readTime, const Gesture& gesture);
    [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipe(nsecs_t when, nsecs_t readTime,
                                                               uint32_t fingerCount, float dx,
                                                               float dy);
Loading