xref: /aosp_15_r20/frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // clang-format off
18 #include "../Macros.h"
19 // clang-format on
20 
21 #include "CursorInputMapper.h"
22 
23 #include <optional>
24 
25 #include <com_android_input_flags.h>
26 #include <ftl/enum.h>
27 #include <input/AccelerationCurve.h>
28 
29 #include "CursorButtonAccumulator.h"
30 #include "CursorScrollAccumulator.h"
31 #include "PointerControllerInterface.h"
32 #include "TouchCursorInputMapperCommon.h"
33 
34 #include "input/PrintTools.h"
35 
36 namespace android {
37 
38 // The default velocity control parameters that has no effect.
39 static const VelocityControlParameters FLAT_VELOCITY_CONTROL_PARAMS{};
40 
41 // --- CursorMotionAccumulator ---
42 
CursorMotionAccumulator()43 CursorMotionAccumulator::CursorMotionAccumulator() {
44     clearRelativeAxes();
45 }
46 
reset(InputDeviceContext & deviceContext)47 void CursorMotionAccumulator::reset(InputDeviceContext& deviceContext) {
48     clearRelativeAxes();
49 }
50 
clearRelativeAxes()51 void CursorMotionAccumulator::clearRelativeAxes() {
52     mRelX = 0;
53     mRelY = 0;
54 }
55 
process(const RawEvent & rawEvent)56 void CursorMotionAccumulator::process(const RawEvent& rawEvent) {
57     if (rawEvent.type == EV_REL) {
58         switch (rawEvent.code) {
59             case REL_X:
60                 mRelX = rawEvent.value;
61                 break;
62             case REL_Y:
63                 mRelY = rawEvent.value;
64                 break;
65         }
66     }
67 }
68 
finishSync()69 void CursorMotionAccumulator::finishSync() {
70     clearRelativeAxes();
71 }
72 
73 // --- CursorInputMapper ---
74 
CursorInputMapper(InputDeviceContext & deviceContext,const InputReaderConfiguration & readerConfig)75 CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext,
76                                      const InputReaderConfiguration& readerConfig)
77       : InputMapper(deviceContext, readerConfig),
78         mLastEventTime(std::numeric_limits<nsecs_t>::min()) {}
79 
getSources() const80 uint32_t CursorInputMapper::getSources() const {
81     return mSource;
82 }
83 
populateDeviceInfo(InputDeviceInfo & info)84 void CursorInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
85     InputMapper::populateDeviceInfo(info);
86 
87     if (mParameters.mode == Parameters::Mode::POINTER) {
88         if (!mBoundsInLogicalDisplay.isEmpty()) {
89             info.addMotionRange(AMOTION_EVENT_AXIS_X, mSource, mBoundsInLogicalDisplay.left,
90                                 mBoundsInLogicalDisplay.right, 0.0f, 0.0f, 0.0f);
91             info.addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, mBoundsInLogicalDisplay.top,
92                                 mBoundsInLogicalDisplay.bottom, 0.0f, 0.0f, 0.0f);
93         }
94     } else {
95         info.addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
96         info.addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
97         info.addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -1.0f, 1.0f, 0.0f, mXScale,
98                             0.0f);
99         info.addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale,
100                             0.0f);
101     }
102     info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
103 
104     if (mCursorScrollAccumulator.haveRelativeVWheel()) {
105         info.addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
106     }
107     if (mCursorScrollAccumulator.haveRelativeHWheel()) {
108         info.addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
109     }
110 }
111 
dump(std::string & dump)112 void CursorInputMapper::dump(std::string& dump) {
113     dump += INDENT2 "Cursor Input Mapper:\n";
114     dumpParameters(dump);
115     dump += StringPrintf(INDENT3 "XScale: %0.3f\n", mXScale);
116     dump += StringPrintf(INDENT3 "YScale: %0.3f\n", mYScale);
117     dump += StringPrintf(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
118     dump += StringPrintf(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
119     dump += StringPrintf(INDENT3 "HaveVWheel: %s\n",
120                          toString(mCursorScrollAccumulator.haveRelativeVWheel()));
121     dump += StringPrintf(INDENT3 "HaveHWheel: %s\n",
122                          toString(mCursorScrollAccumulator.haveRelativeHWheel()));
123     dump += StringPrintf(INDENT3 "WheelYVelocityControlParameters: %s",
124                          mWheelYVelocityControl.getParameters().dump().c_str());
125     dump += StringPrintf(INDENT3 "WheelXVelocityControlParameters: %s",
126                          mWheelXVelocityControl.getParameters().dump().c_str());
127     dump += StringPrintf(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
128     dump += StringPrintf(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
129     dump += StringPrintf(INDENT3 "DisplayId: %s\n",
130                          toString(mDisplayId, streamableToString).c_str());
131     dump += StringPrintf(INDENT3 "Orientation: %s\n", ftl::enum_string(mOrientation).c_str());
132     dump += StringPrintf(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
133     dump += StringPrintf(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
134     dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
135 }
136 
reconfigure(nsecs_t when,const InputReaderConfiguration & readerConfig,ConfigurationChanges changes)137 std::list<NotifyArgs> CursorInputMapper::reconfigure(nsecs_t when,
138                                                      const InputReaderConfiguration& readerConfig,
139                                                      ConfigurationChanges changes) {
140     std::list<NotifyArgs> out = InputMapper::reconfigure(when, readerConfig, changes);
141 
142     if (!changes.any()) { // first time only
143         configureBasicParams();
144     }
145 
146     const bool configurePointerCapture = !changes.any() ||
147             (mParameters.mode != Parameters::Mode::NAVIGATION &&
148              changes.test(InputReaderConfiguration::Change::POINTER_CAPTURE));
149     if (configurePointerCapture) {
150         configureOnPointerCapture(readerConfig);
151         out.push_back(NotifyDeviceResetArgs(getContext()->getNextId(), when, getDeviceId()));
152     }
153 
154     if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO) ||
155         configurePointerCapture) {
156         configureOnChangeDisplayInfo(readerConfig);
157     }
158 
159     // Pointer speed settings depend on display settings.
160     if (!changes.any() || changes.test(InputReaderConfiguration::Change::POINTER_SPEED) ||
161         changes.test(InputReaderConfiguration::Change::DISPLAY_INFO) || configurePointerCapture) {
162         configureOnChangePointerSpeed(readerConfig);
163     }
164 
165     if (!changes.any() || changes.test(InputReaderConfiguration::Change::MOUSE_SETTINGS)) {
166         configureOnChangeMouseSettings(readerConfig);
167     }
168     return out;
169 }
170 
computeParameters(const InputDeviceContext & deviceContext)171 CursorInputMapper::Parameters CursorInputMapper::computeParameters(
172         const InputDeviceContext& deviceContext) {
173     Parameters parameters;
174     parameters.mode = Parameters::Mode::POINTER;
175     const PropertyMap& config = deviceContext.getConfiguration();
176     std::optional<std::string> cursorModeString = config.getString("cursor.mode");
177     if (cursorModeString.has_value()) {
178         if (*cursorModeString == "navigation") {
179             parameters.mode = Parameters::Mode::NAVIGATION;
180         } else if (*cursorModeString != "pointer" && *cursorModeString != "default") {
181             ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString->c_str());
182         }
183     }
184 
185     parameters.orientationAware = config.getBool("cursor.orientationAware").value_or(false);
186 
187     parameters.hasAssociatedDisplay = false;
188     if (parameters.mode == Parameters::Mode::POINTER || parameters.orientationAware) {
189         parameters.hasAssociatedDisplay = true;
190     }
191     return parameters;
192 }
193 
dumpParameters(std::string & dump)194 void CursorInputMapper::dumpParameters(std::string& dump) {
195     dump += INDENT3 "Parameters:\n";
196     dump += StringPrintf(INDENT4 "HasAssociatedDisplay: %s\n",
197                          toString(mParameters.hasAssociatedDisplay));
198     dump += StringPrintf(INDENT4 "Mode: %s\n", ftl::enum_string(mParameters.mode).c_str());
199     dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
200 }
201 
reset(nsecs_t when)202 std::list<NotifyArgs> CursorInputMapper::reset(nsecs_t when) {
203     mButtonState = 0;
204     mDownTime = 0;
205     mLastEventTime = std::numeric_limits<nsecs_t>::min();
206 
207     mPointerVelocityControl.reset();
208     mWheelXVelocityControl.reset();
209     mWheelYVelocityControl.reset();
210 
211     mCursorButtonAccumulator.reset(getDeviceContext());
212     mCursorMotionAccumulator.reset(getDeviceContext());
213     mCursorScrollAccumulator.reset(getDeviceContext());
214 
215     return InputMapper::reset(when);
216 }
217 
process(const RawEvent & rawEvent)218 std::list<NotifyArgs> CursorInputMapper::process(const RawEvent& rawEvent) {
219     std::list<NotifyArgs> out;
220     mCursorButtonAccumulator.process(rawEvent);
221     mCursorMotionAccumulator.process(rawEvent);
222     mCursorScrollAccumulator.process(rawEvent);
223 
224     if (rawEvent.type == EV_SYN && rawEvent.code == SYN_REPORT) {
225         const auto [eventTime, readTime] =
226                 applyBluetoothTimestampSmoothening(getDeviceContext().getDeviceIdentifier(),
227                                                    rawEvent.when, rawEvent.readTime,
228                                                    mLastEventTime);
229         out += sync(eventTime, readTime);
230         mLastEventTime = eventTime;
231     }
232     return out;
233 }
234 
sync(nsecs_t when,nsecs_t readTime)235 std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) {
236     std::list<NotifyArgs> out;
237     if (!mDisplayId) {
238         // Ignore events when there is no target display configured.
239         return out;
240     }
241 
242     int32_t lastButtonState = mButtonState;
243     int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
244     mButtonState = currentButtonState;
245 
246     bool wasDown = isPointerDown(lastButtonState);
247     bool down = isPointerDown(currentButtonState);
248     bool downChanged;
249     if (!wasDown && down) {
250         mDownTime = when;
251         downChanged = true;
252     } else if (wasDown && !down) {
253         downChanged = true;
254     } else {
255         downChanged = false;
256     }
257     nsecs_t downTime = mDownTime;
258     bool buttonsChanged = currentButtonState != lastButtonState;
259     int32_t buttonsPressed = currentButtonState & ~lastButtonState;
260     int32_t buttonsReleased = lastButtonState & ~currentButtonState;
261 
262     float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
263     float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
264     bool moved = deltaX != 0 || deltaY != 0;
265 
266     // Rotate delta according to orientation.
267     rotateDelta(mOrientation, &deltaX, &deltaY);
268 
269     // Move the pointer.
270     PointerProperties pointerProperties;
271     pointerProperties.clear();
272     pointerProperties.id = 0;
273     pointerProperties.toolType = ToolType::MOUSE;
274 
275     PointerCoords pointerCoords;
276     pointerCoords.clear();
277 
278     // A negative value represents inverted scrolling direction.
279     // Applies only if the source is a mouse.
280     const bool isMouse =
281             (mSource == AINPUT_SOURCE_MOUSE) || (mSource == AINPUT_SOURCE_MOUSE_RELATIVE);
282     const int scrollingDirection = (mMouseReverseVerticalScrolling && isMouse) ? -1 : 1;
283     float vscroll = scrollingDirection * mCursorScrollAccumulator.getRelativeVWheel();
284     float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
285     bool scrolled = vscroll != 0 || hscroll != 0;
286 
287     mWheelYVelocityControl.move(when, nullptr, &vscroll);
288     mWheelXVelocityControl.move(when, &hscroll, nullptr);
289 
290     mPointerVelocityControl.move(when, &deltaX, &deltaY);
291 
292     float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
293     float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
294     if (mSource == AINPUT_SOURCE_MOUSE) {
295         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
296         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
297     } else {
298         // Pointer capture and navigation modes
299         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
300         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
301         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
302         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
303     }
304 
305     pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
306 
307     // Moving an external trackball or mouse should wake the device.
308     // We don't do this for internal cursor devices to prevent them from waking up
309     // the device in your pocket.
310     // TODO: Use the input device configuration to control this behavior more finely.
311     uint32_t policyFlags = 0;
312     if ((buttonsPressed || moved || scrolled) && getDeviceContext().isExternal()) {
313         policyFlags |= POLICY_FLAG_WAKE;
314     }
315 
316     // Synthesize key down from buttons if needed.
317     out += synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, readTime, getDeviceId(),
318                                 mSource, *mDisplayId, policyFlags, lastButtonState,
319                                 currentButtonState);
320 
321     // Send motion event.
322     if (downChanged || moved || scrolled || buttonsChanged) {
323         int32_t metaState = getContext()->getGlobalMetaState();
324         int32_t buttonState = lastButtonState;
325         int32_t motionEventAction;
326         if (downChanged) {
327             motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
328         } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
329             motionEventAction = AMOTION_EVENT_ACTION_MOVE;
330         } else {
331             motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
332         }
333 
334         if (buttonsReleased) {
335             BitSet32 released(buttonsReleased);
336             while (!released.isEmpty()) {
337                 int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
338                 buttonState &= ~actionButton;
339                 out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime,
340                                                getDeviceId(), mSource, *mDisplayId, policyFlags,
341                                                AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
342                                                metaState, buttonState, MotionClassification::NONE,
343                                                AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
344                                                &pointerCoords, mXPrecision, mYPrecision,
345                                                xCursorPosition, yCursorPosition, downTime,
346                                                /*videoFrames=*/{}));
347             }
348         }
349 
350         out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
351                                        mSource, *mDisplayId, policyFlags, motionEventAction, 0, 0,
352                                        metaState, currentButtonState, MotionClassification::NONE,
353                                        AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
354                                        &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
355                                        yCursorPosition, downTime,
356                                        /*videoFrames=*/{}));
357 
358         if (buttonsPressed) {
359             BitSet32 pressed(buttonsPressed);
360             while (!pressed.isEmpty()) {
361                 int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
362                 buttonState |= actionButton;
363                 out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime,
364                                                getDeviceId(), mSource, *mDisplayId, policyFlags,
365                                                AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
366                                                metaState, buttonState, MotionClassification::NONE,
367                                                AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
368                                                &pointerCoords, mXPrecision, mYPrecision,
369                                                xCursorPosition, yCursorPosition, downTime,
370                                                /*videoFrames=*/{}));
371             }
372         }
373 
374         ALOG_ASSERT(buttonState == currentButtonState);
375 
376         // Send hover move after UP to tell the application that the mouse is hovering now.
377         if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
378             out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
379                                            mSource, *mDisplayId, policyFlags,
380                                            AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
381                                            currentButtonState, MotionClassification::NONE,
382                                            AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
383                                            &pointerCoords, mXPrecision, mYPrecision,
384                                            xCursorPosition, yCursorPosition, downTime,
385                                            /*videoFrames=*/{}));
386         }
387 
388         // Send scroll events.
389         if (scrolled) {
390             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
391             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
392 
393             out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
394                                            mSource, *mDisplayId, policyFlags,
395                                            AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
396                                            currentButtonState, MotionClassification::NONE,
397                                            AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
398                                            &pointerCoords, mXPrecision, mYPrecision,
399                                            xCursorPosition, yCursorPosition, downTime,
400                                            /*videoFrames=*/{}));
401         }
402     }
403 
404     // Synthesize key up from buttons if needed.
405     out += synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, readTime, getDeviceId(),
406                                 mSource, *mDisplayId, policyFlags, lastButtonState,
407                                 currentButtonState);
408 
409     mCursorMotionAccumulator.finishSync();
410     mCursorScrollAccumulator.finishSync();
411     return out;
412 }
413 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)414 int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
415     if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
416         return getDeviceContext().getScanCodeState(scanCode);
417     } else {
418         return AKEY_STATE_UNKNOWN;
419     }
420 }
421 
getAssociatedDisplayId()422 std::optional<ui::LogicalDisplayId> CursorInputMapper::getAssociatedDisplayId() {
423     return mDisplayId;
424 }
425 
configureBasicParams()426 void CursorInputMapper::configureBasicParams() {
427     mCursorScrollAccumulator.configure(getDeviceContext());
428 
429     // Configure basic parameters.
430     mParameters = computeParameters(getDeviceContext());
431 
432     // Configure device mode.
433     switch (mParameters.mode) {
434         case Parameters::Mode::POINTER_RELATIVE:
435             // Should not happen during first time configuration.
436             ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER");
437             mParameters.mode = Parameters::Mode::POINTER;
438             [[fallthrough]];
439         case Parameters::Mode::POINTER:
440             mSource = AINPUT_SOURCE_MOUSE;
441             mXPrecision = 1.0f;
442             mYPrecision = 1.0f;
443             mXScale = 1.0f;
444             mYScale = 1.0f;
445             break;
446         case Parameters::Mode::NAVIGATION:
447             mSource = AINPUT_SOURCE_TRACKBALL;
448             mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
449             mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
450             mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
451             mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
452             break;
453     }
454 
455     mVWheelScale = 1.0f;
456     mHWheelScale = 1.0f;
457 }
458 
configureOnPointerCapture(const InputReaderConfiguration & config)459 void CursorInputMapper::configureOnPointerCapture(const InputReaderConfiguration& config) {
460     if (config.pointerCaptureRequest.isEnable()) {
461         if (mParameters.mode == Parameters::Mode::POINTER) {
462             mParameters.mode = Parameters::Mode::POINTER_RELATIVE;
463             mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
464         } else {
465             ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
466         }
467     } else {
468         if (mParameters.mode == Parameters::Mode::POINTER_RELATIVE) {
469             mParameters.mode = Parameters::Mode::POINTER;
470             mSource = AINPUT_SOURCE_MOUSE;
471         } else {
472             ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE");
473         }
474     }
475     bumpGeneration();
476 }
477 
configureOnChangePointerSpeed(const InputReaderConfiguration & config)478 void CursorInputMapper::configureOnChangePointerSpeed(const InputReaderConfiguration& config) {
479     if (mParameters.mode == Parameters::Mode::POINTER_RELATIVE) {
480         // Disable any acceleration or scaling for the pointer when Pointer Capture is enabled.
481         mPointerVelocityControl.setAccelerationEnabled(false);
482         mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
483         mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
484     } else {
485         mPointerVelocityControl.setAccelerationEnabled(
486                 config.displaysWithMousePointerAccelerationDisabled.count(
487                         mDisplayId.value_or(ui::LogicalDisplayId::INVALID)) == 0);
488         mPointerVelocityControl.setCurve(
489                 createAccelerationCurveForPointerSensitivity(config.mousePointerSpeed));
490         mWheelXVelocityControl.setParameters(config.wheelVelocityControlParameters);
491         mWheelYVelocityControl.setParameters(config.wheelVelocityControlParameters);
492     }
493 }
494 
configureOnChangeDisplayInfo(const InputReaderConfiguration & config)495 void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfiguration& config) {
496     const bool isPointer = mParameters.mode == Parameters::Mode::POINTER;
497 
498     mDisplayId = ui::LogicalDisplayId::INVALID;
499     std::optional<DisplayViewport> resolvedViewport;
500     if (auto assocViewport = mDeviceContext.getAssociatedViewport(); assocViewport) {
501         // This InputDevice is associated with a viewport.
502         // Only generate events for the associated display.
503         mDisplayId = assocViewport->displayId;
504         resolvedViewport = *assocViewport;
505     } else if (isPointer) {
506         // The InputDevice is not associated with a viewport, but it controls the mouse pointer.
507         // Always use DISPLAY_ID_NONE for mouse events.
508         // PointerChoreographer will make it target the correct the displayId later.
509         resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
510         mDisplayId =
511                 resolvedViewport ? std::make_optional(ui::LogicalDisplayId::INVALID) : std::nullopt;
512     }
513 
514     mOrientation = (mParameters.orientationAware && mParameters.hasAssociatedDisplay) ||
515                     mParameters.mode == Parameters::Mode::POINTER_RELATIVE || !resolvedViewport
516             ? ui::ROTATION_0
517             : getInverseRotation(resolvedViewport->orientation);
518 
519     mBoundsInLogicalDisplay = resolvedViewport
520             ? FloatRect{static_cast<float>(resolvedViewport->logicalLeft),
521                         static_cast<float>(resolvedViewport->logicalTop),
522                         static_cast<float>(resolvedViewport->logicalRight - 1),
523                         static_cast<float>(resolvedViewport->logicalBottom - 1)}
524             : FloatRect{0, 0, 0, 0};
525 
526     bumpGeneration();
527 }
528 
configureOnChangeMouseSettings(const InputReaderConfiguration & config)529 void CursorInputMapper::configureOnChangeMouseSettings(const InputReaderConfiguration& config) {
530     mMouseReverseVerticalScrolling = config.mouseReverseVerticalScrollingEnabled;
531     mCursorButtonAccumulator.setSwapLeftRightButtons(config.mouseSwapPrimaryButtonEnabled);
532 }
533 
534 } // namespace android
535