diff options
| author | 2024-09-13 19:17:25 +0000 | |
|---|---|---|
| committer | 2024-10-08 20:13:21 +0000 | |
| commit | 2ac7e8169faa060ac33deb48847d07fb9fc4e680 (patch) | |
| tree | 9a0e43ca636317c203337d973f7f5e4776a48c42 | |
| parent | e227cadd47fe644efaf1e43a3c224b0571025d9d (diff) | |
Mouse: Add support to reverse vertical mouse scroll
Bug: 359349392
Bug: 352598211
Test: atest CursorInputMapperUnitTest
Flag: com.android.hardware.input.mouse_reverse_vertical_scrolling
Change-Id: Ib6b20f571b76cb0643bd2b31bcc8daa926306927
4 files changed, 70 insertions, 2 deletions
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h index 2f6c6d74e7..69ae587942 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -96,6 +96,9 @@ struct InputReaderConfiguration { // The key remapping has changed. KEY_REMAPPING = 1u << 14, + // The mouse settings changed, this includes mouse reverse vertical scrolling. + MOUSE_SETTINGS = 1u << 15, + // All devices must be reopened. MUST_REOPEN = 1u << 31, }; @@ -252,6 +255,10 @@ struct InputReaderConfiguration { // Keycodes to be remapped. std::map<int32_t /* fromKeyCode */, int32_t /* toKeyCode */> keyRemapping; + // True if the external mouse should have its vertical scrolling reversed, so that rotating the + // wheel downwards scrolls the content upwards. + bool mouseReverseVerticalScrollingEnabled; + InputReaderConfiguration() : virtualKeyQuietTime(0), defaultPointerDisplayId(ui::LogicalDisplayId::DEFAULT), @@ -282,7 +289,8 @@ struct InputReaderConfiguration { shouldNotifyTouchpadHardwareState(false), touchpadRightClickZoneEnabled(false), stylusButtonMotionEventsEnabled(true), - stylusPointerIconEnabled(false) {} + stylusPointerIconEnabled(false), + mouseReverseVerticalScrollingEnabled(false) {} std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const; std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueDisplayId) diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index 20cdb59b00..302caa75a0 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -164,6 +164,10 @@ std::list<NotifyArgs> CursorInputMapper::reconfigure(nsecs_t when, changes.test(InputReaderConfiguration::Change::DISPLAY_INFO) || configurePointerCapture) { configureOnChangePointerSpeed(readerConfig); } + + if (!changes.any() || changes.test(InputReaderConfiguration::Change::MOUSE_SETTINGS)) { + configureOnChangeMouseSettings(readerConfig); + } return out; } @@ -275,7 +279,12 @@ std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) { PointerCoords pointerCoords; pointerCoords.clear(); - float vscroll = mCursorScrollAccumulator.getRelativeVWheel(); + // A negative value represents inverted scrolling direction. + // Applies only if the source is a mouse. + const bool isMouse = + (mSource == AINPUT_SOURCE_MOUSE) || (mSource == AINPUT_SOURCE_MOUSE_RELATIVE); + const int scrollingDirection = (mMouseReverseVerticalScrolling && isMouse) ? -1 : 1; + float vscroll = scrollingDirection * mCursorScrollAccumulator.getRelativeVWheel(); float hscroll = mCursorScrollAccumulator.getRelativeHWheel(); bool scrolled = vscroll != 0 || hscroll != 0; @@ -537,4 +546,8 @@ void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfigurat bumpGeneration(); } +void CursorInputMapper::configureOnChangeMouseSettings(const InputReaderConfiguration& config) { + mMouseReverseVerticalScrolling = config.mouseReverseVerticalScrollingEnabled; +} + } // namespace android diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h index 3fc370cacd..403e96d758 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.h +++ b/services/inputflinger/reader/mapper/CursorInputMapper.h @@ -121,6 +121,7 @@ private: nsecs_t mLastEventTime; const bool mEnableNewMousePointerBallistics; + bool mMouseReverseVerticalScrolling = false; explicit CursorInputMapper(InputDeviceContext& deviceContext, const InputReaderConfiguration& readerConfig); @@ -129,6 +130,7 @@ private: void configureOnPointerCapture(const InputReaderConfiguration& config); void configureOnChangePointerSpeed(const InputReaderConfiguration& config); void configureOnChangeDisplayInfo(const InputReaderConfiguration& config); + void configureOnChangeMouseSettings(const InputReaderConfiguration& config); [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime); diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp index b27d02d77c..a43b64cf7a 100644 --- a/services/inputflinger/tests/CursorInputMapper_test.cpp +++ b/services/inputflinger/tests/CursorInputMapper_test.cpp @@ -882,6 +882,51 @@ TEST_F(CursorInputMapperUnitTest, HighResScrollIgnoresRegularScroll) { WithScroll(0.5f, 0.5f))))); } +TEST_F(CursorInputMapperUnitTest, ProcessReversedVerticalScroll) { + mReaderConfiguration.mouseReverseVerticalScrollingEnabled = true; + createMapper(); + + std::list<NotifyArgs> args; + args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1); + args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL, 1); + args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); + + // Reversed vertical scrolling only affects the y-axis, expect it to be -1.0f to indicate the + // inverted scroll direction. + EXPECT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithSource(AINPUT_SOURCE_MOUSE), + WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))), + VariantWith<NotifyMotionArgs>( + AllOf(WithSource(AINPUT_SOURCE_MOUSE), + WithMotionAction(AMOTION_EVENT_ACTION_SCROLL), + WithScroll(1.0f, -1.0f))))); +} + +TEST_F(CursorInputMapperUnitTest, ProcessHighResReversedVerticalScroll) { + mReaderConfiguration.mouseReverseVerticalScrollingEnabled = true; + vd_flags::high_resolution_scroll(true); + EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES)) + .WillRepeatedly(Return(true)); + EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES)) + .WillRepeatedly(Return(true)); + createMapper(); + + std::list<NotifyArgs> args; + args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60); + args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL_HI_RES, 60); + args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); + + EXPECT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithSource(AINPUT_SOURCE_MOUSE), + WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))), + VariantWith<NotifyMotionArgs>( + AllOf(WithSource(AINPUT_SOURCE_MOUSE), + WithMotionAction(AMOTION_EVENT_ACTION_SCROLL), + WithScroll(0.5f, -0.5f))))); +} + /** * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any * pointer acceleration or speed processing should not be applied. |