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