diff options
| author | 2021-11-04 16:51:29 -0700 | |
|---|---|---|
| committer | 2021-11-17 02:14:06 -0800 | |
| commit | 6b430413d07b6afca1a4146ea91809567b5cfe9a (patch) | |
| tree | ceb69c9d88200e64d7779decdb8e640690da4937 | |
| parent | 3bb6799ff0b68f818eb4a01d2a6b07fe9575edf0 (diff) | |
Change PointerController to display space
PointerController used to work in the logical display space, so
TouchInputMapper and CursorInputMapper would need to transform the
coordinates before interacting with it.
This CL makes PointerController work in the display space. It will
transform incoming and outgoing coordinates to stay in the display
space using the DisplayInfo provided by SurfaceFlinger. Using info
provided by SF also means that there will be better synchonization
between the pointers and display changes like rotation.
Bug: 188939842
Bug: 144544464
Test: manual: ensure mouse and touch spots work in different display
orientations and sizes set using "adb shell wm size"
Change-Id: I764c070adef7e9f26c0062f1b3466c7115a305ac
| -rw-r--r-- | include/input/Input.h | 5 | ||||
| -rw-r--r-- | libs/input/Input.cpp | 12 | ||||
| -rw-r--r-- | services/inputflinger/include/PointerControllerInterface.h | 3 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/CursorInputMapper.cpp | 17 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/CursorInputMapper.h | 2 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h | 20 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.cpp | 110 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.h | 8 |
8 files changed, 47 insertions, 130 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index 1e06257591..5242dcb476 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -201,6 +201,11 @@ namespace android { class Parcel; #endif +/* + * Apply the given transform to the point without applying any translation/offset. + */ +vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy); + const char* inputEventTypeToString(int32_t type); std::string inputEventSourceToString(int32_t source); diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 8974b22c86..cb93c92310 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -60,12 +60,6 @@ float transformAngle(const ui::Transform& transform, float angleRadians) { return atan2f(transformedPoint.x, -transformedPoint.y); } -vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) { - const vec2 transformedXy = transform.transform(xy); - const vec2 transformedOrigin = transform.transform(0, 0); - return transformedXy - transformedOrigin; -} - bool shouldDisregardTransformation(uint32_t source) { // Do not apply any transformations to axes from joysticks or touchpads. return isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK) || @@ -120,6 +114,12 @@ int32_t IdGenerator::nextId() const { // --- InputEvent --- +vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) { + const vec2 transformedXy = transform.transform(xy); + const vec2 transformedOrigin = transform.transform(0, 0); + return transformedXy - transformedOrigin; +} + const char* inputEventTypeToString(int32_t type) { switch (type) { case AINPUT_EVENT_TYPE_KEY: { diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h index b1069497d3..db4228d862 100644 --- a/services/inputflinger/include/PointerControllerInterface.h +++ b/services/inputflinger/include/PointerControllerInterface.h @@ -30,7 +30,8 @@ namespace android { * fingers * * The pointer controller is responsible for providing synchronization and for tracking - * display orientation changes if needed. + * display orientation changes if needed. It works in the display panel's coordinate space, which + * is the same coordinate space used by InputReader. */ class PointerControllerInterface { protected: diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index 15ba45945a..fcb56ef05c 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -188,8 +188,6 @@ void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { mOrientation = DISPLAY_ORIENTATION_0; - mDisplayWidth = 0; - mDisplayHeight = 0; const bool isOrientedDevice = (mParameters.orientationAware && mParameters.hasAssociatedDisplay); @@ -203,8 +201,6 @@ void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config->getDisplayViewportByType(ViewportType::INTERNAL); if (internalViewport) { mOrientation = getInverseRotation(internalViewport->orientation); - mDisplayWidth = internalViewport->deviceWidth; - mDisplayHeight = internalViewport->deviceHeight; } } @@ -335,14 +331,7 @@ void CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) { mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER); if (moved) { - float dx = deltaX; - float dy = deltaY; - // Rotate the delta from InputReader's un-rotated coordinate space to - // PointerController's rotated coordinate space that is oriented with the - // viewport. - rotateDelta(getInverseRotation(mOrientation), &dx, &dy); - - mPointerController->move(dx, dy); + mPointerController->move(deltaX, deltaY); } if (buttonsChanged) { @@ -353,10 +342,6 @@ void CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) { } mPointerController->getPosition(&xCursorPosition, &yCursorPosition); - // Rotate the cursor position that is in PointerController's rotated coordinate space - // to InputReader's un-rotated coordinate space. - rotatePoint(mOrientation, xCursorPosition /*byRef*/, yCursorPosition /*byRef*/, - mDisplayWidth, mDisplayHeight); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition); pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h index 88e947f7d5..9a8ca01294 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.h +++ b/services/inputflinger/reader/mapper/CursorInputMapper.h @@ -105,8 +105,6 @@ private: VelocityControl mWheelYVelocityControl; int32_t mOrientation; - int32_t mDisplayWidth; - int32_t mDisplayHeight; std::shared_ptr<PointerControllerInterface> mPointerController; diff --git a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h index 8c30e38908..31a3d2e172 100644 --- a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h +++ b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h @@ -64,26 +64,6 @@ static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) { } } -// Rotates the given point (x, y) by the supplied orientation. The width and height are the -// dimensions of the surface prior to this rotation being applied. -static void rotatePoint(int32_t orientation, float& x, float& y, int32_t width, int32_t height) { - rotateDelta(orientation, &x, &y); - switch (orientation) { - case DISPLAY_ORIENTATION_90: - y += width; - break; - case DISPLAY_ORIENTATION_180: - x += width; - y += height; - break; - case DISPLAY_ORIENTATION_270: - x += height; - break; - default: - break; - } -} - // Returns true if the pointer should be reported as being down given the specified // button states. This determines whether the event is reported as a touch event. static bool isPointerDown(int32_t buttonState) { diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index 3fe6fd130f..913c666a4a 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -1668,9 +1668,10 @@ void TouchInputMapper::updateTouchSpots() { mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); mPointerController->setButtonState(mCurrentRawState.buttonState); - setTouchSpots(mCurrentCookedState.cookedPointerData.pointerCoords, - mCurrentCookedState.cookedPointerData.idToIndex, - mCurrentCookedState.cookedPointerData.touchingIdBits, mViewport.displayId); + mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords, + mCurrentCookedState.cookedPointerData.idToIndex, + mCurrentCookedState.cookedPointerData.touchingIdBits, + mViewport.displayId); } bool TouchInputMapper::isTouchScreen() { @@ -2410,9 +2411,10 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u } if (mPointerGesture.currentGestureMode == PointerGesture::Mode::FREEFORM) { - setTouchSpots(mPointerGesture.currentGestureCoords, - mPointerGesture.currentGestureIdToIndex, - mPointerGesture.currentGestureIdBits, mPointerController->getDisplayId()); + mPointerController->setSpots(mPointerGesture.currentGestureCoords, + mPointerGesture.currentGestureIdToIndex, + mPointerGesture.currentGestureIdBits, + mPointerController->getDisplayId()); } } else { mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER); @@ -2562,7 +2564,8 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, nsecs_t readTime, u // the pointer is hovering again even if the user is not currently touching // the touch pad. This ensures that a view will receive a fresh hover enter // event after a tap. - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); PointerProperties pointerProperties; pointerProperties.clear(); @@ -2819,12 +2822,13 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi // Move the pointer using a relative motion. // When using spots, the click will occur at the position of the anchor // spot and all other spots will move there. - moveMouseCursor(deltaX, deltaY); + mPointerController->move(deltaX, deltaY); } else { mPointerVelocityControl.reset(); } - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); mPointerGesture.currentGestureMode = PointerGesture::Mode::BUTTON_CLICK_OR_DRAG; mPointerGesture.currentGestureIdBits.clear(); @@ -2850,7 +2854,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi mPointerGesture.lastGestureMode == PointerGesture::Mode::TAP_DRAG) && lastFingerCount == 1) { if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) { - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { #if DEBUG_GESTURES @@ -2918,7 +2923,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi mPointerGesture.currentGestureMode = PointerGesture::Mode::HOVER; if (mPointerGesture.lastGestureMode == PointerGesture::Mode::TAP) { if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { mPointerGesture.currentGestureMode = PointerGesture::Mode::TAP_DRAG; @@ -2952,7 +2958,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi // Move the pointer using a relative motion. // When using spots, the hover or drag will occur at the position of the anchor spot. - moveMouseCursor(deltaX, deltaY); + mPointerController->move(deltaX, deltaY); } else { mPointerVelocityControl.reset(); } @@ -2974,7 +2980,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi down = false; } - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); mPointerGesture.currentGestureIdBits.clear(); mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId); @@ -3047,9 +3054,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, bool* outCancelPrevi mCurrentRawState.rawPointerData .getCentroidOfTouchingPointers(&mPointerGesture.referenceTouchX, &mPointerGesture.referenceTouchY); - auto [x, y] = getMouseCursorPosition(); - mPointerGesture.referenceGestureX = x; - mPointerGesture.referenceGestureY = y; + mPointerController->getPosition(&mPointerGesture.referenceGestureX, + &mPointerGesture.referenceGestureY); } // Clear the reference deltas for fingers not yet included in the reference calculation. @@ -3387,13 +3393,15 @@ void TouchInputMapper::dispatchPointerStylus(nsecs_t when, nsecs_t readTime, uin if (!mCurrentCookedState.stylusIdBits.isEmpty()) { uint32_t id = mCurrentCookedState.stylusIdBits.firstMarkedBit(); uint32_t index = mCurrentCookedState.cookedPointerData.idToIndex[id]; - setMouseCursorPosition(mCurrentCookedState.cookedPointerData.pointerCoords[index].getX(), - mCurrentCookedState.cookedPointerData.pointerCoords[index].getY()); + mPointerController + ->setPosition(mCurrentCookedState.cookedPointerData.pointerCoords[index].getX(), + mCurrentCookedState.cookedPointerData.pointerCoords[index].getY()); hovering = mCurrentCookedState.cookedPointerData.hoveringIdBits.hasBit(id); down = !hovering; - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); mPointerSimple.currentCoords.copyFrom( mCurrentCookedState.cookedPointerData.pointerCoords[index]); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); @@ -3434,7 +3442,7 @@ void TouchInputMapper::dispatchPointerMouse(nsecs_t when, nsecs_t readTime, uint rotateDelta(mInputDeviceOrientation, &deltaX, &deltaY); mPointerVelocityControl.move(when, &deltaX, &deltaY); - moveMouseCursor(deltaX, deltaY); + mPointerController->move(deltaX, deltaY); } else { mPointerVelocityControl.reset(); } @@ -3442,7 +3450,8 @@ void TouchInputMapper::dispatchPointerMouse(nsecs_t when, nsecs_t readTime, uint down = isPointerDown(mCurrentRawState.buttonState); hovering = !down; - auto [x, y] = getMouseCursorPosition(); + float x, y; + mPointerController->getPosition(&x, &y); mPointerSimple.currentCoords.copyFrom( mCurrentCookedState.cookedPointerData.pointerCoords[currentIndex]); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); @@ -3482,7 +3491,8 @@ void TouchInputMapper::dispatchPointerSimple(nsecs_t when, nsecs_t readTime, uin } int32_t displayId = mPointerController->getDisplayId(); - auto [xCursorPosition, yCursorPosition] = getMouseCursorPosition(); + float xCursorPosition, yCursorPosition; + mPointerController->getPosition(&xCursorPosition, &yCursorPosition); if (mPointerSimple.down && !down) { mPointerSimple.down = false; @@ -3648,9 +3658,7 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t p float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION; float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION; if (mDeviceMode == DeviceMode::POINTER) { - auto [x, y] = getMouseCursorPosition(); - xCursorPosition = x; - yCursorPosition = y; + mPointerController->getPosition(&xCursorPosition, &yCursorPosition); } const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE); const int32_t deviceId = getDeviceId(); @@ -3999,56 +4007,4 @@ std::optional<int32_t> TouchInputMapper::getAssociatedDisplayId() { return std::nullopt; } -void TouchInputMapper::moveMouseCursor(float dx, float dy) const { - // Convert from InputReader's un-rotated coordinate space to PointerController's coordinate - // space that is oriented with the viewport. - rotateDelta(mViewport.orientation, &dx, &dy); - - mPointerController->move(dx, dy); -} - -std::pair<float, float> TouchInputMapper::getMouseCursorPosition() const { - float x = 0; - float y = 0; - mPointerController->getPosition(&x, &y); - - if (!mViewport.isValid()) return {x, y}; - - // Convert from PointerController's rotated coordinate space that is oriented with the viewport - // to InputReader's un-rotated coordinate space. - const int32_t orientation = getInverseRotation(mViewport.orientation); - rotatePoint(orientation, x, y, mViewport.deviceWidth, mViewport.deviceHeight); - return {x, y}; -} - -void TouchInputMapper::setMouseCursorPosition(float x, float y) const { - // Convert from InputReader's un-rotated coordinate space to PointerController's rotated - // coordinate space that is oriented with the viewport. - rotatePoint(mViewport.orientation, x, y, mDisplayWidth, mDisplayHeight); - - mPointerController->setPosition(x, y); -} - -void TouchInputMapper::setTouchSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, - BitSet32 spotIdBits, int32_t displayId) { - std::array<PointerCoords, MAX_POINTERS> outSpotCoords{}; - - for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) { - const uint32_t index = spotIdToIndex[idBits.clearFirstMarkedBit()]; - float x = spotCoords[index].getX(); - float y = spotCoords[index].getY(); - float pressure = spotCoords[index].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE); - - // Convert from InputReader's un-rotated coordinate space to PointerController's rotated - // coordinate space. - rotatePoint(mViewport.orientation, x, y, mDisplayWidth, mDisplayHeight); - - outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_X, x); - outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_Y, y); - outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure); - } - - mPointerController->setSpots(outSpotCoords.data(), spotIdToIndex, spotIdBits, displayId); -} - } // namespace android diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index 496491b62d..9b020a609a 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -803,14 +803,6 @@ private: const char* modeToString(DeviceMode deviceMode); void rotateAndScale(float& x, float& y) const; - - // Wrapper methods for interfacing with PointerController. These are used to convert points - // between the coordinate spaces used by InputReader and PointerController, if they differ. - void moveMouseCursor(float dx, float dy) const; - std::pair<float, float> getMouseCursorPosition() const; - void setMouseCursorPosition(float x, float y) const; - void setTouchSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, - BitSet32 spotIdBits, int32_t displayId); }; } // namespace android |