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

Commit 99aba56b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add configuration for disabling stylus button motion events"

parents 0fc8c8a9 7aa7ff0d
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -197,6 +197,9 @@ struct InputReaderConfiguration {
        // The keyboard layout association has changed.
        CHANGE_KEYBOARD_LAYOUT_ASSOCIATION = 1 << 11,

        // The stylus button reporting configurations has changed.
        CHANGE_STYLUS_BUTTON_REPORTING = 1 << 12,

        // All devices must be reopened.
        CHANGE_MUST_REOPEN = 1 << 31,
    };
@@ -309,6 +312,10 @@ struct InputReaderConfiguration {
    // The set of currently disabled input devices.
    std::set<int32_t> disabledDevices;

    // True if stylus button reporting through motion events should be enabled, in which case
    // stylus button state changes are reported through motion events.
    bool stylusButtonMotionEventsEnabled;

    InputReaderConfiguration()
          : virtualKeyQuietTime(0),
            pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f,
@@ -329,7 +336,8 @@ struct InputReaderConfiguration {
            pointerGestureMovementSpeedRatio(0.8f),
            pointerGestureZoomSpeedRatio(0.3f),
            showTouches(false),
            pointerCaptureRequest() {}
            pointerCaptureRequest(),
            stylusButtonMotionEventsEnabled(true) {}

    static std::string changesToString(uint32_t changes);

+14 −3
Original line number Diff line number Diff line
@@ -88,6 +88,14 @@ static ui::Size getNaturalDisplaySize(const DisplayViewport& viewport) {
    return rotatedDisplaySize;
}

static int32_t filterButtonState(InputReaderConfiguration& config, int32_t buttonState) {
    if (!config.stylusButtonMotionEventsEnabled) {
        buttonState &=
                ~(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY | AMOTION_EVENT_BUTTON_STYLUS_SECONDARY);
    }
    return buttonState;
}

// --- RawPointerData ---

void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
@@ -1400,8 +1408,9 @@ std::list<NotifyArgs> TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
    next.readTime = readTime;

    // Sync button state.
    next.buttonState =
            mTouchButtonAccumulator.getButtonState() | mCursorButtonAccumulator.getButtonState();
    next.buttonState = filterButtonState(mConfig,
                                         mTouchButtonAccumulator.getButtonState() |
                                                 mCursorButtonAccumulator.getButtonState());

    // Sync scroll
    next.rawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
@@ -1640,7 +1649,9 @@ bool TouchInputMapper::isTouchScreen() {
void TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) {
    if (mDeviceMode == DeviceMode::DIRECT && hasExternalStylus()) {
        // If any of the external buttons are already pressed by the touch device, ignore them.
        const int32_t pressedButtons = ~mCurrentRawState.buttonState & mExternalStylusState.buttons;
        const int32_t pressedButtons =
                filterButtonState(mConfig,
                                  ~mCurrentRawState.buttonState & mExternalStylusState.buttons);
        const int32_t releasedButtons =
                mExternalStylusButtonsApplied & ~mExternalStylusState.buttons;

+4 −0
Original line number Diff line number Diff line
@@ -201,6 +201,10 @@ void FakeInputReaderPolicy::setVelocityControlParams(const VelocityControlParame
    mConfig.wheelVelocityControlParameters = params;
}

void FakeInputReaderPolicy::setStylusButtonMotionEventsEnabled(bool enabled) {
    mConfig.stylusButtonMotionEventsEnabled = enabled;
}

void FakeInputReaderPolicy::getReaderConfiguration(InputReaderConfiguration* outConfig) {
    *outConfig = mConfig;
}
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ public:
    float getPointerGestureMovementSpeedRatio();
    float getPointerGestureZoomSpeedRatio();
    void setVelocityControlParams(const VelocityControlParameters& params);
    void setStylusButtonMotionEventsEnabled(bool enabled);

private:
    void getReaderConfiguration(InputReaderConfiguration* outConfig) override;
+90 −0
Original line number Diff line number Diff line
@@ -2020,6 +2020,56 @@ TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
                  WithDeviceId(touchscreenId))));
}

TYPED_TEST(StylusButtonIntegrationTest, StylusButtonMotionEventsDisabled) {
    TestFixture::mFakePolicy->setStylusButtonMotionEventsEnabled(false);
    TestFixture::mReader->requestRefreshConfiguration(
            InputReaderConfiguration::CHANGE_STYLUS_BUTTON_REPORTING);

    const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
    const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
    const auto stylusId = TestFixture::mStylusInfo.getId();

    // Start a stylus gesture. By the time this event is processed, the configuration change that
    // was requested is guaranteed to be completed.
    TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
    TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
    TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
    TestFixture::mTouchscreen->sendDown(centerPoint);
    TestFixture::mTouchscreen->sendSync();
    ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
                  WithDeviceId(touchscreenId))));

    // Press and release a stylus button. Each change only generates a MOVE motion event.
    // Key events are unaffected.
    TestFixture::mStylus->pressKey(BTN_STYLUS);
    ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
            AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
    ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
                  WithDeviceId(touchscreenId))));

    TestFixture::mStylus->releaseKey(BTN_STYLUS);
    ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
            AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
    ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
                  WithDeviceId(touchscreenId))));

    // Finish the stylus gesture.
    TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
    TestFixture::mTouchscreen->sendSync();
    ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
                  WithDeviceId(touchscreenId))));
}

// --- ExternalStylusIntegrationTest ---

// Verify the behavior of an external stylus. An external stylus can report pressure or button
@@ -6577,6 +6627,46 @@ TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
                  WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
}

TEST_F(SingleTouchInputMapperTest, StylusButtonMotionEventsDisabled) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(ui::ROTATION_0);
    prepareButtons();
    prepareAxes(POSITION);

    mFakePolicy->setStylusButtonMotionEventsEnabled(false);

    SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());

    // Press a stylus button.
    processKey(mapper, BTN_STYLUS, 1);
    processSync(mapper);

    // Start a touch gesture and ensure that the stylus button is not reported.
    processDown(mapper, 100, 200);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));

    // Release and press the stylus button again.
    processKey(mapper, BTN_STYLUS, 0);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
    processKey(mapper, BTN_STYLUS, 1);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));

    // Release the touch gesture.
    processUp(mapper);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));

    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}

TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsSetToTouchNavigation_setsCorrectType) {
    mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
    prepareDisplay(ui::ROTATION_0);