diff options
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.cpp | 45 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.h | 6 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 51 |
3 files changed, 89 insertions, 13 deletions
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index fb30b88b8d..b748bfeffe 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -608,8 +608,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) { if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } - } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN && - mParameters.hasAssociatedDisplay) { + } else if (isTouchScreen()) { mSource = AINPUT_SOURCE_TOUCHSCREEN; mDeviceMode = DeviceMode::DIRECT; if (hasStylus()) { @@ -1453,8 +1452,11 @@ void TouchInputMapper::sync(nsecs_t when) { void TouchInputMapper::processRawTouches(bool timeout) { if (mDeviceMode == DeviceMode::DISABLED) { // Drop all input if the device is disabled. + cancelTouch(mCurrentRawState.when); mCurrentRawState.clear(); mRawStatesPending.clear(); + mCurrentCookedState.clear(); + updateTouchSpots(); return; } @@ -1586,17 +1588,7 @@ void TouchInputMapper::cookAndDispatch(nsecs_t when) { dispatchPointerUsage(when, policyFlags, pointerUsage); } else { - if (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches && - mPointerController != nullptr) { - mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT); - mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); - - mPointerController->setButtonState(mCurrentRawState.buttonState); - mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords, - mCurrentCookedState.cookedPointerData.idToIndex, - mCurrentCookedState.cookedPointerData.touchingIdBits, - mViewport.displayId); - } + updateTouchSpots(); if (!mCurrentMotionAborted) { dispatchButtonRelease(when, policyFlags); @@ -1625,6 +1617,33 @@ void TouchInputMapper::cookAndDispatch(nsecs_t when) { mLastCookedState.copyFrom(mCurrentCookedState); } +void TouchInputMapper::updateTouchSpots() { + if (!mConfig.showTouches || mPointerController == nullptr) { + return; + } + + // Update touch spots when this is a touchscreen even when it's not enabled so that we can + // clear touch spots. + if (mDeviceMode != DeviceMode::DIRECT && + (mDeviceMode != DeviceMode::DISABLED || !isTouchScreen())) { + return; + } + + mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT); + mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); + + mPointerController->setButtonState(mCurrentRawState.buttonState); + mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords, + mCurrentCookedState.cookedPointerData.idToIndex, + mCurrentCookedState.cookedPointerData.touchingIdBits, + mViewport.displayId); +} + +bool TouchInputMapper::isTouchScreen() { + return mParameters.deviceType == Parameters::DeviceType::TOUCH_SCREEN && + mParameters.hasAssociatedDisplay; +} + void TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) { if (mDeviceMode == DeviceMode::DIRECT && hasExternalStylus() && mExternalStylusId != -1) { mCurrentRawState.buttonState |= mExternalStylusState.buttons; diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index df6581d1c8..66218251f9 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -757,6 +757,12 @@ private: PointerCoords* outCoords, const uint32_t* outIdToIndex, BitSet32 idBits) const; + // Returns if this touch device is a touch screen with an associated display. + bool isTouchScreen(); + // Updates touch spots if they are enabled. Should only be used when this device is a + // touchscreen. + void updateTouchSpots(); + bool isPointInsideSurface(int32_t x, int32_t y); const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y); diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 91d5864670..36da8ddc8e 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -7362,6 +7362,57 @@ TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) { mFakeListener->assertNotifyMotionWasNotCalled(); } +TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) { + addConfigurationProperty("touch.deviceType", "touchScreen"); + mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, + DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, NO_PORT, + ViewportType::INTERNAL); + std::optional<DisplayViewport> optionalDisplayViewport = + mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID); + ASSERT_TRUE(optionalDisplayViewport.has_value()); + DisplayViewport displayViewport = *optionalDisplayViewport; + + configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); + prepareAxes(POSITION); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); + + // Finger down + int32_t x = 100, y = 100; + processPosition(mapper, x, y); + processSync(mapper); + + NotifyMotionArgs motionArgs; + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); + EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); + + // Deactivate display viewport + displayViewport.isActive = false; + ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport)); + configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); + + // Finger move + x += 10, y += 10; + processPosition(mapper, x, y); + processSync(mapper); + + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); + EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action); + + // Reactivate display viewport + displayViewport.isActive = true; + ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport)); + configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); + + // Finger move again + x += 10, y += 10; + processPosition(mapper, x, y); + processSync(mapper); + + // Gesture is aborted, so events after display is activated won't be dispatched until there is + // no pointer on the touch device. + mFakeListener->assertNotifyMotionWasNotCalled(); +} + TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { // Setup the first touch screen device. prepareAxes(POSITION | ID | SLOT); |