From dba57c3cc89fcc8e9b218541701a4565607c8432 Mon Sep 17 00:00:00 2001 From: electrikjesus Date: Fri, 23 Feb 2024 12:48:15 -0500 Subject: [PATCH 1/9] inputflinger: Allow setting right mouse as back Allows overriding AMOTION_EVENT_BUTTON_SECONDARY with AMOTION_EVENT_BUTTON_BACK, using a property trigger. This will work with the ro.boot.force.right_mouse_as_back (true/false) property, or the androidboot.force.right_mouse_as_back (true/false) kernel cmdline option. --- .../mapper/accumulator/CursorButtonAccumulator.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp index 2d7d73b4a3cf..992e13ccf7c3 100644 --- a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp +++ b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp @@ -18,6 +18,7 @@ #include "EventHub.h" #include "InputDevice.h" +#include namespace android { @@ -84,7 +85,13 @@ uint32_t CursorButtonAccumulator::getButtonState() const { result |= AMOTION_EVENT_BUTTON_PRIMARY; } if (mBtnRight) { - result |= AMOTION_EVENT_BUTTON_SECONDARY; + char mBtnRightState[PROPERTY_VALUE_MAX] = {0}; + property_get("ro.boot.force.right_mouse_as_back", mBtnRightState, "false"); + if (strcmp(mBtnRightState, "true") == 0) { + result |= AMOTION_EVENT_BUTTON_BACK; + } else { + result |= AMOTION_EVENT_BUTTON_SECONDARY; + } } if (mBtnMiddle) { result |= AMOTION_EVENT_BUTTON_TERTIARY; From 04129801008ca7dad97735e41131083031188491 Mon Sep 17 00:00:00 2001 From: electrikjesus Date: Wed, 6 Mar 2024 19:09:55 -0500 Subject: [PATCH 2/9] inputflinger: Move to letting us override win key with a property This requires a commit in frameworks/base to be removed: 5bc2c3d520e958493c9b4d5624457403267c9689 We can use ro.boot.force.win_as_home=1 or androidboot.force.win_as_home=1 to trigger the legacy behavior of Win hey being HOME action --- services/inputflinger/dispatcher/InputDispatcher.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 93bae30d10a5..b533d700c90b 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -62,6 +62,7 @@ static constexpr bool DEBUG_TOUCH_OCCLUSION = true; #include #include #include +#include #include #include @@ -3760,12 +3761,17 @@ void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChange */ void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action, int32_t& keyCode, int32_t& metaState) { + // Allow overriding win key with home key + char mWinAsHome[PROPERTY_VALUE_MAX] = {0}; + property_get("ro.boot.force.win_as_home", mWinAsHome, "0"); if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) { int32_t newKeyCode = AKEYCODE_UNKNOWN; if (keyCode == AKEYCODE_DEL) { newKeyCode = AKEYCODE_BACK; } else if (keyCode == AKEYCODE_ENTER) { newKeyCode = AKEYCODE_HOME; + } else if (strcmp(mWinAsHome, "1") == 0) { + newKeyCode = AKEYCODE_HOME; } if (newKeyCode != AKEYCODE_UNKNOWN) { std::scoped_lock _l(mLock); From 22a3fd84146e09494ac86acfe50514cde1e11b0a Mon Sep 17 00:00:00 2001 From: zhenyiwu Date: Tue, 11 Jul 2023 12:09:21 +0800 Subject: [PATCH 3/9] frameworks/native: Fix multi-display multi-mouse issue The inputflinger can not handle multi USB mouse for multi display use case. An attempt was made to append the input-port-associations.xml configuration file to vendor/etc/ with official documentation, but can not handle multi USB mouse for multi display use case. The reason is that USB mouse can be multiple, and the associated diaplay ID can be multiple,but PointerController is singleton unique and only one viewport and one display id are saved in PointerController So in the case of multiple USB mouse, although the associated display id is saved in each USB mouse, the target display id and the target viewport are judged according to the viewport and display id saved in PointerController,so only one USB mouse can be mapped to one display other USB mouse can't be mapped to display. So need to remove the code that determines the display id based on the controller,and set an associated display id for each CursorInputMapper. Correct the viewport saved in PointerController based on the associated viewport before handling mouse events. Bug: None Test: atest inputflinger_tests Change-Id: I907d0e7675df02c1edb42060a3e8fe535feac137 --- services/inputflinger/reader/mapper/CursorInputMapper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index 32f414388e64..a38788cf0511 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -400,7 +400,11 @@ void CursorInputMapper::process(const RawEvent* rawEvent) { mCursorMotionAccumulator.process(rawEvent); mCursorPositionAccumulator.process(rawEvent); mCursorScrollAccumulator.process(rawEvent); - + if (auto viewport = mDeviceContext.getAssociatedViewport(); viewport) { + if (viewport->displayId != mPointerController->getDisplayId()) { + mPointerController->setDisplayViewport(*viewport); + } + } if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { sync(rawEvent->when, rawEvent->readTime); } From aa8d3038ab2449271e19d3a44e19b391c694e0b7 Mon Sep 17 00:00:00 2001 From: dzy Date: Mon, 13 Feb 2023 17:47:36 +0800 Subject: [PATCH 4/9] multi-display:inputflinger service support mouse display on external screen. Tips: Must setprop sys.mouse.presentation 1 Depend on commit:frameworks/base(60d9f87,"Multi-display:support mouse...") Source: https://github.com/TinkerBoard2-Android/frameworks-native/commit/d3f542f1089c76b3c4b5b4c9d215867c3715ed46 Change-Id: I421eadd92ff82c2bc402858ee67fc10597d75ce0 --- .../inputflinger/include/InputReaderBase.h | 1 + .../reader/mapper/CursorInputMapper.cpp | 18 +++++++++++++++++- .../reader/mapper/CursorInputMapper.h | 2 ++ .../inputflinger/tests/InputReader_test.cpp | 5 +++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h index 605f06fa50de..63b5ca2f1a09 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -394,6 +394,7 @@ class InputReaderPolicyInterface : public virtual RefBase { /* Gets the affine calibration associated with the specified device. */ virtual TouchAffineTransformation getTouchAffineTransformation( const std::string& inputDeviceDescriptor, int32_t surfaceRotation) = 0; + virtual int32_t notifyDisplayIdChanged() = 0; }; } // namespace android diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index a38788cf0511..84977e4270a8 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -24,6 +24,7 @@ #include "CursorScrollAccumulator.h" #include "PointerControllerInterface.h" #include "TouchCursorInputMapperCommon.h" +#include namespace android { @@ -362,6 +363,7 @@ void CursorInputMapper::dumpParameters(std::string& dump) { void CursorInputMapper::reset(nsecs_t when) { mButtonState = 0; mDownTime = 0; + mDisplayId=0; mPointerVelocityControl.reset(); mWheelXVelocityControl.reset(); @@ -523,7 +525,21 @@ void CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) { pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); - displayId = mPointerController->getDisplayId(); + + char mMousePresentation[PROPERTY_VALUE_MAX] = {0}; + property_get("sys.mouse.presentation", mMousePresentation, "0"); + if (strcmp(mMousePresentation, "1") == 0) { + displayId = mDisplayId; + float minX, minY, maxX, maxY; + if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { + if(xCursorPosition==minX||xCursorPosition==maxX||yCursorPosition==minY||yCursorPosition==maxY){ + displayId=getPolicy()->notifyDisplayIdChanged(); + mDisplayId=displayId; + } + } + }else{ + displayId = mPointerController->getDisplayId(); + } } else { // Pointer capture and navigation modes pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h index 9b7807736f9a..1d2fa3d5327d 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.h +++ b/services/inputflinger/reader/mapper/CursorInputMapper.h @@ -140,6 +140,8 @@ class CursorInputMapper : public InputMapper { float mVWheelScale; float mHWheelScale; + int32_t mDisplayId; + // Velocity controls for mouse pointer and wheel movements. // The controls for X and Y wheel movements are separate to keep them decoupled. VelocityControl mPointerVelocityControl; diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index b419d9ab3d4f..bec39105a9a4 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -303,6 +303,11 @@ class FakeInputReaderPolicy : public InputReaderPolicyInterface { return mInputDevices; } + int32_t notifyDisplayIdChanged(){ + return 0; + } + + TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor, int32_t surfaceRotation) { return transform; From 9ff2a79e09639a70aecc74f2fc0e8bb2d1c627b0 Mon Sep 17 00:00:00 2001 From: Jon West Date: Thu, 14 Nov 2024 09:08:37 -0500 Subject: [PATCH 5/9] multi-display: inputflinger: Natural mouse display transition updates Remember Y position and swap minX/maxX when switching. This gives us a more natural cursor movement when switching displays Requires: frameworks/native: multi-display:inputflinger service support mouse display on external screen --- services/inputflinger/reader/mapper/CursorInputMapper.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index 84977e4270a8..0ac6dfe2d210 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -532,9 +532,15 @@ void CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) { displayId = mDisplayId; float minX, minY, maxX, maxY; if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { - if(xCursorPosition==minX||xCursorPosition==maxX||yCursorPosition==minY||yCursorPosition==maxY){ + float originalY = yCursorPosition; // remember the original y position + if(xCursorPosition==minX){ displayId=getPolicy()->notifyDisplayIdChanged(); mDisplayId=displayId; + mPointerController->setPosition(maxX, originalY); + } else if(xCursorPosition==maxX){ + displayId=getPolicy()->notifyDisplayIdChanged(); + mDisplayId=displayId; + mPointerController->setPosition(minX, originalY); } } }else{ From 7963c63fd2f3da05df41d0628f4eb65f54b37a87 Mon Sep 17 00:00:00 2001 From: Jon West Date: Fri, 20 Dec 2024 11:43:55 -0500 Subject: [PATCH 6/9] multi-display: inputflinger: use a persist prop for mouse presentation --- services/inputflinger/reader/mapper/CursorInputMapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index 0ac6dfe2d210..68c1862d5039 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -527,7 +527,7 @@ void CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) { pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); char mMousePresentation[PROPERTY_VALUE_MAX] = {0}; - property_get("sys.mouse.presentation", mMousePresentation, "0"); + property_get("persist.mouse.presentation", mMousePresentation, "0"); if (strcmp(mMousePresentation, "1") == 0) { displayId = mDisplayId; float minX, minY, maxX, maxY; From e04807c8709c2d831da211592998657d7b8f24dc Mon Sep 17 00:00:00 2001 From: Jon West Date: Tue, 12 Nov 2024 17:07:44 -0500 Subject: [PATCH 7/9] [WIP] make cursor display configurable (v2) --- services/inputflinger/reader/InputReader.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index f552aea1b8f6..6a8c52be20ca 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -31,7 +31,7 @@ #include #include #include - +#include #include "InputDevice.h" using android::base::StringPrintf; @@ -458,6 +458,11 @@ void InputReader::updatePointerDisplayLocked() { std::optional viewport = mConfig.getDisplayViewportById(mConfig.defaultPointerDisplayId); + + int32_t mOverrideDisplayId = property_get_int32("sys.override.cursor_display_id", -1); + if (mOverrideDisplayId != -1) { + viewport = mConfig.getDisplayViewportById(mOverrideDisplayId); + } if (!viewport) { ALOGW("Can't find the designated viewport with ID %" PRId32 " to update cursor input " "mapper. Fall back to default display", From c7ef86612e0e5dc0627412ecf63e4539e25428f2 Mon Sep 17 00:00:00 2001 From: Jon West Date: Fri, 20 Dec 2024 11:47:01 -0500 Subject: [PATCH 8/9] multi-display: inputflinger: use a persist prop for cursor display override --- services/inputflinger/reader/InputReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 6a8c52be20ca..aa24e1cfe6b9 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -459,7 +459,7 @@ void InputReader::updatePointerDisplayLocked() { std::optional viewport = mConfig.getDisplayViewportById(mConfig.defaultPointerDisplayId); - int32_t mOverrideDisplayId = property_get_int32("sys.override.cursor_display_id", -1); + int32_t mOverrideDisplayId = property_get_int32("persist.override.cursor_display_id", -1); if (mOverrideDisplayId != -1) { viewport = mConfig.getDisplayViewportById(mOverrideDisplayId); } From 9a5c4f587669a653be415873d6e40bb4af029b2d Mon Sep 17 00:00:00 2001 From: Jon West Date: Thu, 6 Mar 2025 17:07:40 -0500 Subject: [PATCH 9/9] multi-display: inputflinger: Allow mouse presentation on touchpad with gesture Bring over changes from CursorInputMapper for mouse presentation so that we can also use it with the touchpad. Requires using 2-finger swipe gesture to switch to the next display once the pointer reaches the edge of the display. --- .../reader/mapper/TouchInputMapper.cpp | 26 ++++++++++++++++++- .../reader/mapper/TouchInputMapper.h | 2 ++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index c9a4d31035f7..412d9fc75ddd 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -25,6 +25,7 @@ #include "CursorScrollAccumulator.h" #include "TouchButtonAccumulator.h" #include "TouchCursorInputMapperCommon.h" +#include namespace android { @@ -1442,6 +1443,7 @@ void TouchInputMapper::reset(nsecs_t when) { mHavePointerIds = false; mCurrentMotionAborted = false; mDownTime = 0; + mDisplayId = 0; mCurrentVirtualKey.down = false; @@ -2638,7 +2640,29 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); - const int32_t displayId = mPointerController->getDisplayId(); + int32_t displayId = ADISPLAY_ID_NONE; + + char mMousePresentation[PROPERTY_VALUE_MAX] = {0}; + property_get("persist.mouse.presentation", mMousePresentation, "0"); + if (strcmp(mMousePresentation, "1") == 0) { + displayId = mDisplayId; + float minX, minY, maxX, maxY; + if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { + float originalY = y; // remember the original y position + if(x==minX){ + displayId=getPolicy()->notifyDisplayIdChanged(); + mDisplayId=displayId; + mPointerController->setPosition(maxX, originalY); + } else if(x==maxX){ + displayId=getPolicy()->notifyDisplayIdChanged(); + mDisplayId=displayId; + mPointerController->setPosition(minX, originalY); + } + } + }else{ + displayId = mPointerController->getDisplayId(); + } + NotifyMotionArgs args(getContext()->getNextId(), when, readTime, getDeviceId(), mSource, displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, flags, metaState, buttonState, MotionClassification::NONE, diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index f8af368a65ca..c928c244ceff 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -448,6 +448,8 @@ class TouchInputMapper : public InputMapper { // requested orientation, so it will depend on whether the device is orientation aware. int32_t mSurfaceOrientation; + int32_t mDisplayId; + // Translation and scaling factors, orientation-independent. float mXTranslate; float mXScale;