blob: 520a4a4f52898fc97009bde845416e309742dbd7 [file] [log] [blame]
Prabir Pradhanbaa5c822019-08-30 15:27:05 -07001/*
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
Prabir Pradhan9244aea2020-02-05 20:31:40 -080017#include "../Macros.h"
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070018
19#include "CursorInputMapper.h"
20
21#include "CursorButtonAccumulator.h"
22#include "CursorScrollAccumulator.h"
23#include "TouchCursorInputMapperCommon.h"
24
25namespace android {
26
27// --- CursorMotionAccumulator ---
28
29CursorMotionAccumulator::CursorMotionAccumulator() {
30 clearRelativeAxes();
31}
32
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080033void CursorMotionAccumulator::reset(InputDeviceContext& deviceContext) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070034 clearRelativeAxes();
35}
36
37void CursorMotionAccumulator::clearRelativeAxes() {
38 mRelX = 0;
39 mRelY = 0;
40}
41
42void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
43 if (rawEvent->type == EV_REL) {
44 switch (rawEvent->code) {
45 case REL_X:
46 mRelX = rawEvent->value;
47 break;
48 case REL_Y:
49 mRelY = rawEvent->value;
50 break;
51 }
52 }
53}
54
55void CursorMotionAccumulator::finishSync() {
56 clearRelativeAxes();
57}
58
59// --- CursorInputMapper ---
60
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080061CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext)
62 : InputMapper(deviceContext) {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070063
64CursorInputMapper::~CursorInputMapper() {}
65
66uint32_t CursorInputMapper::getSources() {
67 return mSource;
68}
69
70void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
71 InputMapper::populateDeviceInfo(info);
72
73 if (mParameters.mode == Parameters::MODE_POINTER) {
74 float minX, minY, maxX, maxY;
75 if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
76 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
77 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
78 }
79 } else {
80 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
81 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
82 }
83 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
84
85 if (mCursorScrollAccumulator.haveRelativeVWheel()) {
86 info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
87 }
88 if (mCursorScrollAccumulator.haveRelativeHWheel()) {
89 info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
90 }
91}
92
93void CursorInputMapper::dump(std::string& dump) {
94 dump += INDENT2 "Cursor Input Mapper:\n";
95 dumpParameters(dump);
96 dump += StringPrintf(INDENT3 "XScale: %0.3f\n", mXScale);
97 dump += StringPrintf(INDENT3 "YScale: %0.3f\n", mYScale);
98 dump += StringPrintf(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
99 dump += StringPrintf(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
100 dump += StringPrintf(INDENT3 "HaveVWheel: %s\n",
101 toString(mCursorScrollAccumulator.haveRelativeVWheel()));
102 dump += StringPrintf(INDENT3 "HaveHWheel: %s\n",
103 toString(mCursorScrollAccumulator.haveRelativeHWheel()));
104 dump += StringPrintf(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
105 dump += StringPrintf(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
106 dump += StringPrintf(INDENT3 "Orientation: %d\n", mOrientation);
107 dump += StringPrintf(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
108 dump += StringPrintf(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
109 dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
110}
111
112void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
113 uint32_t changes) {
114 InputMapper::configure(when, config, changes);
115
116 if (!changes) { // first time only
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800117 mCursorScrollAccumulator.configure(getDeviceContext());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700118
119 // Configure basic parameters.
120 configureParameters();
121
122 // Configure device mode.
123 switch (mParameters.mode) {
124 case Parameters::MODE_POINTER_RELATIVE:
125 // Should not happen during first time configuration.
126 ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER");
127 mParameters.mode = Parameters::MODE_POINTER;
128 [[fallthrough]];
129 case Parameters::MODE_POINTER:
130 mSource = AINPUT_SOURCE_MOUSE;
131 mXPrecision = 1.0f;
132 mYPrecision = 1.0f;
133 mXScale = 1.0f;
134 mYScale = 1.0f;
135 mPointerController = getPolicy()->obtainPointerController(getDeviceId());
136 break;
137 case Parameters::MODE_NAVIGATION:
138 mSource = AINPUT_SOURCE_TRACKBALL;
139 mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
140 mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
141 mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
142 mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
143 break;
144 }
145
146 mVWheelScale = 1.0f;
147 mHWheelScale = 1.0f;
148 }
149
150 if ((!changes && config->pointerCapture) ||
151 (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
152 if (config->pointerCapture) {
153 if (mParameters.mode == Parameters::MODE_POINTER) {
154 mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
155 mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
156 // Keep PointerController around in order to preserve the pointer position.
157 mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
158 } else {
159 ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
160 }
161 } else {
162 if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) {
163 mParameters.mode = Parameters::MODE_POINTER;
164 mSource = AINPUT_SOURCE_MOUSE;
165 } else {
166 ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE");
167 }
168 }
169 bumpGeneration();
170 if (changes) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800171 NotifyDeviceResetArgs args(getContext()->getNextSequenceNum(), when, getDeviceId());
172 getListener()->notifyDeviceReset(&args);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700173 }
174 }
175
176 if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
177 mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
178 mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
179 mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
180 }
181
182 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
183 mOrientation = DISPLAY_ORIENTATION_0;
184 if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
185 std::optional<DisplayViewport> internalViewport =
186 config->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
187 if (internalViewport) {
188 mOrientation = internalViewport->orientation;
189 }
190 }
191
192 // Update the PointerController if viewports changed.
193 if (mParameters.mode == Parameters::MODE_POINTER) {
Garfield Tan888a6a42020-01-09 11:39:16 -0800194 updatePointerControllerDisplayViewport(*config);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700195 }
196 bumpGeneration();
197 }
198}
199
Garfield Tan888a6a42020-01-09 11:39:16 -0800200void CursorInputMapper::updatePointerControllerDisplayViewport(
201 const InputReaderConfiguration& config) {
202 std::optional<DisplayViewport> viewport =
203 config.getDisplayViewportById(config.defaultPointerDisplayId);
204 if (!viewport) {
205 ALOGW("Can't find the designated viewport with ID %" PRId32 " to update cursor input "
206 "mapper. Fall back to default display",
207 config.defaultPointerDisplayId);
208 viewport = config.getDisplayViewportById(ADISPLAY_ID_DEFAULT);
209 }
210
211 if (!viewport) {
212 ALOGE("Still can't find a viable viewport to update cursor input mapper. Skip setting it to"
213 " PointerController.");
214 return;
215 }
216
217 mPointerController->setDisplayViewport(*viewport);
218}
219
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700220void CursorInputMapper::configureParameters() {
221 mParameters.mode = Parameters::MODE_POINTER;
222 String8 cursorModeString;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800223 if (getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.mode"),
224 cursorModeString)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700225 if (cursorModeString == "navigation") {
226 mParameters.mode = Parameters::MODE_NAVIGATION;
227 } else if (cursorModeString != "pointer" && cursorModeString != "default") {
228 ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
229 }
230 }
231
232 mParameters.orientationAware = false;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800233 getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
234 mParameters.orientationAware);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700235
236 mParameters.hasAssociatedDisplay = false;
237 if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
238 mParameters.hasAssociatedDisplay = true;
239 }
240}
241
242void CursorInputMapper::dumpParameters(std::string& dump) {
243 dump += INDENT3 "Parameters:\n";
244 dump += StringPrintf(INDENT4 "HasAssociatedDisplay: %s\n",
245 toString(mParameters.hasAssociatedDisplay));
246
247 switch (mParameters.mode) {
248 case Parameters::MODE_POINTER:
249 dump += INDENT4 "Mode: pointer\n";
250 break;
251 case Parameters::MODE_POINTER_RELATIVE:
252 dump += INDENT4 "Mode: relative pointer\n";
253 break;
254 case Parameters::MODE_NAVIGATION:
255 dump += INDENT4 "Mode: navigation\n";
256 break;
257 default:
258 ALOG_ASSERT(false);
259 }
260
261 dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
262}
263
264void CursorInputMapper::reset(nsecs_t when) {
265 mButtonState = 0;
266 mDownTime = 0;
267
268 mPointerVelocityControl.reset();
269 mWheelXVelocityControl.reset();
270 mWheelYVelocityControl.reset();
271
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800272 mCursorButtonAccumulator.reset(getDeviceContext());
273 mCursorMotionAccumulator.reset(getDeviceContext());
274 mCursorScrollAccumulator.reset(getDeviceContext());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700275
276 InputMapper::reset(when);
277}
278
279void CursorInputMapper::process(const RawEvent* rawEvent) {
280 mCursorButtonAccumulator.process(rawEvent);
281 mCursorMotionAccumulator.process(rawEvent);
282 mCursorScrollAccumulator.process(rawEvent);
283
284 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
285 sync(rawEvent->when);
286 }
287}
288
289void CursorInputMapper::sync(nsecs_t when) {
290 int32_t lastButtonState = mButtonState;
291 int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
292 mButtonState = currentButtonState;
293
294 bool wasDown = isPointerDown(lastButtonState);
295 bool down = isPointerDown(currentButtonState);
296 bool downChanged;
297 if (!wasDown && down) {
298 mDownTime = when;
299 downChanged = true;
300 } else if (wasDown && !down) {
301 downChanged = true;
302 } else {
303 downChanged = false;
304 }
305 nsecs_t downTime = mDownTime;
306 bool buttonsChanged = currentButtonState != lastButtonState;
307 int32_t buttonsPressed = currentButtonState & ~lastButtonState;
308 int32_t buttonsReleased = lastButtonState & ~currentButtonState;
309
310 float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
311 float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
312 bool moved = deltaX != 0 || deltaY != 0;
313
314 // Rotate delta according to orientation if needed.
315 if (mParameters.orientationAware && mParameters.hasAssociatedDisplay &&
316 (deltaX != 0.0f || deltaY != 0.0f)) {
317 rotateDelta(mOrientation, &deltaX, &deltaY);
318 }
319
320 // Move the pointer.
321 PointerProperties pointerProperties;
322 pointerProperties.clear();
323 pointerProperties.id = 0;
324 pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
325
326 PointerCoords pointerCoords;
327 pointerCoords.clear();
328
329 float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
330 float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
331 bool scrolled = vscroll != 0 || hscroll != 0;
332
333 mWheelYVelocityControl.move(when, nullptr, &vscroll);
334 mWheelXVelocityControl.move(when, &hscroll, nullptr);
335
336 mPointerVelocityControl.move(when, &deltaX, &deltaY);
337
338 int32_t displayId;
339 float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
340 float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
341 if (mSource == AINPUT_SOURCE_MOUSE) {
342 if (moved || scrolled || buttonsChanged) {
343 mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
344
345 if (moved) {
346 mPointerController->move(deltaX, deltaY);
347 }
348
349 if (buttonsChanged) {
350 mPointerController->setButtonState(currentButtonState);
351 }
352
353 mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
354 }
355
356 mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
357 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
358 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
359 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
360 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
361 displayId = mPointerController->getDisplayId();
362 } else {
363 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
364 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
365 displayId = ADISPLAY_ID_NONE;
366 }
367
368 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
369
370 // Moving an external trackball or mouse should wake the device.
371 // We don't do this for internal cursor devices to prevent them from waking up
372 // the device in your pocket.
373 // TODO: Use the input device configuration to control this behavior more finely.
374 uint32_t policyFlags = 0;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800375 if ((buttonsPressed || moved || scrolled) && getDeviceContext().isExternal()) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700376 policyFlags |= POLICY_FLAG_WAKE;
377 }
378
379 // Synthesize key down from buttons if needed.
380 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
381 displayId, policyFlags, lastButtonState, currentButtonState);
382
383 // Send motion event.
384 if (downChanged || moved || scrolled || buttonsChanged) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800385 int32_t metaState = getContext()->getGlobalMetaState();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700386 int32_t buttonState = lastButtonState;
387 int32_t motionEventAction;
388 if (downChanged) {
389 motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
390 } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
391 motionEventAction = AMOTION_EVENT_ACTION_MOVE;
392 } else {
393 motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
394 }
395
396 if (buttonsReleased) {
397 BitSet32 released(buttonsReleased);
398 while (!released.isEmpty()) {
399 int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
400 buttonState &= ~actionButton;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800401 NotifyMotionArgs releaseArgs(getContext()->getNextSequenceNum(), when,
402 getDeviceId(), mSource, displayId, policyFlags,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700403 AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
404 metaState, buttonState, MotionClassification::NONE,
405 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
406 &pointerCoords, mXPrecision, mYPrecision,
407 xCursorPosition, yCursorPosition, downTime,
408 /* videoFrames */ {});
409 getListener()->notifyMotion(&releaseArgs);
410 }
411 }
412
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800413 NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700414 displayId, policyFlags, motionEventAction, 0, 0, metaState,
415 currentButtonState, MotionClassification::NONE,
416 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
417 mXPrecision, mYPrecision, xCursorPosition, yCursorPosition, downTime,
418 /* videoFrames */ {});
419 getListener()->notifyMotion(&args);
420
421 if (buttonsPressed) {
422 BitSet32 pressed(buttonsPressed);
423 while (!pressed.isEmpty()) {
424 int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
425 buttonState |= actionButton;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800426 NotifyMotionArgs pressArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700427 mSource, displayId, policyFlags,
428 AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
429 metaState, buttonState, MotionClassification::NONE,
430 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
431 &pointerCoords, mXPrecision, mYPrecision,
432 xCursorPosition, yCursorPosition, downTime,
433 /* videoFrames */ {});
434 getListener()->notifyMotion(&pressArgs);
435 }
436 }
437
438 ALOG_ASSERT(buttonState == currentButtonState);
439
440 // Send hover move after UP to tell the application that the mouse is hovering now.
441 if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800442 NotifyMotionArgs hoverArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
443 mSource, displayId, policyFlags,
444 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
445 currentButtonState, MotionClassification::NONE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700446 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
447 &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
448 yCursorPosition, downTime, /* videoFrames */ {});
449 getListener()->notifyMotion(&hoverArgs);
450 }
451
452 // Send scroll events.
453 if (scrolled) {
454 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
455 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
456
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800457 NotifyMotionArgs scrollArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700458 mSource, displayId, policyFlags,
459 AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
460 currentButtonState, MotionClassification::NONE,
461 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
462 &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
463 yCursorPosition, downTime, /* videoFrames */ {});
464 getListener()->notifyMotion(&scrollArgs);
465 }
466 }
467
468 // Synthesize key up from buttons if needed.
469 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
470 displayId, policyFlags, lastButtonState, currentButtonState);
471
472 mCursorMotionAccumulator.finishSync();
473 mCursorScrollAccumulator.finishSync();
474}
475
476int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
477 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800478 return getDeviceContext().getScanCodeState(scanCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700479 } else {
480 return AKEY_STATE_UNKNOWN;
481 }
482}
483
484void CursorInputMapper::fadePointer() {
485 if (mPointerController != nullptr) {
486 mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
487 }
488}
489
490std::optional<int32_t> CursorInputMapper::getAssociatedDisplayId() {
491 if (mParameters.hasAssociatedDisplay) {
492 if (mParameters.mode == Parameters::MODE_POINTER) {
493 return std::make_optional(mPointerController->getDisplayId());
494 } else {
495 // If the device is orientationAware and not a mouse,
496 // it expects to dispatch events to any display
497 return std::make_optional(ADISPLAY_ID_NONE);
498 }
499 }
500 return std::nullopt;
501}
502
503} // namespace android