blob: e6941ef0270d241ff59e73678dde111677fabf26 [file] [log] [blame]
Garfield Tane84e6f92019-08-29 17:28:41 -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
Arthur Hung1a1007b2022-05-11 07:15:01 +000017#include "DebugConfig.h"
Chris Yef59a2f42020-10-16 12:55:26 -070018#include "input/InputDevice.h"
19
Garfield Tane84e6f92019-08-29 17:28:41 -070020#include "InputState.h"
21
Arthur Hung1a1007b2022-05-11 07:15:01 +000022#include <cinttypes>
Garfield Tanff1f1bb2020-01-28 13:24:04 -080023#include "InputDispatcher.h"
24
Garfield Tane84e6f92019-08-29 17:28:41 -070025namespace android::inputdispatcher {
26
Garfield Tanff1f1bb2020-01-28 13:24:04 -080027InputState::InputState(const IdGenerator& idGenerator) : mIdGenerator(idGenerator) {}
Garfield Tane84e6f92019-08-29 17:28:41 -070028
29InputState::~InputState() {}
30
Siarhei Vishniakou7e2f8f12023-07-11 10:51:20 -070031bool InputState::isHovering(DeviceId deviceId, uint32_t source, int32_t displayId) const {
Garfield Tane84e6f92019-08-29 17:28:41 -070032 for (const MotionMemento& memento : mMotionMementos) {
33 if (memento.deviceId == deviceId && memento.source == source &&
34 memento.displayId == displayId && memento.hovering) {
35 return true;
36 }
37 }
38 return false;
39}
40
Siarhei Vishniakoud2770042019-10-29 11:08:14 -070041bool InputState::trackKey(const KeyEntry& entry, int32_t action, int32_t flags) {
Garfield Tane84e6f92019-08-29 17:28:41 -070042 switch (action) {
43 case AKEY_EVENT_ACTION_UP: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -070044 if (entry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -070045 std::erase_if(mFallbackKeys,
46 [&entry](const auto& item) { return item.second == entry.keyCode; });
Garfield Tane84e6f92019-08-29 17:28:41 -070047 }
48 ssize_t index = findKeyMemento(entry);
49 if (index >= 0) {
50 mKeyMementos.erase(mKeyMementos.begin() + index);
51 return true;
52 }
53 /* FIXME: We can't just drop the key up event because that prevents creating
54 * popup windows that are automatically shown when a key is held and then
55 * dismissed when the key is released. The problem is that the popup will
56 * not have received the original key down, so the key up will be considered
57 * to be inconsistent with its observed state. We could perhaps handle this
58 * by synthesizing a key down but that will cause other problems.
59 *
60 * So for now, allow inconsistent key up events to be dispatched.
61 *
62 #if DEBUG_OUTBOUND_EVENT_DETAILS
63 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
64 "keyCode=%d, scanCode=%d",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -070065 entry.deviceId, entry.source, entry.keyCode, entry.scanCode);
Garfield Tane84e6f92019-08-29 17:28:41 -070066 #endif
67 return false;
68 */
69 return true;
70 }
71
72 case AKEY_EVENT_ACTION_DOWN: {
73 ssize_t index = findKeyMemento(entry);
74 if (index >= 0) {
75 mKeyMementos.erase(mKeyMementos.begin() + index);
76 }
77 addKeyMemento(entry, flags);
78 return true;
79 }
80
81 default:
82 return true;
83 }
84}
85
Siarhei Vishniakoud2770042019-10-29 11:08:14 -070086bool InputState::trackMotion(const MotionEntry& entry, int32_t action, int32_t flags) {
Garfield Tane84e6f92019-08-29 17:28:41 -070087 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
88 switch (actionMasked) {
89 case AMOTION_EVENT_ACTION_UP:
90 case AMOTION_EVENT_ACTION_CANCEL: {
Harry Cutts33476232023-01-30 19:57:29 +000091 ssize_t index = findMotionMemento(entry, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -070092 if (index >= 0) {
93 mMotionMementos.erase(mMotionMementos.begin() + index);
94 return true;
95 }
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -070096
Garfield Tane84e6f92019-08-29 17:28:41 -070097 return false;
98 }
99
100 case AMOTION_EVENT_ACTION_DOWN: {
Harry Cutts33476232023-01-30 19:57:29 +0000101 ssize_t index = findMotionMemento(entry, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700102 if (index >= 0) {
103 mMotionMementos.erase(mMotionMementos.begin() + index);
104 }
Harry Cutts33476232023-01-30 19:57:29 +0000105 addMotionMemento(entry, flags, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700106 return true;
107 }
108
109 case AMOTION_EVENT_ACTION_POINTER_UP:
110 case AMOTION_EVENT_ACTION_POINTER_DOWN:
111 case AMOTION_EVENT_ACTION_MOVE: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700112 if (entry.source & AINPUT_SOURCE_CLASS_NAVIGATION) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700113 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need
114 // to generate cancellation events for these since they're based in relative rather
115 // than absolute units.
116 return true;
117 }
118
Harry Cutts33476232023-01-30 19:57:29 +0000119 ssize_t index = findMotionMemento(entry, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700120
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700121 if (entry.source & AINPUT_SOURCE_CLASS_JOYSTICK) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700122 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
123 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral.
124 // Any other value and we need to track the motion so we can send cancellation
125 // events for anything generating fallback events (e.g. DPad keys for joystick
126 // movements).
127 if (index >= 0) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700128 if (entry.pointerCoords[0].isEmpty()) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700129 mMotionMementos.erase(mMotionMementos.begin() + index);
130 } else {
131 MotionMemento& memento = mMotionMementos[index];
132 memento.setPointers(entry);
133 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700134 } else if (!entry.pointerCoords[0].isEmpty()) {
Harry Cutts33476232023-01-30 19:57:29 +0000135 addMotionMemento(entry, flags, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700136 }
137
138 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
139 return true;
140 }
Svet Ganov5d3bc372020-01-26 23:11:07 -0800141
Garfield Tane84e6f92019-08-29 17:28:41 -0700142 if (index >= 0) {
143 MotionMemento& memento = mMotionMementos[index];
Svet Ganov5d3bc372020-01-26 23:11:07 -0800144 if (memento.firstNewPointerIdx < 0) {
145 memento.setPointers(entry);
146 return true;
147 }
Garfield Tane84e6f92019-08-29 17:28:41 -0700148 }
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -0700149
Garfield Tane84e6f92019-08-29 17:28:41 -0700150 return false;
151 }
152
153 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
Harry Cutts33476232023-01-30 19:57:29 +0000154 ssize_t index = findMotionMemento(entry, /*hovering=*/true);
Garfield Tane84e6f92019-08-29 17:28:41 -0700155 if (index >= 0) {
156 mMotionMementos.erase(mMotionMementos.begin() + index);
157 return true;
158 }
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -0700159
Garfield Tane84e6f92019-08-29 17:28:41 -0700160 return false;
161 }
162
163 case AMOTION_EVENT_ACTION_HOVER_ENTER:
164 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
Harry Cutts33476232023-01-30 19:57:29 +0000165 ssize_t index = findMotionMemento(entry, /*hovering=*/true);
Garfield Tane84e6f92019-08-29 17:28:41 -0700166 if (index >= 0) {
167 mMotionMementos.erase(mMotionMementos.begin() + index);
168 }
Harry Cutts33476232023-01-30 19:57:29 +0000169 addMotionMemento(entry, flags, /*hovering=*/true);
Garfield Tane84e6f92019-08-29 17:28:41 -0700170 return true;
171 }
172
173 default:
174 return true;
175 }
176}
177
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700178ssize_t InputState::findKeyMemento(const KeyEntry& entry) const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700179 for (size_t i = 0; i < mKeyMementos.size(); i++) {
180 const KeyMemento& memento = mKeyMementos[i];
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700181 if (memento.deviceId == entry.deviceId && memento.source == entry.source &&
182 memento.displayId == entry.displayId && memento.keyCode == entry.keyCode &&
183 memento.scanCode == entry.scanCode) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700184 return i;
185 }
186 }
187 return -1;
188}
189
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700190ssize_t InputState::findMotionMemento(const MotionEntry& entry, bool hovering) const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700191 for (size_t i = 0; i < mMotionMementos.size(); i++) {
192 const MotionMemento& memento = mMotionMementos[i];
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700193 if (memento.deviceId == entry.deviceId && memento.source == entry.source &&
194 memento.displayId == entry.displayId && memento.hovering == hovering) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700195 return i;
196 }
197 }
198 return -1;
199}
200
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700201void InputState::addKeyMemento(const KeyEntry& entry, int32_t flags) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700202 KeyMemento memento;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700203 memento.deviceId = entry.deviceId;
204 memento.source = entry.source;
205 memento.displayId = entry.displayId;
206 memento.keyCode = entry.keyCode;
207 memento.scanCode = entry.scanCode;
208 memento.metaState = entry.metaState;
Garfield Tane84e6f92019-08-29 17:28:41 -0700209 memento.flags = flags;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700210 memento.downTime = entry.downTime;
211 memento.policyFlags = entry.policyFlags;
Garfield Tane84e6f92019-08-29 17:28:41 -0700212 mKeyMementos.push_back(memento);
213}
214
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700215void InputState::addMotionMemento(const MotionEntry& entry, int32_t flags, bool hovering) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700216 MotionMemento memento;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700217 memento.deviceId = entry.deviceId;
218 memento.source = entry.source;
219 memento.displayId = entry.displayId;
Garfield Tane84e6f92019-08-29 17:28:41 -0700220 memento.flags = flags;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700221 memento.xPrecision = entry.xPrecision;
222 memento.yPrecision = entry.yPrecision;
223 memento.xCursorPosition = entry.xCursorPosition;
224 memento.yCursorPosition = entry.yCursorPosition;
225 memento.downTime = entry.downTime;
Garfield Tane84e6f92019-08-29 17:28:41 -0700226 memento.setPointers(entry);
227 memento.hovering = hovering;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700228 memento.policyFlags = entry.policyFlags;
Garfield Tane84e6f92019-08-29 17:28:41 -0700229 mMotionMementos.push_back(memento);
230}
231
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700232void InputState::MotionMemento::setPointers(const MotionEntry& entry) {
Siarhei Vishniakou82dc0422023-02-17 23:12:52 -0800233 pointerCount = 0;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700234 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Siarhei Vishniakou82dc0422023-02-17 23:12:52 -0800235 if (MotionEvent::getActionMasked(entry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
236 // In POINTER_UP events, the pointer is leaving. Since the action is not stored,
237 // this departing pointer should not be recorded.
238 const uint8_t actionIndex = MotionEvent::getActionIndex(entry.action);
239 if (i == actionIndex) {
240 continue;
241 }
242 }
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700243 pointerProperties[pointerCount] = entry.pointerProperties[i];
244 pointerCoords[pointerCount] = entry.pointerCoords[i];
Siarhei Vishniakou82dc0422023-02-17 23:12:52 -0800245 pointerCount++;
Garfield Tane84e6f92019-08-29 17:28:41 -0700246 }
247}
248
Svet Ganov5d3bc372020-01-26 23:11:07 -0800249void InputState::MotionMemento::mergePointerStateTo(MotionMemento& other) const {
250 for (uint32_t i = 0; i < pointerCount; i++) {
251 if (other.firstNewPointerIdx < 0) {
252 other.firstNewPointerIdx = other.pointerCount;
253 }
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700254 other.pointerProperties[other.pointerCount] = pointerProperties[i];
255 other.pointerCoords[other.pointerCount] = pointerCoords[i];
Svet Ganov5d3bc372020-01-26 23:11:07 -0800256 other.pointerCount++;
257 }
258}
259
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700260std::vector<std::unique_ptr<EventEntry>> InputState::synthesizeCancelationEvents(
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -0700261 nsecs_t currentTime, const CancelationOptions& options) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700262 std::vector<std::unique_ptr<EventEntry>> events;
Garfield Tane84e6f92019-08-29 17:28:41 -0700263 for (KeyMemento& memento : mKeyMementos) {
264 if (shouldCancelKey(memento, options)) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700265 events.push_back(
266 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId,
267 memento.source, memento.displayId,
268 memento.policyFlags, AKEY_EVENT_ACTION_UP,
269 memento.flags | AKEY_EVENT_FLAG_CANCELED,
270 memento.keyCode, memento.scanCode, memento.metaState,
Harry Cutts33476232023-01-30 19:57:29 +0000271 /*repeatCount=*/0, memento.downTime));
Garfield Tane84e6f92019-08-29 17:28:41 -0700272 }
273 }
274
275 for (const MotionMemento& memento : mMotionMementos) {
276 if (shouldCancelMotion(memento, options)) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000277 if (options.pointerIds == std::nullopt) {
278 const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT
279 : AMOTION_EVENT_ACTION_CANCEL;
Siarhei Vishniakou1ae72f12023-01-29 12:55:30 -0800280 int32_t flags = memento.flags;
281 if (action == AMOTION_EVENT_ACTION_CANCEL) {
282 flags |= AMOTION_EVENT_FLAG_CANCELED;
283 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000284 events.push_back(
285 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
286 memento.deviceId, memento.source,
287 memento.displayId, memento.policyFlags,
Harry Cutts33476232023-01-30 19:57:29 +0000288 action, /*actionButton=*/0, flags, AMETA_NONE,
289 /*buttonState=*/0, MotionClassification::NONE,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000290 AMOTION_EVENT_EDGE_FLAG_NONE,
291 memento.xPrecision, memento.yPrecision,
292 memento.xCursorPosition,
293 memento.yCursorPosition, memento.downTime,
294 memento.pointerCount,
295 memento.pointerProperties,
296 memento.pointerCoords));
297 } else {
298 std::vector<std::unique_ptr<MotionEntry>> pointerCancelEvents =
299 synthesizeCancelationEventsForPointers(memento, options.pointerIds.value(),
300 currentTime);
301 events.insert(events.end(), std::make_move_iterator(pointerCancelEvents.begin()),
302 std::make_move_iterator(pointerCancelEvents.end()));
303 }
Garfield Tane84e6f92019-08-29 17:28:41 -0700304 }
305 }
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -0700306 return events;
Garfield Tane84e6f92019-08-29 17:28:41 -0700307}
308
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700309std::vector<std::unique_ptr<EventEntry>> InputState::synthesizePointerDownEvents(
310 nsecs_t currentTime) {
311 std::vector<std::unique_ptr<EventEntry>> events;
Svet Ganov5d3bc372020-01-26 23:11:07 -0800312 for (MotionMemento& memento : mMotionMementos) {
313 if (!(memento.source & AINPUT_SOURCE_CLASS_POINTER)) {
314 continue;
315 }
316
317 if (memento.firstNewPointerIdx < 0) {
318 continue;
319 }
320
321 uint32_t pointerCount = 0;
322 PointerProperties pointerProperties[MAX_POINTERS];
323 PointerCoords pointerCoords[MAX_POINTERS];
324
325 // We will deliver all pointers the target already knows about
326 for (uint32_t i = 0; i < static_cast<uint32_t>(memento.firstNewPointerIdx); i++) {
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700327 pointerProperties[i] = memento.pointerProperties[i];
328 pointerCoords[i] = memento.pointerCoords[i];
Svet Ganov5d3bc372020-01-26 23:11:07 -0800329 pointerCount++;
330 }
331
332 // We will send explicit events for all pointers the target doesn't know about
333 for (uint32_t i = static_cast<uint32_t>(memento.firstNewPointerIdx);
334 i < memento.pointerCount; i++) {
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700335 pointerProperties[i] = memento.pointerProperties[i];
336 pointerCoords[i] = memento.pointerCoords[i];
Svet Ganov5d3bc372020-01-26 23:11:07 -0800337 pointerCount++;
338
339 // Down only if the first pointer, pointer down otherwise
340 const int32_t action = (pointerCount <= 1)
341 ? AMOTION_EVENT_ACTION_DOWN
342 : AMOTION_EVENT_ACTION_POINTER_DOWN
343 | (i << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
344
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700345 events.push_back(
346 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
347 memento.deviceId, memento.source,
348 memento.displayId, memento.policyFlags, action,
Harry Cutts33476232023-01-30 19:57:29 +0000349 /*actionButton=*/0, memento.flags, AMETA_NONE,
350 /*buttonState=*/0, MotionClassification::NONE,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700351 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
352 memento.yPrecision, memento.xCursorPosition,
353 memento.yCursorPosition, memento.downTime,
Prabir Pradhan5beda762021-12-10 09:30:08 +0000354 pointerCount, pointerProperties, pointerCoords));
Svet Ganov5d3bc372020-01-26 23:11:07 -0800355 }
356
357 memento.firstNewPointerIdx = INVALID_POINTER_INDEX;
358 }
359
360 return events;
361}
362
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000363std::vector<std::unique_ptr<MotionEntry>> InputState::synthesizeCancelationEventsForPointers(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800364 const MotionMemento& memento, std::bitset<MAX_POINTER_ID + 1> pointerIds,
365 nsecs_t currentTime) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000366 std::vector<std::unique_ptr<MotionEntry>> events;
367 std::vector<uint32_t> canceledPointerIndices;
368 std::vector<PointerProperties> pointerProperties(MAX_POINTERS);
369 std::vector<PointerCoords> pointerCoords(MAX_POINTERS);
370 for (uint32_t pointerIdx = 0; pointerIdx < memento.pointerCount; pointerIdx++) {
371 uint32_t pointerId = uint32_t(memento.pointerProperties[pointerIdx].id);
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700372 pointerProperties[pointerIdx] = memento.pointerProperties[pointerIdx];
373 pointerCoords[pointerIdx] = memento.pointerCoords[pointerIdx];
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800374 if (pointerIds.test(pointerId)) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000375 canceledPointerIndices.push_back(pointerIdx);
376 }
377 }
378
379 if (canceledPointerIndices.size() == memento.pointerCount) {
380 const int32_t action =
381 memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Siarhei Vishniakou1ae72f12023-01-29 12:55:30 -0800382 int32_t flags = memento.flags;
383 if (action == AMOTION_EVENT_ACTION_CANCEL) {
384 flags |= AMOTION_EVENT_FLAG_CANCELED;
385 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000386 events.push_back(
387 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId,
388 memento.source, memento.displayId,
Harry Cutts33476232023-01-30 19:57:29 +0000389 memento.policyFlags, action, /*actionButton=*/0,
390 flags, AMETA_NONE, /*buttonState=*/0,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000391 MotionClassification::NONE,
392 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
393 memento.yPrecision, memento.xCursorPosition,
394 memento.yCursorPosition, memento.downTime,
395 memento.pointerCount, memento.pointerProperties,
396 memento.pointerCoords));
397 } else {
Siarhei Vishniakou1ae72f12023-01-29 12:55:30 -0800398 // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000399 // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the
400 // previously canceled pointers from PointerProperties and PointerCoords, and update
401 // pointerCount appropriately. For convenience, sort the canceled pointer indices so that we
402 // can just slide the remaining pointers to the beginning of the array when a pointer is
403 // canceled.
404 std::sort(canceledPointerIndices.begin(), canceledPointerIndices.end(),
405 std::greater<uint32_t>());
406
407 uint32_t pointerCount = memento.pointerCount;
408 for (const uint32_t pointerIdx : canceledPointerIndices) {
409 const int32_t action = pointerCount == 1 ? AMOTION_EVENT_ACTION_CANCEL
410 : AMOTION_EVENT_ACTION_POINTER_UP |
411 (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
412 events.push_back(
413 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
414 memento.deviceId, memento.source,
415 memento.displayId, memento.policyFlags, action,
Harry Cutts33476232023-01-30 19:57:29 +0000416 /*actionButton=*/0,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000417 memento.flags | AMOTION_EVENT_FLAG_CANCELED,
Harry Cutts33476232023-01-30 19:57:29 +0000418 AMETA_NONE, /*buttonState=*/0,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000419 MotionClassification::NONE,
420 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
421 memento.yPrecision, memento.xCursorPosition,
422 memento.yCursorPosition, memento.downTime,
423 pointerCount, pointerProperties.data(),
424 pointerCoords.data()));
425
426 // Cleanup pointer information
427 pointerProperties.erase(pointerProperties.begin() + pointerIdx);
428 pointerCoords.erase(pointerCoords.begin() + pointerIdx);
429 pointerCount--;
430 }
431 }
432 return events;
433}
434
Garfield Tane84e6f92019-08-29 17:28:41 -0700435void InputState::clear() {
436 mKeyMementos.clear();
437 mMotionMementos.clear();
438 mFallbackKeys.clear();
439}
440
Svet Ganov5d3bc372020-01-26 23:11:07 -0800441void InputState::mergePointerStateTo(InputState& other) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700442 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800443 MotionMemento& memento = mMotionMementos[i];
444 // Since we support split pointers we need to merge touch events
445 // from the same source + device + screen.
Garfield Tane84e6f92019-08-29 17:28:41 -0700446 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800447 bool merged = false;
448 for (size_t j = 0; j < other.mMotionMementos.size(); j++) {
449 MotionMemento& otherMemento = other.mMotionMementos[j];
Garfield Tane84e6f92019-08-29 17:28:41 -0700450 if (memento.deviceId == otherMemento.deviceId &&
451 memento.source == otherMemento.source &&
452 memento.displayId == otherMemento.displayId) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800453 memento.mergePointerStateTo(otherMemento);
454 merged = true;
455 break;
Garfield Tane84e6f92019-08-29 17:28:41 -0700456 }
457 }
Svet Ganov5d3bc372020-01-26 23:11:07 -0800458 if (!merged) {
459 memento.firstNewPointerIdx = 0;
460 other.mMotionMementos.push_back(memento);
461 }
Garfield Tane84e6f92019-08-29 17:28:41 -0700462 }
463 }
464}
465
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -0700466std::optional<int32_t> InputState::getFallbackKey(int32_t originalKeyCode) {
467 auto it = mFallbackKeys.find(originalKeyCode);
468 if (it == mFallbackKeys.end()) {
469 return {};
470 }
471 return it->second;
Garfield Tane84e6f92019-08-29 17:28:41 -0700472}
473
474void InputState::setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -0700475 mFallbackKeys.insert_or_assign(originalKeyCode, fallbackKeyCode);
Garfield Tane84e6f92019-08-29 17:28:41 -0700476}
477
478void InputState::removeFallbackKey(int32_t originalKeyCode) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -0700479 mFallbackKeys.erase(originalKeyCode);
Garfield Tane84e6f92019-08-29 17:28:41 -0700480}
481
482bool InputState::shouldCancelKey(const KeyMemento& memento, const CancelationOptions& options) {
483 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
484 return false;
485 }
486
487 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
488 return false;
489 }
490
491 if (options.displayId && memento.displayId != options.displayId.value()) {
492 return false;
493 }
494
495 switch (options.mode) {
Michael Wrightfb04fd52022-11-24 22:31:11 +0000496 case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
497 case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700498 return true;
Michael Wrightfb04fd52022-11-24 22:31:11 +0000499 case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700500 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
501 default:
502 return false;
503 }
504}
505
506bool InputState::shouldCancelMotion(const MotionMemento& memento,
507 const CancelationOptions& options) {
508 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
509 return false;
510 }
511
512 if (options.displayId && memento.displayId != options.displayId.value()) {
513 return false;
514 }
515
516 switch (options.mode) {
Michael Wrightfb04fd52022-11-24 22:31:11 +0000517 case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700518 return true;
Michael Wrightfb04fd52022-11-24 22:31:11 +0000519 case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700520 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
Michael Wrightfb04fd52022-11-24 22:31:11 +0000521 case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700522 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
523 default:
524 return false;
525 }
526}
527
528} // namespace android::inputdispatcher