Loading services/inputflinger/PointerChoreographer.cpp +57 −11 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ bool isFromMouse(const NotifyMotionArgs& args) { args.pointerProperties[0].toolType == ToolType::MOUSE; } bool isFromTouchpad(const NotifyMotionArgs& args) { return isFromSource(args.source, AINPUT_SOURCE_MOUSE) && args.pointerProperties[0].toolType == ToolType::FINGER; } bool isHoverAction(int32_t action) { return action == AMOTION_EVENT_ACTION_HOVER_ENTER || action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT; Loading Loading @@ -83,6 +88,8 @@ NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& arg if (isFromMouse(args)) { return processMouseEventLocked(args); } else if (isFromTouchpad(args)) { return processTouchpadEventLocked(args); } else if (mStylusPointerIconEnabled && isStylusHoverEvent(args)) { processStylusHoverEventLocked(args); } else if (isFromSource(args.source, AINPUT_SOURCE_TOUCHSCREEN)) { Loading @@ -97,30 +104,54 @@ NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotio << args.dump(); } const int32_t displayId = getTargetMouseDisplayLocked(args.displayId); auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId); // Get the mouse pointer controller for the display, or create one if it doesn't exist. auto [it, emplaced] = mMousePointersByDisplay.try_emplace(displayId, getMouseControllerConstructor(displayId)); if (emplaced) { notifyPointerDisplayIdChangedLocked(); const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); pc.move(deltaX, deltaY); pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); const auto [x, y] = pc.getPosition(); NotifyMotionArgs newArgs(args); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); newArgs.xCursorPosition = x; newArgs.yCursorPosition = y; newArgs.displayId = displayId; return newArgs; } PointerControllerInterface& pc = *it->second; NotifyMotionArgs PointerChoreographer::processTouchpadEventLocked(const NotifyMotionArgs& args) { auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId); NotifyMotionArgs newArgs(args); newArgs.displayId = displayId; if (args.getPointerCount() == 1 && args.classification == MotionClassification::NONE) { // This is a movement of the mouse pointer. const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); pc.move(deltaX, deltaY); pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); const auto [x, y] = pc.getPosition(); NotifyMotionArgs newArgs(args); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); newArgs.xCursorPosition = x; newArgs.yCursorPosition = y; newArgs.displayId = displayId; } else { // This is a trackpad gesture with fake finger(s) that should not move the mouse pointer. pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); const auto [x, y] = pc.getPosition(); for (uint32_t i = 0; i < newArgs.getPointerCount(); i++) { newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, args.pointerCoords[i].getX() + x); newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, args.pointerCoords[i].getY() + y); } newArgs.xCursorPosition = x; newArgs.yCursorPosition = y; } return newArgs; } Loading Loading @@ -270,6 +301,21 @@ int32_t PointerChoreographer::getTargetMouseDisplayLocked(int32_t associatedDisp return associatedDisplayId == ADISPLAY_ID_NONE ? mDefaultMouseDisplayId : associatedDisplayId; } std::pair<int32_t, PointerControllerInterface&> PointerChoreographer::getDisplayIdAndMouseControllerLocked(int32_t associatedDisplayId) { const int32_t displayId = getTargetMouseDisplayLocked(associatedDisplayId); // Get the mouse pointer controller for the display, or create one if it doesn't exist. auto [it, emplaced] = mMousePointersByDisplay.try_emplace(displayId, getMouseControllerConstructor(displayId)); if (emplaced) { notifyPointerDisplayIdChangedLocked(); } return {displayId, *it->second}; } InputDeviceInfo* PointerChoreographer::findInputDeviceLocked(DeviceId deviceId) { auto it = std::find_if(mInputDeviceInfos.begin(), mInputDeviceInfos.end(), [deviceId](const auto& info) { return info.getId() == deviceId; }); Loading services/inputflinger/PointerChoreographer.h +3 −0 Original line number Diff line number Diff line Loading @@ -95,10 +95,13 @@ private: void notifyPointerDisplayIdChangedLocked() REQUIRES(mLock); const DisplayViewport* findViewportByIdLocked(int32_t displayId) const REQUIRES(mLock); int32_t getTargetMouseDisplayLocked(int32_t associatedDisplayId) const REQUIRES(mLock); std::pair<int32_t, PointerControllerInterface&> getDisplayIdAndMouseControllerLocked( int32_t associatedDisplayId) REQUIRES(mLock); InputDeviceInfo* findInputDeviceLocked(DeviceId deviceId) REQUIRES(mLock); NotifyMotionArgs processMotion(const NotifyMotionArgs& args); NotifyMotionArgs processMouseEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); NotifyMotionArgs processTouchpadEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); void processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); void processStylusHoverEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); void processDeviceReset(const NotifyDeviceResetArgs& args); Loading services/inputflinger/reader/mapper/CursorInputMapper.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -527,10 +527,8 @@ void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfigurat if (mEnablePointerChoreographer) { // Always use DISPLAY_ID_NONE for mouse events. // PointerChoreographer will make it target the correct the displayId later. const auto pointerViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay(); mDisplayId = pointerViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt; resolvedViewport = pointerViewport; resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay(); mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt; } else { mDisplayId = mPointerController->getDisplayId(); if (auto v = config.getDisplayViewportById(*mDisplayId); v) { Loading services/inputflinger/reader/mapper/TouchpadInputMapper.cpp +44 −18 Original line number Diff line number Diff line Loading @@ -246,7 +246,8 @@ TouchpadInputMapper::TouchpadInputMapper(InputDeviceContext& deviceContext, mStateConverter(deviceContext, mMotionAccumulator), mGestureConverter(*getContext(), deviceContext, getDeviceId()), mCapturedEventConverter(*getContext(), deviceContext, mMotionAccumulator, getDeviceId()), mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())) { mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())), mEnablePointerChoreographer(input_flags::enable_pointer_choreographer()) { RawAbsoluteAxisInfo slotAxisInfo; deviceContext.getAbsoluteAxisInfo(ABS_MT_SLOT, &slotAxisInfo); if (!slotAxisInfo.valid || slotAxisInfo.maxValue <= 0) { Loading Loading @@ -331,31 +332,56 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when, if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) { mDisplayId = ADISPLAY_ID_NONE; if (auto viewport = mDeviceContext.getAssociatedViewport(); viewport) { std::optional<DisplayViewport> resolvedViewport; std::optional<FloatRect> boundsInLogicalDisplay; if (auto assocViewport = mDeviceContext.getAssociatedViewport(); assocViewport) { // This InputDevice is associated with a viewport. // Only generate events for the associated display. mDisplayId = assocViewport->displayId; resolvedViewport = *assocViewport; if (!mEnablePointerChoreographer) { const bool mismatchedPointerDisplay = (viewport->displayId != mPointerController->getDisplayId()); (assocViewport->displayId != mPointerController->getDisplayId()); if (mismatchedPointerDisplay) { ALOGW("Touchpad \"%s\" associated viewport display does not match pointer " "controller", mDeviceContext.getName().c_str()); mDisplayId.reset(); } } mDisplayId = mismatchedPointerDisplay ? std::nullopt : std::make_optional(viewport->displayId); } else { // The InputDevice is not associated with a viewport, but it controls the mouse pointer. if (mEnablePointerChoreographer) { // Always use DISPLAY_ID_NONE for touchpad events. // PointerChoreographer will make it target the correct the displayId later. resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay(); mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt; } else { mDisplayId = mPointerController->getDisplayId(); if (auto v = config.getDisplayViewportById(*mDisplayId); v) { resolvedViewport = *v; } ui::Rotation orientation = ui::ROTATION_0; if (mDisplayId.has_value()) { if (auto viewport = config.getDisplayViewportById(*mDisplayId); viewport) { orientation = getInverseRotation(viewport->orientation); if (auto bounds = mPointerController->getBounds(); bounds) { boundsInLogicalDisplay = *bounds; } } } mGestureConverter.setDisplayId(mDisplayId); mGestureConverter.setOrientation(orientation); mGestureConverter.setOrientation(resolvedViewport ? getInverseRotation(resolvedViewport->orientation) : ui::ROTATION_0); if (!boundsInLogicalDisplay) { boundsInLogicalDisplay = resolvedViewport ? FloatRect{static_cast<float>(resolvedViewport->logicalLeft), static_cast<float>(resolvedViewport->logicalTop), static_cast<float>(resolvedViewport->logicalRight - 1), static_cast<float>(resolvedViewport->logicalBottom - 1)} : FloatRect{0, 0, 0, 0}; } mGestureConverter.setBoundsInLogicalDisplay(*boundsInLogicalDisplay); } if (!changes.any() || changes.test(InputReaderConfiguration::Change::TOUCHPAD_SETTINGS)) { mPropertyProvider.getProperty("Use Custom Touchpad Pointer Accel Curve") Loading services/inputflinger/reader/mapper/TouchpadInputMapper.h +2 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ private: // Tracking IDs for touches that have at some point been reported as palms by the touchpad. std::set<int32_t> mPalmTrackingIds; const bool mEnablePointerChoreographer; // The display that events generated by this mapper should target. This can be set to // ADISPLAY_ID_NONE to target the focused display. If there is no display target (i.e. // std::nullopt), all events will be ignored. Loading Loading
services/inputflinger/PointerChoreographer.cpp +57 −11 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ bool isFromMouse(const NotifyMotionArgs& args) { args.pointerProperties[0].toolType == ToolType::MOUSE; } bool isFromTouchpad(const NotifyMotionArgs& args) { return isFromSource(args.source, AINPUT_SOURCE_MOUSE) && args.pointerProperties[0].toolType == ToolType::FINGER; } bool isHoverAction(int32_t action) { return action == AMOTION_EVENT_ACTION_HOVER_ENTER || action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT; Loading Loading @@ -83,6 +88,8 @@ NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& arg if (isFromMouse(args)) { return processMouseEventLocked(args); } else if (isFromTouchpad(args)) { return processTouchpadEventLocked(args); } else if (mStylusPointerIconEnabled && isStylusHoverEvent(args)) { processStylusHoverEventLocked(args); } else if (isFromSource(args.source, AINPUT_SOURCE_TOUCHSCREEN)) { Loading @@ -97,30 +104,54 @@ NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotio << args.dump(); } const int32_t displayId = getTargetMouseDisplayLocked(args.displayId); auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId); // Get the mouse pointer controller for the display, or create one if it doesn't exist. auto [it, emplaced] = mMousePointersByDisplay.try_emplace(displayId, getMouseControllerConstructor(displayId)); if (emplaced) { notifyPointerDisplayIdChangedLocked(); const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); pc.move(deltaX, deltaY); pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); const auto [x, y] = pc.getPosition(); NotifyMotionArgs newArgs(args); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); newArgs.xCursorPosition = x; newArgs.yCursorPosition = y; newArgs.displayId = displayId; return newArgs; } PointerControllerInterface& pc = *it->second; NotifyMotionArgs PointerChoreographer::processTouchpadEventLocked(const NotifyMotionArgs& args) { auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId); NotifyMotionArgs newArgs(args); newArgs.displayId = displayId; if (args.getPointerCount() == 1 && args.classification == MotionClassification::NONE) { // This is a movement of the mouse pointer. const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); pc.move(deltaX, deltaY); pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); const auto [x, y] = pc.getPosition(); NotifyMotionArgs newArgs(args); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); newArgs.xCursorPosition = x; newArgs.yCursorPosition = y; newArgs.displayId = displayId; } else { // This is a trackpad gesture with fake finger(s) that should not move the mouse pointer. pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); const auto [x, y] = pc.getPosition(); for (uint32_t i = 0; i < newArgs.getPointerCount(); i++) { newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, args.pointerCoords[i].getX() + x); newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, args.pointerCoords[i].getY() + y); } newArgs.xCursorPosition = x; newArgs.yCursorPosition = y; } return newArgs; } Loading Loading @@ -270,6 +301,21 @@ int32_t PointerChoreographer::getTargetMouseDisplayLocked(int32_t associatedDisp return associatedDisplayId == ADISPLAY_ID_NONE ? mDefaultMouseDisplayId : associatedDisplayId; } std::pair<int32_t, PointerControllerInterface&> PointerChoreographer::getDisplayIdAndMouseControllerLocked(int32_t associatedDisplayId) { const int32_t displayId = getTargetMouseDisplayLocked(associatedDisplayId); // Get the mouse pointer controller for the display, or create one if it doesn't exist. auto [it, emplaced] = mMousePointersByDisplay.try_emplace(displayId, getMouseControllerConstructor(displayId)); if (emplaced) { notifyPointerDisplayIdChangedLocked(); } return {displayId, *it->second}; } InputDeviceInfo* PointerChoreographer::findInputDeviceLocked(DeviceId deviceId) { auto it = std::find_if(mInputDeviceInfos.begin(), mInputDeviceInfos.end(), [deviceId](const auto& info) { return info.getId() == deviceId; }); Loading
services/inputflinger/PointerChoreographer.h +3 −0 Original line number Diff line number Diff line Loading @@ -95,10 +95,13 @@ private: void notifyPointerDisplayIdChangedLocked() REQUIRES(mLock); const DisplayViewport* findViewportByIdLocked(int32_t displayId) const REQUIRES(mLock); int32_t getTargetMouseDisplayLocked(int32_t associatedDisplayId) const REQUIRES(mLock); std::pair<int32_t, PointerControllerInterface&> getDisplayIdAndMouseControllerLocked( int32_t associatedDisplayId) REQUIRES(mLock); InputDeviceInfo* findInputDeviceLocked(DeviceId deviceId) REQUIRES(mLock); NotifyMotionArgs processMotion(const NotifyMotionArgs& args); NotifyMotionArgs processMouseEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); NotifyMotionArgs processTouchpadEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); void processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); void processStylusHoverEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock); void processDeviceReset(const NotifyDeviceResetArgs& args); Loading
services/inputflinger/reader/mapper/CursorInputMapper.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -527,10 +527,8 @@ void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfigurat if (mEnablePointerChoreographer) { // Always use DISPLAY_ID_NONE for mouse events. // PointerChoreographer will make it target the correct the displayId later. const auto pointerViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay(); mDisplayId = pointerViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt; resolvedViewport = pointerViewport; resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay(); mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt; } else { mDisplayId = mPointerController->getDisplayId(); if (auto v = config.getDisplayViewportById(*mDisplayId); v) { Loading
services/inputflinger/reader/mapper/TouchpadInputMapper.cpp +44 −18 Original line number Diff line number Diff line Loading @@ -246,7 +246,8 @@ TouchpadInputMapper::TouchpadInputMapper(InputDeviceContext& deviceContext, mStateConverter(deviceContext, mMotionAccumulator), mGestureConverter(*getContext(), deviceContext, getDeviceId()), mCapturedEventConverter(*getContext(), deviceContext, mMotionAccumulator, getDeviceId()), mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())) { mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())), mEnablePointerChoreographer(input_flags::enable_pointer_choreographer()) { RawAbsoluteAxisInfo slotAxisInfo; deviceContext.getAbsoluteAxisInfo(ABS_MT_SLOT, &slotAxisInfo); if (!slotAxisInfo.valid || slotAxisInfo.maxValue <= 0) { Loading Loading @@ -331,31 +332,56 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when, if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) { mDisplayId = ADISPLAY_ID_NONE; if (auto viewport = mDeviceContext.getAssociatedViewport(); viewport) { std::optional<DisplayViewport> resolvedViewport; std::optional<FloatRect> boundsInLogicalDisplay; if (auto assocViewport = mDeviceContext.getAssociatedViewport(); assocViewport) { // This InputDevice is associated with a viewport. // Only generate events for the associated display. mDisplayId = assocViewport->displayId; resolvedViewport = *assocViewport; if (!mEnablePointerChoreographer) { const bool mismatchedPointerDisplay = (viewport->displayId != mPointerController->getDisplayId()); (assocViewport->displayId != mPointerController->getDisplayId()); if (mismatchedPointerDisplay) { ALOGW("Touchpad \"%s\" associated viewport display does not match pointer " "controller", mDeviceContext.getName().c_str()); mDisplayId.reset(); } } mDisplayId = mismatchedPointerDisplay ? std::nullopt : std::make_optional(viewport->displayId); } else { // The InputDevice is not associated with a viewport, but it controls the mouse pointer. if (mEnablePointerChoreographer) { // Always use DISPLAY_ID_NONE for touchpad events. // PointerChoreographer will make it target the correct the displayId later. resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay(); mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt; } else { mDisplayId = mPointerController->getDisplayId(); if (auto v = config.getDisplayViewportById(*mDisplayId); v) { resolvedViewport = *v; } ui::Rotation orientation = ui::ROTATION_0; if (mDisplayId.has_value()) { if (auto viewport = config.getDisplayViewportById(*mDisplayId); viewport) { orientation = getInverseRotation(viewport->orientation); if (auto bounds = mPointerController->getBounds(); bounds) { boundsInLogicalDisplay = *bounds; } } } mGestureConverter.setDisplayId(mDisplayId); mGestureConverter.setOrientation(orientation); mGestureConverter.setOrientation(resolvedViewport ? getInverseRotation(resolvedViewport->orientation) : ui::ROTATION_0); if (!boundsInLogicalDisplay) { boundsInLogicalDisplay = resolvedViewport ? FloatRect{static_cast<float>(resolvedViewport->logicalLeft), static_cast<float>(resolvedViewport->logicalTop), static_cast<float>(resolvedViewport->logicalRight - 1), static_cast<float>(resolvedViewport->logicalBottom - 1)} : FloatRect{0, 0, 0, 0}; } mGestureConverter.setBoundsInLogicalDisplay(*boundsInLogicalDisplay); } if (!changes.any() || changes.test(InputReaderConfiguration::Change::TOUCHPAD_SETTINGS)) { mPropertyProvider.getProperty("Use Custom Touchpad Pointer Accel Curve") Loading
services/inputflinger/reader/mapper/TouchpadInputMapper.h +2 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ private: // Tracking IDs for touches that have at some point been reported as palms by the touchpad. std::set<int32_t> mPalmTrackingIds; const bool mEnablePointerChoreographer; // The display that events generated by this mapper should target. This can be set to // ADISPLAY_ID_NONE to target the focused display. If there is no display target (i.e. // std::nullopt), all events will be ignored. Loading