blob: 254b64b4d99e932181993c2b51a6d5ccb90b9523 [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);
Nathaniel R. Lewis2e8f2d42019-08-21 04:56:10 +000085 info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -1.0f, 1.0f, 0.0f, mXScale,
86 0.0f);
87 info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale,
88 0.0f);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070089 }
90 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
91
92 if (mCursorScrollAccumulator.haveRelativeVWheel()) {
93 info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
94 }
95 if (mCursorScrollAccumulator.haveRelativeHWheel()) {
96 info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
97 }
98}
99
100void CursorInputMapper::dump(std::string& dump) {
101 dump += INDENT2 "Cursor Input Mapper:\n";
102 dumpParameters(dump);
103 dump += StringPrintf(INDENT3 "XScale: %0.3f\n", mXScale);
104 dump += StringPrintf(INDENT3 "YScale: %0.3f\n", mYScale);
105 dump += StringPrintf(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
106 dump += StringPrintf(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
107 dump += StringPrintf(INDENT3 "HaveVWheel: %s\n",
108 toString(mCursorScrollAccumulator.haveRelativeVWheel()));
109 dump += StringPrintf(INDENT3 "HaveHWheel: %s\n",
110 toString(mCursorScrollAccumulator.haveRelativeHWheel()));
111 dump += StringPrintf(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
112 dump += StringPrintf(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
113 dump += StringPrintf(INDENT3 "Orientation: %d\n", mOrientation);
114 dump += StringPrintf(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
115 dump += StringPrintf(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
116 dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
117}
118
119void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
120 uint32_t changes) {
121 InputMapper::configure(when, config, changes);
122
123 if (!changes) { // first time only
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800124 mCursorScrollAccumulator.configure(getDeviceContext());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700125
126 // Configure basic parameters.
127 configureParameters();
128
129 // Configure device mode.
130 switch (mParameters.mode) {
131 case Parameters::MODE_POINTER_RELATIVE:
132 // Should not happen during first time configuration.
133 ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER");
134 mParameters.mode = Parameters::MODE_POINTER;
135 [[fallthrough]];
136 case Parameters::MODE_POINTER:
137 mSource = AINPUT_SOURCE_MOUSE;
138 mXPrecision = 1.0f;
139 mYPrecision = 1.0f;
140 mXScale = 1.0f;
141 mYScale = 1.0f;
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800142 mPointerController = getContext()->getPointerController(getDeviceId());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700143 break;
144 case Parameters::MODE_NAVIGATION:
145 mSource = AINPUT_SOURCE_TRACKBALL;
146 mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
147 mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
148 mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
149 mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
150 break;
151 }
152
153 mVWheelScale = 1.0f;
154 mHWheelScale = 1.0f;
155 }
156
157 if ((!changes && config->pointerCapture) ||
158 (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
159 if (config->pointerCapture) {
160 if (mParameters.mode == Parameters::MODE_POINTER) {
161 mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
162 mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
163 // Keep PointerController around in order to preserve the pointer position.
Michael Wrightca5bede2020-07-02 00:00:29 +0100164 mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700165 } else {
166 ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
167 }
168 } else {
169 if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) {
170 mParameters.mode = Parameters::MODE_POINTER;
171 mSource = AINPUT_SOURCE_MOUSE;
172 } else {
173 ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE");
174 }
175 }
176 bumpGeneration();
177 if (changes) {
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000178 NotifyDeviceResetArgs args(getContext()->getNextId(), when, getDeviceId());
179 getListener()->notifyDeviceReset(&args);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700180 }
181 }
182
183 if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
184 mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
185 mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
186 mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
187 }
188
189 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
190 mOrientation = DISPLAY_ORIENTATION_0;
191 if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
192 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100193 config->getDisplayViewportByType(ViewportType::INTERNAL);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700194 if (internalViewport) {
195 mOrientation = internalViewport->orientation;
196 }
197 }
198
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700199 bumpGeneration();
200 }
201}
202
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700203void CursorInputMapper::configureParameters() {
204 mParameters.mode = Parameters::MODE_POINTER;
205 String8 cursorModeString;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800206 if (getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.mode"),
207 cursorModeString)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700208 if (cursorModeString == "navigation") {
209 mParameters.mode = Parameters::MODE_NAVIGATION;
210 } else if (cursorModeString != "pointer" && cursorModeString != "default") {
211 ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
212 }
213 }
214
215 mParameters.orientationAware = false;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800216 getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
217 mParameters.orientationAware);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700218
219 mParameters.hasAssociatedDisplay = false;
220 if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
221 mParameters.hasAssociatedDisplay = true;
222 }
223}
224
225void CursorInputMapper::dumpParameters(std::string& dump) {
226 dump += INDENT3 "Parameters:\n";
227 dump += StringPrintf(INDENT4 "HasAssociatedDisplay: %s\n",
228 toString(mParameters.hasAssociatedDisplay));
229
230 switch (mParameters.mode) {
231 case Parameters::MODE_POINTER:
232 dump += INDENT4 "Mode: pointer\n";
233 break;
234 case Parameters::MODE_POINTER_RELATIVE:
235 dump += INDENT4 "Mode: relative pointer\n";
236 break;
237 case Parameters::MODE_NAVIGATION:
238 dump += INDENT4 "Mode: navigation\n";
239 break;
240 default:
241 ALOG_ASSERT(false);
242 }
243
244 dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
245}
246
247void CursorInputMapper::reset(nsecs_t when) {
248 mButtonState = 0;
249 mDownTime = 0;
250
251 mPointerVelocityControl.reset();
252 mWheelXVelocityControl.reset();
253 mWheelYVelocityControl.reset();
254
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800255 mCursorButtonAccumulator.reset(getDeviceContext());
256 mCursorMotionAccumulator.reset(getDeviceContext());
257 mCursorScrollAccumulator.reset(getDeviceContext());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700258
259 InputMapper::reset(when);
260}
261
262void CursorInputMapper::process(const RawEvent* rawEvent) {
263 mCursorButtonAccumulator.process(rawEvent);
264 mCursorMotionAccumulator.process(rawEvent);
265 mCursorScrollAccumulator.process(rawEvent);
266
267 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
268 sync(rawEvent->when);
269 }
270}
271
272void CursorInputMapper::sync(nsecs_t when) {
273 int32_t lastButtonState = mButtonState;
274 int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
275 mButtonState = currentButtonState;
276
277 bool wasDown = isPointerDown(lastButtonState);
278 bool down = isPointerDown(currentButtonState);
279 bool downChanged;
280 if (!wasDown && down) {
281 mDownTime = when;
282 downChanged = true;
283 } else if (wasDown && !down) {
284 downChanged = true;
285 } else {
286 downChanged = false;
287 }
288 nsecs_t downTime = mDownTime;
289 bool buttonsChanged = currentButtonState != lastButtonState;
290 int32_t buttonsPressed = currentButtonState & ~lastButtonState;
291 int32_t buttonsReleased = lastButtonState & ~currentButtonState;
292
293 float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
294 float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
295 bool moved = deltaX != 0 || deltaY != 0;
296
297 // Rotate delta according to orientation if needed.
298 if (mParameters.orientationAware && mParameters.hasAssociatedDisplay &&
299 (deltaX != 0.0f || deltaY != 0.0f)) {
300 rotateDelta(mOrientation, &deltaX, &deltaY);
301 }
302
303 // Move the pointer.
304 PointerProperties pointerProperties;
305 pointerProperties.clear();
306 pointerProperties.id = 0;
307 pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
308
309 PointerCoords pointerCoords;
310 pointerCoords.clear();
311
312 float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
313 float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
314 bool scrolled = vscroll != 0 || hscroll != 0;
315
316 mWheelYVelocityControl.move(when, nullptr, &vscroll);
317 mWheelXVelocityControl.move(when, &hscroll, nullptr);
318
319 mPointerVelocityControl.move(when, &deltaX, &deltaY);
320
Chris Ye364fdb52020-08-05 15:07:56 -0700321 int32_t displayId = ADISPLAY_ID_NONE;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700322 float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
323 float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
324 if (mSource == AINPUT_SOURCE_MOUSE) {
325 if (moved || scrolled || buttonsChanged) {
Michael Wrightca5bede2020-07-02 00:00:29 +0100326 mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700327
328 if (moved) {
329 mPointerController->move(deltaX, deltaY);
330 }
331
332 if (buttonsChanged) {
333 mPointerController->setButtonState(currentButtonState);
334 }
335
Michael Wrightca5bede2020-07-02 00:00:29 +0100336 mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700337 }
338
339 mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
340 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
341 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
342 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
343 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
344 displayId = mPointerController->getDisplayId();
Chris Ye364fdb52020-08-05 15:07:56 -0700345 } else if (mSource == AINPUT_SOURCE_MOUSE_RELATIVE) {
346 // Pointer capture mode
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700347 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
348 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
Nathaniel R. Lewis2e8f2d42019-08-21 04:56:10 +0000349 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
350 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700351 }
352
353 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
354
355 // Moving an external trackball or mouse should wake the device.
356 // We don't do this for internal cursor devices to prevent them from waking up
357 // the device in your pocket.
358 // TODO: Use the input device configuration to control this behavior more finely.
359 uint32_t policyFlags = 0;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800360 if ((buttonsPressed || moved || scrolled) && getDeviceContext().isExternal()) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700361 policyFlags |= POLICY_FLAG_WAKE;
362 }
363
364 // Synthesize key down from buttons if needed.
365 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
366 displayId, policyFlags, lastButtonState, currentButtonState);
367
368 // Send motion event.
369 if (downChanged || moved || scrolled || buttonsChanged) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800370 int32_t metaState = getContext()->getGlobalMetaState();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700371 int32_t buttonState = lastButtonState;
372 int32_t motionEventAction;
373 if (downChanged) {
374 motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
375 } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
376 motionEventAction = AMOTION_EVENT_ACTION_MOVE;
377 } else {
378 motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
379 }
380
381 if (buttonsReleased) {
382 BitSet32 released(buttonsReleased);
383 while (!released.isEmpty()) {
384 int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
385 buttonState &= ~actionButton;
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000386 NotifyMotionArgs releaseArgs(getContext()->getNextId(), when, getDeviceId(),
387 mSource, displayId, policyFlags,
388 AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
389 metaState, buttonState, MotionClassification::NONE,
390 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
391 &pointerCoords, mXPrecision, mYPrecision,
392 xCursorPosition, yCursorPosition, downTime,
393 /* videoFrames */ {});
394 getListener()->notifyMotion(&releaseArgs);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700395 }
396 }
397
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000398 NotifyMotionArgs args(getContext()->getNextId(), when, getDeviceId(), mSource, displayId,
399 policyFlags, motionEventAction, 0, 0, metaState, currentButtonState,
400 MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
401 &pointerProperties, &pointerCoords, mXPrecision, mYPrecision,
402 xCursorPosition, yCursorPosition, downTime,
403 /* videoFrames */ {});
404 getListener()->notifyMotion(&args);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700405
406 if (buttonsPressed) {
407 BitSet32 pressed(buttonsPressed);
408 while (!pressed.isEmpty()) {
409 int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
410 buttonState |= actionButton;
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000411 NotifyMotionArgs pressArgs(getContext()->getNextId(), when, getDeviceId(), mSource,
412 displayId, policyFlags,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700413 AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
414 metaState, buttonState, MotionClassification::NONE,
415 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
416 &pointerCoords, mXPrecision, mYPrecision,
417 xCursorPosition, yCursorPosition, downTime,
418 /* videoFrames */ {});
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000419 getListener()->notifyMotion(&pressArgs);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700420 }
421 }
422
423 ALOG_ASSERT(buttonState == currentButtonState);
424
425 // Send hover move after UP to tell the application that the mouse is hovering now.
426 if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000427 NotifyMotionArgs hoverArgs(getContext()->getNextId(), when, getDeviceId(), mSource,
428 displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
429 0, metaState, currentButtonState, MotionClassification::NONE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700430 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
431 &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
432 yCursorPosition, downTime, /* videoFrames */ {});
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000433 getListener()->notifyMotion(&hoverArgs);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700434 }
435
436 // Send scroll events.
437 if (scrolled) {
438 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
439 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
440
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000441 NotifyMotionArgs scrollArgs(getContext()->getNextId(), when, getDeviceId(), mSource,
442 displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
443 metaState, currentButtonState, MotionClassification::NONE,
444 AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
445 &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
446 yCursorPosition, downTime, /* videoFrames */ {});
447 getListener()->notifyMotion(&scrollArgs);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700448 }
449 }
450
451 // Synthesize key up from buttons if needed.
452 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
453 displayId, policyFlags, lastButtonState, currentButtonState);
454
455 mCursorMotionAccumulator.finishSync();
456 mCursorScrollAccumulator.finishSync();
457}
458
459int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
460 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800461 return getDeviceContext().getScanCodeState(scanCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700462 } else {
463 return AKEY_STATE_UNKNOWN;
464 }
465}
466
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700467std::optional<int32_t> CursorInputMapper::getAssociatedDisplayId() {
468 if (mParameters.hasAssociatedDisplay) {
469 if (mParameters.mode == Parameters::MODE_POINTER) {
470 return std::make_optional(mPointerController->getDisplayId());
471 } else {
472 // If the device is orientationAware and not a mouse,
473 // it expects to dispatch events to any display
474 return std::make_optional(ADISPLAY_ID_NONE);
475 }
476 }
477 return std::nullopt;
478}
479
480} // namespace android