diff options
author | Prabir Pradhan <prabirmsp@google.com> | 2022-06-24 18:37:04 +0000 |
---|---|---|
committer | Prabir Pradhan <prabirmsp@google.com> | 2022-11-30 18:19:45 +0000 |
commit | 5d9d8e998c655aa680fcdafe2dfa03bc9a937995 (patch) | |
tree | b4b981065e249214a9a3f21591a343997075c201 | |
parent | 722325c5ada97021b0e39bd4fcdfaec3f396a026 (diff) | |
download | native-5d9d8e998c655aa680fcdafe2dfa03bc9a937995.tar.gz |
Do not transform values from a SOURCE_MOUSE_RELATIVE device
In Pointer Capture mode, we want the API to report events directly
as they are coming from the kernel without any transformations.
We already do this for SORUCE_TOUCHPAD. Here, we update the handling
of SOURCE_MOUSE_RELATIVE so that when Pointer Capture is enabled,
mouse events are not effected by the display or window state.
Bug: 233184154
Test: Apply non-standard scaling to a device using
"adb shell wm size" and run: atest MicrosoftSculpttouchTest
Test: atest libinput_tests
Test: atest inputflinger_tests
Change-Id: Ia6ef5a21312da949ac2704e9bfe4638626d3a894
Merged-In: Ia6ef5a21312da949ac2704e9bfe4638626d3a894
-rw-r--r-- | libs/input/Input.cpp | 5 | ||||
-rw-r--r-- | libs/input/tests/InputEvent_test.cpp | 10 | ||||
-rw-r--r-- | services/inputflinger/reader/mapper/CursorInputMapper.cpp | 8 | ||||
-rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 42 |
4 files changed, 55 insertions, 10 deletions
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 4127f7ce10..f646bd4a13 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -64,9 +64,10 @@ float transformAngle(const ui::Transform& transform, float angleRadians) { } bool shouldDisregardTransformation(uint32_t source) { - // Do not apply any transformations to axes from joysticks or touchpads. + // Do not apply any transformations to axes from joysticks, touchpads, or relative mice. return isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK) || - isFromSource(source, AINPUT_SOURCE_CLASS_POSITION); + isFromSource(source, AINPUT_SOURCE_CLASS_POSITION) || + isFromSource(source, AINPUT_SOURCE_MOUSE_RELATIVE); } bool shouldDisregardOffset(uint32_t source) { diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp index a92016ba3b..4b3124636b 100644 --- a/libs/input/tests/InputEvent_test.cpp +++ b/libs/input/tests/InputEvent_test.cpp @@ -715,10 +715,10 @@ TEST_F(MotionEventTest, ApplyTransform) { } TEST_F(MotionEventTest, JoystickAndTouchpadAreNotTransformed) { - constexpr static std::array kNonTransformedSources = {std::pair(AINPUT_SOURCE_TOUCHPAD, - AMOTION_EVENT_ACTION_DOWN), - std::pair(AINPUT_SOURCE_JOYSTICK, - AMOTION_EVENT_ACTION_MOVE)}; + constexpr static std::array kNonTransformedSources = + {std::pair(AINPUT_SOURCE_TOUCHPAD, AMOTION_EVENT_ACTION_DOWN), + std::pair(AINPUT_SOURCE_JOYSTICK, AMOTION_EVENT_ACTION_MOVE), + std::pair(AINPUT_SOURCE_MOUSE_RELATIVE, AMOTION_EVENT_ACTION_MOVE)}; // Create a rotate-90 transform with an offset (like a window which isn't fullscreen). ui::Transform transform(ui::Transform::ROT_90, 800, 400); transform.set(transform.tx() + 20, transform.ty() + 40); @@ -738,7 +738,7 @@ TEST_F(MotionEventTest, JoystickAndTouchpadAreNotTransformed) { TEST_F(MotionEventTest, NonPointerSourcesAreNotTranslated) { constexpr static std::array kNonPointerSources = {std::pair(AINPUT_SOURCE_TRACKBALL, AMOTION_EVENT_ACTION_DOWN), - std::pair(AINPUT_SOURCE_MOUSE_RELATIVE, + std::pair(AINPUT_SOURCE_TOUCH_NAVIGATION, AMOTION_EVENT_ACTION_MOVE)}; // Create a rotate-90 transform with an offset (like a window which isn't fullscreen). ui::Transform transform(ui::Transform::ROT_90, 800, 400); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index ea51b8e9dc..40e9a3cf22 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -203,7 +203,8 @@ void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* } } - if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { + if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO) || + configurePointerCapture) { mOrientation = DISPLAY_ORIENTATION_0; const bool isOrientedDevice = (mParameters.orientationAware && mParameters.hasAssociatedDisplay); @@ -212,8 +213,9 @@ void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* // anything if the device is already orientation-aware. If the device is not // orientation-aware, then we need to apply the inverse rotation of the display so that // when the display rotation is applied later as a part of the per-window transform, we - // get the expected screen coordinates. - if (!isOrientedDevice) { + // get the expected screen coordinates. When pointer capture is enabled, we do not apply any + // rotations and report values directly from the input device. + if (!isOrientedDevice && mParameters.mode != Parameters::Mode::POINTER_RELATIVE) { std::optional<DisplayViewport> internalViewport = config->getDisplayViewportByType(ViewportType::INTERNAL); if (internalViewport) { diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index db4669967f..5d6ec7487a 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -4974,6 +4974,48 @@ TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) { ASSERT_EQ(20, args.pointerCoords[0].getY()); } +TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) { + addConfigurationProperty("cursor.mode", "pointer"); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); + + NotifyDeviceResetArgs resetArgs; + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); + ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime); + ASSERT_EQ(DEVICE_ID, resetArgs.deviceId); + + // Ensure the display is rotated. + prepareDisplay(DISPLAY_ORIENTATION_90); + + NotifyMotionArgs args; + + // Verify that the coordinates are rotated. + process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10); + process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20); + process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); + ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source); + ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); + ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X)); + ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)); + + // Enable Pointer Capture. + mFakePolicy->setPointerCapture(true); + configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE); + NotifyPointerCaptureChangedArgs captureArgs; + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs)); + ASSERT_TRUE(captureArgs.request.enable); + + // Move and verify rotation is not applied. + process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10); + process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20); + process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); + ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); + ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); + ASSERT_EQ(10, args.pointerCoords[0].getX()); + ASSERT_EQ(20, args.pointerCoords[0].getY()); +} + TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) { CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); |