Loading services/inputflinger/reader/mapper/TouchInputMapper.cpp +22 −1 Original line number Diff line number Diff line Loading @@ -1855,6 +1855,27 @@ std::list<NotifyArgs> TouchInputMapper::consumeRawTouches(nsecs_t when, nsecs_t } } if (!mCurrentRawState.rawPointerData.hoveringIdBits.isEmpty() && mCurrentRawState.rawPointerData.touchingIdBits.isEmpty() && mDeviceMode != DeviceMode::UNSCALED) { // We have hovering pointers, and there are no touching pointers. bool hoveringPointersInFrame = false; auto hoveringIds = mCurrentRawState.rawPointerData.hoveringIdBits; while (!hoveringIds.isEmpty()) { uint32_t id = hoveringIds.clearFirstMarkedBit(); const auto& pointer = mCurrentRawState.rawPointerData.pointerForId(id); if (isPointInsidePhysicalFrame(pointer.x, pointer.y)) { hoveringPointersInFrame = true; break; } } if (!hoveringPointersInFrame) { // All hovering pointers are outside the physical frame. outConsumed = true; return out; } } if (mLastRawState.rawPointerData.touchingIdBits.isEmpty() && !mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) { // Pointer just went down. Check for virtual key press or off-screen touches. Loading @@ -1865,7 +1886,7 @@ std::list<NotifyArgs> TouchInputMapper::consumeRawTouches(nsecs_t when, nsecs_t if (!isPointInsidePhysicalFrame(pointer.x, pointer.y) && mDeviceMode != DeviceMode::UNSCALED) { // If exactly one pointer went down, check for virtual key hit. // Otherwise we will drop the entire stroke. // Otherwise, we will drop the entire stroke. if (mCurrentRawState.rawPointerData.touchingIdBits.count() == 1) { const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y); if (virtualKey) { Loading services/inputflinger/tests/InputReader_test.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -6735,6 +6735,54 @@ TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsChangedToTouchNavigation_upda ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mDevice->getSources()); } TEST_F(SingleTouchInputMapperTest, HoverEventsOutsidePhysicalFrameAreIgnored) { // Initialize the device without setting device source to touch navigation. addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(ui::ROTATION_0); prepareButtons(); prepareAxes(POSITION); mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0); // Set a physical frame in the display viewport. auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); viewport->physicalLeft = 0; viewport->physicalTop = 0; viewport->physicalRight = DISPLAY_WIDTH / 2; viewport->physicalBottom = DISPLAY_HEIGHT / 2; mFakePolicy->updateViewport(*viewport); configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); // Hovering inside the physical frame produces events. processKey(mapper, BTN_TOOL_PEN, 1); processMove(mapper, RAW_X_MIN + 1, RAW_Y_MIN + 1); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))); // Leaving the physical frame ends the hovering gesture. processMove(mapper, RAW_X_MAX - 1, RAW_Y_MAX - 1); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT))); // Moving outside the physical frame does not produce events. processMove(mapper, RAW_X_MAX - 2, RAW_Y_MAX - 2); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled()); // Re-entering the physical frame produces events. processMove(mapper, RAW_X_MIN, RAW_Y_MIN); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))); } // --- TouchDisplayProjectionTest --- class TouchDisplayProjectionTest : public SingleTouchInputMapperTest { Loading Loading
services/inputflinger/reader/mapper/TouchInputMapper.cpp +22 −1 Original line number Diff line number Diff line Loading @@ -1855,6 +1855,27 @@ std::list<NotifyArgs> TouchInputMapper::consumeRawTouches(nsecs_t when, nsecs_t } } if (!mCurrentRawState.rawPointerData.hoveringIdBits.isEmpty() && mCurrentRawState.rawPointerData.touchingIdBits.isEmpty() && mDeviceMode != DeviceMode::UNSCALED) { // We have hovering pointers, and there are no touching pointers. bool hoveringPointersInFrame = false; auto hoveringIds = mCurrentRawState.rawPointerData.hoveringIdBits; while (!hoveringIds.isEmpty()) { uint32_t id = hoveringIds.clearFirstMarkedBit(); const auto& pointer = mCurrentRawState.rawPointerData.pointerForId(id); if (isPointInsidePhysicalFrame(pointer.x, pointer.y)) { hoveringPointersInFrame = true; break; } } if (!hoveringPointersInFrame) { // All hovering pointers are outside the physical frame. outConsumed = true; return out; } } if (mLastRawState.rawPointerData.touchingIdBits.isEmpty() && !mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) { // Pointer just went down. Check for virtual key press or off-screen touches. Loading @@ -1865,7 +1886,7 @@ std::list<NotifyArgs> TouchInputMapper::consumeRawTouches(nsecs_t when, nsecs_t if (!isPointInsidePhysicalFrame(pointer.x, pointer.y) && mDeviceMode != DeviceMode::UNSCALED) { // If exactly one pointer went down, check for virtual key hit. // Otherwise we will drop the entire stroke. // Otherwise, we will drop the entire stroke. if (mCurrentRawState.rawPointerData.touchingIdBits.count() == 1) { const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y); if (virtualKey) { Loading
services/inputflinger/tests/InputReader_test.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -6735,6 +6735,54 @@ TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsChangedToTouchNavigation_upda ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mDevice->getSources()); } TEST_F(SingleTouchInputMapperTest, HoverEventsOutsidePhysicalFrameAreIgnored) { // Initialize the device without setting device source to touch navigation. addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(ui::ROTATION_0); prepareButtons(); prepareAxes(POSITION); mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0); // Set a physical frame in the display viewport. auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); viewport->physicalLeft = 0; viewport->physicalTop = 0; viewport->physicalRight = DISPLAY_WIDTH / 2; viewport->physicalBottom = DISPLAY_HEIGHT / 2; mFakePolicy->updateViewport(*viewport); configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); // Hovering inside the physical frame produces events. processKey(mapper, BTN_TOOL_PEN, 1); processMove(mapper, RAW_X_MIN + 1, RAW_Y_MIN + 1); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))); // Leaving the physical frame ends the hovering gesture. processMove(mapper, RAW_X_MAX - 1, RAW_Y_MAX - 1); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT))); // Moving outside the physical frame does not produce events. processMove(mapper, RAW_X_MAX - 2, RAW_Y_MAX - 2); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled()); // Re-entering the physical frame produces events. processMove(mapper, RAW_X_MIN, RAW_Y_MIN); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER))); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))); } // --- TouchDisplayProjectionTest --- class TouchDisplayProjectionTest : public SingleTouchInputMapperTest { Loading