blob: d1f20c777dde14803d36caed4aeb408199d15b4b [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
Michael Wrightfe3de7d2020-07-02 19:05:30 +010017// clang-format off
Prabir Pradhan9244aea2020-02-05 20:31:40 -080018#include "../Macros.h"
Michael Wrightfe3de7d2020-07-02 19:05:30 +010019// clang-format on
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070020
21#include "CursorInputMapper.h"
22
23#include "CursorButtonAccumulator.h"
24#include "CursorScrollAccumulator.h"
Michael Wrightca5bede2020-07-02 00:00:29 +010025#include "PointerControllerInterface.h"
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070026#include "TouchCursorInputMapperCommon.h"
27
28namespace android {
29
30// --- CursorMotionAccumulator ---
31
32CursorMotionAccumulator::CursorMotionAccumulator() {
33 clearRelativeAxes();
34}
35
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080036void CursorMotionAccumulator::reset(InputDeviceContext& deviceContext) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070037 clearRelativeAxes();
38}
39
40void CursorMotionAccumulator::clearRelativeAxes() {
41 mRelX = 0;
42 mRelY = 0;
43}
44
45void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
46 if (rawEvent->type == EV_REL) {
47 switch (rawEvent->code) {
48 case REL_X:
49 mRelX = rawEvent->value;
50 break;
51 case REL_Y:
52 mRelY = rawEvent->value;
53 break;
54 }
55 }
56}
57
58void CursorMotionAccumulator::finishSync() {
59 clearRelativeAxes();
60}
61
62// --- CursorInputMapper ---
63
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080064CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext)
65 : InputMapper(deviceContext) {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070066
67CursorInputMapper::~CursorInputMapper() {}
68
69uint32_t CursorInputMapper::getSources() {
70 return mSource;
71}
72
73void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
74 InputMapper::populateDeviceInfo(info);
75
76 if (mParameters.mode == Parameters::MODE_POINTER) {
77 float minX, minY, maxX, maxY;
78 if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
79 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
80 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
81 }
82 } else {
83 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
84 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
85 }
86 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
87
88 if (mCursorScrollAccumulator.haveRelativeVWheel()) {
89 info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
90 }
91 if (mCursorScrollAccumulator.haveRelativeHWheel()) {
92 info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
93 }
94}
95
96void CursorInputMapper::dump(std::string& dump) {
97 dump += INDENT2 "Cursor Input Mapper:\n";
98 dumpParameters(dump);
99 dump += StringPrintf(INDENT3 "XScale: %0.3f\n", mXScale);
100 dump += StringPrintf(INDENT3 "YScale: %0.3f\n", mYScale);
101 dump += StringPrintf(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
102 dump += StringPrintf(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
103 dump += StringPrintf(INDENT3 "HaveVWheel: %s\n",
104 toString(mCursorScrollAccumulator.haveRelativeVWheel()));
105 dump += StringPrintf(INDENT3 "HaveHWheel: %s\n",
106 toString(mCursorScrollAccumulator.haveRelativeHWheel()));
107 dump += StringPrintf(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
108 dump += StringPrintf(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
109 dump += StringPrintf(INDENT3 "Orientation: %d\n", mOrientation);
110 dump += StringPrintf(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
111 dump += StringPrintf(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
112 dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
113}
114
115void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
116 uint32_t changes) {
117 InputMapper::configure(when, config, changes);
118
119 if (!changes) { // first time only
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800120 mCursorScrollAccumulator.configure(getDeviceContext());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700121
122 // Configure basic parameters.
123 configureParameters();
124
125 // Configure device mode.
126 switch (mParameters.mode) {
127 case Parameters::MODE_POINTER_RELATIVE:
128 // Should not happen during first time configuration.
129 ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER");
130 mParameters.mode = Parameters::MODE_POINTER;
131 [[fallthrough]];
132 case Parameters::MODE_POINTER:
133 mSource = AINPUT_SOURCE_MOUSE;
134 mXPrecision = 1.0f;
135 mYPrecision = 1.0f;
136 mXScale = 1.0f;
137 mYScale = 1.0f;
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800138 mPointerController = getContext()->getPointerController(getDeviceId());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700139 break;
140 case Parameters::MODE_NAVIGATION:
141 mSource = AINPUT_SOURCE_TRACKBALL;
142 mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
143 mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
144 mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
145 mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
146 break;
147 }
148
149 mVWheelScale = 1.0f;
150 mHWheelScale = 1.0f;
151 }
152
153 if ((!changes && config->pointerCapture) ||
154 (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
155 if (config->pointerCapture) {
156 if (mParameters.mode == Parameters::MODE_POINTER) {
157 mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
158 mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
159 // Keep PointerController around in order to preserve the pointer position.
Michael Wrightca5bede2020-07-02 00:00:29 +0100160 mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700161 } else {
162 ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
163 }
164 } else {
165 if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) {
166 mParameters.mode = Parameters::MODE_POINTER;
167 mSource = AINPUT_SOURCE_MOUSE;
168 } else {
169 ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE");
170 }
171 }
172 bumpGeneration();
173 if (changes) {
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800174 NotifyDeviceResetArgs args(getContext()->getNextId(), when, getDeviceId());
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800175 getListener()->notifyDeviceReset(&args);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700176 }
177 }
178
179 if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
180 mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
181 mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
182 mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
183 }
184
185 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
186 mOrientation = DISPLAY_ORIENTATION_0;
187 if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
188 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100189 config->getDisplayViewportByType(ViewportType::INTERNAL);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700190 if (internalViewport) {
191 mOrientation = internalViewport->orientation;
192 }
193 }
194
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700195 bumpGeneration();
196 }
197}
198
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700199void CursorInputMapper::configureParameters() {
200 mParameters.mode = Parameters::MODE_POINTER;
201 String8 cursorModeString;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800202 if (getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.mode"),
203 cursorModeString)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700204 if (cursorModeString == "navigation") {
205 mParameters.mode = Parameters::MODE_NAVIGATION;
206 } else if (cursorModeString != "pointer" && cursorModeString != "default") {
207 ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
208 }
209 }
210
211 mParameters.orientationAware = false;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800212 getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
213 mParameters.orientationAware);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700214
215 mParameters.hasAssociatedDisplay = false;
216 if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
217 mParameters.hasAssociatedDisplay = true;
218 }
219}
220
221void CursorInputMapper::dumpParameters(std::string& dump) {
222 dump += INDENT3 "Parameters:\n";
223 dump += StringPrintf(INDENT4 "HasAssociatedDisplay: %s\n",
224 toString(mParameters.hasAssociatedDisplay));
225
226 switch (mParameters.mode) {
227 case Parameters::MODE_POINTER:
228 dump += INDENT4 "Mode: pointer\n";
229 break;
230 case Parameters::MODE_POINTER_RELATIVE:
231 dump += INDENT4 "Mode: relative pointer\n";
232 break;
233 case Parameters::MODE_NAVIGATION:
234 dump += INDENT4 "Mode: navigation\n";
235 break;
236 default:
237 ALOG_ASSERT(false);
238 }
239
240 dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
241}
242
243void CursorInputMapper::reset(nsecs_t when) {
244 mButtonState = 0;
245 mDownTime = 0;
246
247 mPointerVelocityControl.reset();
248 mWheelXVelocityControl.reset();
249 mWheelYVelocityControl.reset();
250
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800251 mCursorButtonAccumulator.reset(getDeviceContext());
252 mCursorMotionAccumulator.reset(getDeviceContext());
253 mCursorScrollAccumulator.reset(getDeviceContext());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700254
255 InputMapper::reset(when);
256}
257
258void CursorInputMapper::process(const RawEvent* rawEvent) {
259 mCursorButtonAccumulator.process(rawEvent);
260 mCursorMotionAccumulator.process(rawEvent);
261 mCursorScrollAccumulator.process(rawEvent);
262
263 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
264 sync(rawEvent->when);
265 }
266}
267
268void CursorInputMapper::sync(nsecs_t when) {
269 int32_t lastButtonState = mButtonState;
270 int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
271 mButtonState = currentButtonState;
272
273 bool wasDown = isPointerDown(lastButtonState);
274 bool down = isPointerDown(currentButtonState);
275 bool downChanged;
276 if (!wasDown && down) {
277 mDownTime = when;
278 downChanged = true;
279 } else if (wasDown && !down) {
280 downChanged = true;
281 } else {
282 downChanged = false;
283 }
284 nsecs_t downTime = mDownTime;
285 bool buttonsChanged = currentButtonState != lastButtonState;
286 int32_t buttonsPressed = currentButtonState & ~lastButtonState;
287 int32_t buttonsReleased = lastButtonState & ~currentButtonState;
288
289 float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
290 float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
291 bool moved = deltaX != 0 || deltaY != 0;
292
293 // Rotate delta according to orientation if needed.
294 if (mParameters.orientationAware && mParameters.hasAssociatedDisplay &&
295 (deltaX != 0.0f || deltaY != 0.0f)) {
296 rotateDelta(mOrientation, &deltaX, &deltaY);
297 }
298
299 // Move the pointer.
300 PointerProperties pointerProperties;
301 pointerProperties.clear();
302 pointerProperties.id = 0;
303 pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
304
305 PointerCoords pointerCoords;
306 pointerCoords.clear();
307
308 float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
309 float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
310 bool scrolled = vscroll != 0 || hscroll != 0;
311
312 mWheelYVelocityControl.move(when, nullptr, &vscroll);
313 mWheelXVelocityControl.move(when, &hscroll, nullptr);
314
315 mPointerVelocityControl.move(when, &deltaX, &deltaY);
316
317 int32_t displayId;
318 float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
319 float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
320 if (mSource == AINPUT_SOURCE_MOUSE) {
321 if (moved || scrolled || buttonsChanged) {
Michael Wrightca5bede2020-07-02 00:00:29 +0100322 mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700323
324 if (moved) {
325 mPointerController->move(deltaX, deltaY);
326 }
327
328 if (buttonsChanged) {
329 mPointerController->setButtonState(currentButtonState);
330 }
331
Michael Wrightca5bede2020-07-02 00:00:29 +0100332 mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700333 }
334
335 mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
336 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
337 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
338 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
339 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
340 displayId = mPointerController->getDisplayId();
341 } else {
342 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
343 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
344 displayId = ADISPLAY_ID_NONE;
345 }
346
347 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
348
349 // Moving an external trackball or mouse should wake the device.
350 // We don't do this for internal cursor devices to prevent them from waking up
351 // the device in your pocket.
352 // TODO: Use the input device configuration to control this behavior more finely.
353 uint32_t policyFlags = 0;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800354 if ((buttonsPressed || moved || scrolled) && getDeviceContext().isExternal()) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700355 policyFlags |= POLICY_FLAG_WAKE;
356 }
357
358 // Synthesize key down from buttons if needed.
359 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
360 displayId, policyFlags, lastButtonState, currentButtonState);
361
362 // Send motion event.
363 if (downChanged || moved || scrolled || buttonsChanged) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800364 int32_t metaState = getContext()->getGlobalMetaState();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700365 int32_t buttonState = lastButtonState;
366 int32_t motionEventAction;
367 if (downChanged) {
368 motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
369 } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
370 motionEventAction = AMOTION_EVENT_ACTION_MOVE;
371 } else {
372 motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
373 }
374
375 if (buttonsReleased) {
376 BitSet32 released(buttonsReleased);
377 while (!released.isEmpty()) {
378 int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
379 buttonState &= ~actionButton;
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800380 NotifyMotionArgs releaseArgs(getContext()->getNextId(), when, getDeviceId(),
381 mSource, displayId, policyFlags,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700382 AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
383 metaState, buttonState, MotionClassification::NONE,
384 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
385 &pointerCoords, mXPrecision, mYPrecision,
386 xCursorPosition, yCursorPosition, downTime,
387 /* videoFrames */ {});
388 getListener()->notifyMotion(&releaseArgs);
389 }
390 }
391
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800392 NotifyMotionArgs args(getContext()->getNextId(), when, getDeviceId(), mSource, displayId,
393 policyFlags, motionEventAction, 0, 0, metaState, currentButtonState,
394 MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
395 &pointerProperties, &pointerCoords, mXPrecision, mYPrecision,
396 xCursorPosition, yCursorPosition, downTime,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700397 /* videoFrames */ {});
398 getListener()->notifyMotion(&args);
399
400 if (buttonsPressed) {
401 BitSet32 pressed(buttonsPressed);
402 while (!pressed.isEmpty()) {
403 int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
404 buttonState |= actionButton;
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800405 NotifyMotionArgs pressArgs(getContext()->getNextId(), when, getDeviceId(), mSource,
406 displayId, policyFlags,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700407 AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
408 metaState, buttonState, MotionClassification::NONE,
409 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
410 &pointerCoords, mXPrecision, mYPrecision,
411 xCursorPosition, yCursorPosition, downTime,
412 /* videoFrames */ {});
413 getListener()->notifyMotion(&pressArgs);
414 }
415 }
416
417 ALOG_ASSERT(buttonState == currentButtonState);
418
419 // Send hover move after UP to tell the application that the mouse is hovering now.
420 if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800421 NotifyMotionArgs hoverArgs(getContext()->getNextId(), when, getDeviceId(), mSource,
422 displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
423 0, metaState, currentButtonState, MotionClassification::NONE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700424 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
425 &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
426 yCursorPosition, downTime, /* videoFrames */ {});
427 getListener()->notifyMotion(&hoverArgs);
428 }
429
430 // Send scroll events.
431 if (scrolled) {
432 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
433 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
434
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800435 NotifyMotionArgs scrollArgs(getContext()->getNextId(), when, getDeviceId(), mSource,
436 displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
437 metaState, currentButtonState, MotionClassification::NONE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700438 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
439 &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
440 yCursorPosition, downTime, /* videoFrames */ {});
441 getListener()->notifyMotion(&scrollArgs);
442 }
443 }
444
445 // Synthesize key up from buttons if needed.
446 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
447 displayId, policyFlags, lastButtonState, currentButtonState);
448
449 mCursorMotionAccumulator.finishSync();
450 mCursorScrollAccumulator.finishSync();
451}
452
453int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
454 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800455 return getDeviceContext().getScanCodeState(scanCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700456 } else {
457 return AKEY_STATE_UNKNOWN;
458 }
459}
460
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700461std::optional<int32_t> CursorInputMapper::getAssociatedDisplayId() {
462 if (mParameters.hasAssociatedDisplay) {
463 if (mParameters.mode == Parameters::MODE_POINTER) {
464 return std::make_optional(mPointerController->getDisplayId());
465 } else {
466 // If the device is orientationAware and not a mouse,
467 // it expects to dispatch events to any display
468 return std::make_optional(ADISPLAY_ID_NONE);
469 }
470 }
471 return std::nullopt;
472}
473
474} // namespace android