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

Commit 5d0d97d0 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Dynamically add STYLUS source for multi-touch devices - part 2

This is a follow-up to I70cc15f8f354e3fc876024d194a6f320fabd6d2c.

The previous change added SOURCE_STYLUS to events dynamically if they
came from a stylus tool type. In this change, we instead dynamically add
SOURCE_STYLUS to the InputDevice whenever it produces an MT_TOOL_PEN
event. This means all the events generated by that device will have
SOURCE_STYLUS added to it from that point onwards.

Bug: 246991366
Test: atest inputflinger_tests
Change-Id: I61963563eb4cdd41957247db100fcb87cc1b278b
parent 658e4e3c
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -119,6 +119,18 @@ void MultiTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) {
            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
            }
        } else if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS && !mStylusMtToolSeen) {
            mStylusMtToolSeen = true;
            // The multi-touch device produced a stylus event with MT_TOOL_PEN. Dynamically
            // re-configure this input device so that we add SOURCE_STYLUS if we haven't already.
            // This is to cover the case where we cannot reliably detect whether a multi-touch
            // device will ever produce stylus events when it is initially being configured.
            if (!isFromSource(mSource, AINPUT_SOURCE_STYLUS)) {
                // Add the stylus source immediately so that it is included in any events generated
                // before we have a chance to re-configure the device.
                mSource |= AINPUT_SOURCE_STYLUS;
                bumpGeneration();
            }
        }
        if (shouldSimulateStylusWithTouch() &&
            outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER) {
@@ -200,7 +212,8 @@ void MultiTouchInputMapper::configureRawPointerAxes() {
}

bool MultiTouchInputMapper::hasStylus() const {
    return mTouchButtonAccumulator.hasStylus() || shouldSimulateStylusWithTouch();
    return mStylusMtToolSeen || mTouchButtonAccumulator.hasStylus() ||
            shouldSimulateStylusWithTouch();
}

bool MultiTouchInputMapper::shouldSimulateStylusWithTouch() const {
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ private:
    // Specifies the pointer id bits that are in use, and their associated tracking id.
    BitSet32 mPointerIdBits;
    int32_t mPointerTrackingIdMap[MAX_POINTER_ID + 1];

    bool mStylusMtToolSeen{false};
};

} // namespace android
+0 −9
Original line number Diff line number Diff line
@@ -3763,15 +3763,12 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion(
    PointerCoords pointerCoords[MAX_POINTERS];
    PointerProperties pointerProperties[MAX_POINTERS];
    uint32_t pointerCount = 0;
    bool stylusToolFound = false;
    while (!idBits.isEmpty()) {
        uint32_t id = idBits.clearFirstMarkedBit();
        uint32_t index = idToIndex[id];
        pointerProperties[pointerCount].copyFrom(properties[index]);
        pointerCoords[pointerCount].copyFrom(coords[index]);

        stylusToolFound |= isStylusToolType(pointerProperties[pointerCount].toolType);

        if (changedId >= 0 && id == uint32_t(changedId)) {
            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        }
@@ -3803,12 +3800,6 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion(
    if (mDeviceMode == DeviceMode::POINTER) {
        mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
    }
    if (stylusToolFound) {
        // Dynamically add the stylus source when there's a stylus tool being used to cover the case
        // where we cannot reliably detect whether a multi-touch device will ever produce stylus
        // events when it is initially being configured.
        source |= AINPUT_SOURCE_STYLUS;
    }
    const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
    const int32_t deviceId = getDeviceId();
    std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
+18 −5
Original line number Diff line number Diff line
@@ -10788,11 +10788,12 @@ TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown)
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(MultiTouchInputMapperTest, ToolTypeSource) {
TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);
    prepareAxes(POSITION | ID | SLOT | PRESSURE | TOOL_TYPE);
    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
    // Even if the device supports reporting the ABS_MT_TOOL_TYPE axis, which could give it the
    // ability to report MT_TOOL_PEN, we do not report the device as coming from a stylus source.
@@ -10801,7 +10802,7 @@ TEST_F(MultiTouchInputMapperTest, ToolTypeSource) {
    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
    // However, if the device ever ends up reporting an event with MT_TOOL_PEN, it should be
    // reported with the stylus source, even through the device doesn't support the stylus source.
    // reported with the stylus source.
    processId(mapper, FIRST_TRACKING_ID);
    processToolType(mapper, MT_TOOL_PEN);
    processPosition(mapper, 100, 200);
@@ -10812,15 +10813,27 @@ TEST_F(MultiTouchInputMapperTest, ToolTypeSource) {
                  WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
    // Now that we know the device supports styluses, ensure that the device is re-configured with
    // the stylus source.
    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, mapper.getSources());
    {
        const auto& devices = mReader->getInputDevices();
        auto deviceInfo =
                std::find_if(devices.begin(), devices.end(),
                             [](const InputDeviceInfo& info) { return info.getId() == DEVICE_ID; });
        LOG_ALWAYS_FATAL_IF(deviceInfo == devices.end(), "Cannot find InputDevice");
        ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, deviceInfo->getSources());
    }
    // Ensure the device was not reset to prevent interruptions of any ongoing gestures.
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
    processId(mapper, INVALID_TRACKING_ID);
    processSync(mapper);
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
                  WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
    // The mapper should still report only a touchscreen source.
    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
}
// --- MultiTouchInputMapperTest_ExternalDevice ---