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

Commit 0dcf727c authored by Harry Cutts's avatar Harry Cutts Committed by Android (Google) Code Review
Browse files

Merge "touchpad: add touchpad system gesture setting" into main

parents 0e5536cf af66cee7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -245,6 +245,9 @@ struct InputReaderConfiguration {
    // True to use three-finger tap as a customizable shortcut; false to use it as a middle-click.
    bool touchpadThreeFingerTapShortcutEnabled;

    // True to enable system gestures (three- and four-finger swipes) on touchpads.
    bool touchpadSystemGesturesEnabled;

    // The set of currently disabled input devices.
    std::set<int32_t> disabledDevices;

@@ -297,6 +300,7 @@ struct InputReaderConfiguration {
            shouldNotifyTouchpadHardwareState(false),
            touchpadRightClickZoneEnabled(false),
            touchpadThreeFingerTapShortcutEnabled(false),
            touchpadSystemGesturesEnabled(true),
            stylusButtonMotionEventsEnabled(true),
            stylusPointerIconEnabled(false),
            mouseReverseVerticalScrollingEnabled(false),
+3 −2
Original line number Diff line number Diff line
@@ -351,6 +351,7 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,

        bumpGeneration();
    }
    std::list<NotifyArgs> out;
    if (!changes.any() || changes.test(InputReaderConfiguration::Change::TOUCHPAD_SETTINGS)) {
        mPropertyProvider.getProperty("Use Custom Touchpad Pointer Accel Curve")
                .setBoolValues({true});
@@ -375,11 +376,11 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,
        mPropertyProvider.getProperty("Button Right Click Zone Enable")
                .setBoolValues({config.touchpadRightClickZoneEnabled});
        mTouchpadHardwareStateNotificationsEnabled = config.shouldNotifyTouchpadHardwareState;

        mGestureConverter.setThreeFingerTapShortcutEnabled(
                config.touchpadThreeFingerTapShortcutEnabled);
        out += mGestureConverter.setEnableSystemGestures(when,
                                                         config.touchpadSystemGesturesEnabled);
    }
    std::list<NotifyArgs> out;
    if ((!changes.any() && config.pointerCaptureRequest.isEnable()) ||
        changes.test(InputReaderConfiguration::Change::POINTER_CAPTURE)) {
        mPointerCaptured = config.pointerCaptureRequest.isEnable();
+12 −0
Original line number Diff line number Diff line
@@ -132,6 +132,15 @@ std::list<NotifyArgs> GestureConverter::reset(nsecs_t when) {
    return out;
}

std::list<NotifyArgs> GestureConverter::setEnableSystemGestures(nsecs_t when, bool enable) {
    std::list<NotifyArgs> out;
    if (!enable && mCurrentClassification == MotionClassification::MULTI_FINGER_SWIPE) {
        out += handleMultiFingerSwipeLift(when, when);
    }
    mEnableSystemGestures = enable;
    return out;
}

void GestureConverter::populateMotionRanges(InputDeviceInfo& info) const {
    info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, SOURCE, 0.0f, 1.0f, 0, 0, 0);

@@ -461,6 +470,9 @@ std::list<NotifyArgs> GestureConverter::endScroll(nsecs_t when, nsecs_t readTime
                                                                             uint32_t fingerCount,
                                                                             float dx, float dy) {
    std::list<NotifyArgs> out = {};
    if (!mEnableSystemGestures) {
        return out;
    }

    if (mCurrentClassification != MotionClassification::MULTI_FINGER_SWIPE) {
        // If the user changes the number of fingers mid-way through a swipe (e.g. they start with
+3 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ public:
        mThreeFingerTapShortcutEnabled = enabled;
    }

    [[nodiscard]] std::list<NotifyArgs> setEnableSystemGestures(nsecs_t when, bool enable);

    void populateMotionRanges(InputDeviceInfo& info) const;

    [[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
@@ -104,6 +106,7 @@ private:
    InputReaderContext& mReaderContext;
    const bool mEnableFlingStop;
    const bool mEnableNoFocusChange;
    bool mEnableSystemGestures{true};

    bool mThreeFingerTapShortcutEnabled;

+102 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ const auto TOUCHPAD_PALM_REJECTION_V2 =
using testing::AllOf;
using testing::Each;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::VariantWith;

class GestureConverterTest : public testing::Test {
@@ -849,6 +850,107 @@ TEST_F(GestureConverterTest, FourFingerSwipe_Horizontal) {
                              WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));
}

TEST_F(GestureConverterTest, DisablingSystemGestures_IgnoresMultiFingerSwipe) {
    InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
    GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
    converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);

    std::list<NotifyArgs> args = converter.setEnableSystemGestures(ARBITRARY_TIME, false);
    ASSERT_THAT(args, IsEmpty());

    Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
                         /*dy=*/10);
    Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
                            /*dy=*/5);
    Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);

    args += converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
    args += converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
    args += converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
    ASSERT_THAT(args, IsEmpty());

    args = converter.setEnableSystemGestures(ARBITRARY_TIME, true);
    ASSERT_THAT(args, IsEmpty());

    args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    WithMotionAction(AMOTION_EVENT_ACTION_DOWN)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(
                                    AMOTION_EVENT_ACTION_POINTER_DOWN |
                                    1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(
                                    AMOTION_EVENT_ACTION_POINTER_DOWN |
                                    2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT)),
                            VariantWith<NotifyMotionArgs>(
                                    WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
    ASSERT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(
                        WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE))));
}

TEST_F(GestureConverterTest, DisablingSystemGestures_EndsOngoingMultiFingerSwipe) {
    InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
    GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
    converter.setDisplayId(ui::LogicalDisplayId::DEFAULT);

    Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
                         /*dy=*/10);
    std::list<NotifyArgs> args;
    args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
    ASSERT_FALSE(args.empty());

    // Disabling system gestures should end the swipe early.
    args = converter.setEnableSystemGestures(ARBITRARY_TIME, false);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    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))),
                            VariantWith<NotifyMotionArgs>(
                                    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))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
                                          WithGestureOffset(0, 0, EPSILON),
                                          WithMotionClassification(
                                                  MotionClassification::MULTI_FINGER_SWIPE),
                                          WithPointerCount(1u))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
                                          WithMotionClassification(MotionClassification::NONE)))));
    ASSERT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(
                        AllOf(WithToolType(ToolType::FINGER),
                              WithDisplayId(ui::LogicalDisplayId::DEFAULT)))));

    // Further movement in the same swipe should be ignored.
    Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
                            /*dy=*/5);
    args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
    ASSERT_THAT(args, IsEmpty());
    Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
    args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
    ASSERT_THAT(args, IsEmpty());

    // But single-finger pointer motion should be reported.
    Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
    args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                        AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
                              WithRelativeMotion(-5, 10), WithButtonState(0)))));
}

TEST_F(GestureConverterTest, Pinch_Inwards) {
    input_flags::enable_touchpad_no_focus_change(true);