blob: b348808b13e6e07167108e16be0d8d62baae9ad1 [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 Vishniakouf4043212023-09-18 19:33:03 -070086/**
87 * Return:
88 * true if the incoming event was correctly tracked,
89 * false if the incoming event should be dropped.
90 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -070091bool InputState::trackMotion(const MotionEntry& entry, int32_t action, int32_t flags) {
Garfield Tane84e6f92019-08-29 17:28:41 -070092 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
93 switch (actionMasked) {
94 case AMOTION_EVENT_ACTION_UP:
95 case AMOTION_EVENT_ACTION_CANCEL: {
Harry Cutts33476232023-01-30 19:57:29 +000096 ssize_t index = findMotionMemento(entry, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -070097 if (index >= 0) {
98 mMotionMementos.erase(mMotionMementos.begin() + index);
99 return true;
100 }
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -0700101
Garfield Tane84e6f92019-08-29 17:28:41 -0700102 return false;
103 }
104
105 case AMOTION_EVENT_ACTION_DOWN: {
Harry Cutts33476232023-01-30 19:57:29 +0000106 ssize_t index = findMotionMemento(entry, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700107 if (index >= 0) {
108 mMotionMementos.erase(mMotionMementos.begin() + index);
109 }
Harry Cutts33476232023-01-30 19:57:29 +0000110 addMotionMemento(entry, flags, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700111 return true;
112 }
113
114 case AMOTION_EVENT_ACTION_POINTER_UP:
115 case AMOTION_EVENT_ACTION_POINTER_DOWN:
116 case AMOTION_EVENT_ACTION_MOVE: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700117 if (entry.source & AINPUT_SOURCE_CLASS_NAVIGATION) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700118 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need
119 // to generate cancellation events for these since they're based in relative rather
120 // than absolute units.
121 return true;
122 }
123
Harry Cutts33476232023-01-30 19:57:29 +0000124 ssize_t index = findMotionMemento(entry, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700125
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700126 if (entry.source & AINPUT_SOURCE_CLASS_JOYSTICK) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700127 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
128 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral.
129 // Any other value and we need to track the motion so we can send cancellation
130 // events for anything generating fallback events (e.g. DPad keys for joystick
131 // movements).
132 if (index >= 0) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700133 if (entry.pointerCoords[0].isEmpty()) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700134 mMotionMementos.erase(mMotionMementos.begin() + index);
135 } else {
136 MotionMemento& memento = mMotionMementos[index];
137 memento.setPointers(entry);
138 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700139 } else if (!entry.pointerCoords[0].isEmpty()) {
Harry Cutts33476232023-01-30 19:57:29 +0000140 addMotionMemento(entry, flags, /*hovering=*/false);
Garfield Tane84e6f92019-08-29 17:28:41 -0700141 }
142
143 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
144 return true;
145 }
Svet Ganov5d3bc372020-01-26 23:11:07 -0800146
Garfield Tane84e6f92019-08-29 17:28:41 -0700147 if (index >= 0) {
148 MotionMemento& memento = mMotionMementos[index];
Svet Ganov5d3bc372020-01-26 23:11:07 -0800149 if (memento.firstNewPointerIdx < 0) {
150 memento.setPointers(entry);
151 return true;
152 }
Garfield Tane84e6f92019-08-29 17:28:41 -0700153 }
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -0700154
Garfield Tane84e6f92019-08-29 17:28:41 -0700155 return false;
156 }
157
158 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
Harry Cutts33476232023-01-30 19:57:29 +0000159 ssize_t index = findMotionMemento(entry, /*hovering=*/true);
Garfield Tane84e6f92019-08-29 17:28:41 -0700160 if (index >= 0) {
161 mMotionMementos.erase(mMotionMementos.begin() + index);
162 return true;
163 }
Siarhei Vishniakouc94dafe2023-05-26 10:24:19 -0700164
Garfield Tane84e6f92019-08-29 17:28:41 -0700165 return false;
166 }
167
168 case AMOTION_EVENT_ACTION_HOVER_ENTER:
169 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
Harry Cutts33476232023-01-30 19:57:29 +0000170 ssize_t index = findMotionMemento(entry, /*hovering=*/true);
Garfield Tane84e6f92019-08-29 17:28:41 -0700171 if (index >= 0) {
172 mMotionMementos.erase(mMotionMementos.begin() + index);
173 }
Harry Cutts33476232023-01-30 19:57:29 +0000174 addMotionMemento(entry, flags, /*hovering=*/true);
Garfield Tane84e6f92019-08-29 17:28:41 -0700175 return true;
176 }
177
178 default:
179 return true;
180 }
181}
182
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700183ssize_t InputState::findKeyMemento(const KeyEntry& entry) const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700184 for (size_t i = 0; i < mKeyMementos.size(); i++) {
185 const KeyMemento& memento = mKeyMementos[i];
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700186 if (memento.deviceId == entry.deviceId && memento.source == entry.source &&
187 memento.displayId == entry.displayId && memento.keyCode == entry.keyCode &&
188 memento.scanCode == entry.scanCode) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700189 return i;
190 }
191 }
192 return -1;
193}
194
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700195ssize_t InputState::findMotionMemento(const MotionEntry& entry, bool hovering) const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700196 for (size_t i = 0; i < mMotionMementos.size(); i++) {
197 const MotionMemento& memento = mMotionMementos[i];
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700198 if (memento.deviceId == entry.deviceId && memento.source == entry.source &&
199 memento.displayId == entry.displayId && memento.hovering == hovering) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700200 return i;
201 }
202 }
203 return -1;
204}
205
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700206void InputState::addKeyMemento(const KeyEntry& entry, int32_t flags) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700207 KeyMemento memento;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700208 memento.deviceId = entry.deviceId;
209 memento.source = entry.source;
210 memento.displayId = entry.displayId;
211 memento.keyCode = entry.keyCode;
212 memento.scanCode = entry.scanCode;
213 memento.metaState = entry.metaState;
Garfield Tane84e6f92019-08-29 17:28:41 -0700214 memento.flags = flags;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700215 memento.downTime = entry.downTime;
216 memento.policyFlags = entry.policyFlags;
Garfield Tane84e6f92019-08-29 17:28:41 -0700217 mKeyMementos.push_back(memento);
218}
219
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700220void InputState::addMotionMemento(const MotionEntry& entry, int32_t flags, bool hovering) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700221 MotionMemento memento;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700222 memento.deviceId = entry.deviceId;
223 memento.source = entry.source;
224 memento.displayId = entry.displayId;
Garfield Tane84e6f92019-08-29 17:28:41 -0700225 memento.flags = flags;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700226 memento.xPrecision = entry.xPrecision;
227 memento.yPrecision = entry.yPrecision;
228 memento.xCursorPosition = entry.xCursorPosition;
229 memento.yCursorPosition = entry.yCursorPosition;
230 memento.downTime = entry.downTime;
Garfield Tane84e6f92019-08-29 17:28:41 -0700231 memento.setPointers(entry);
232 memento.hovering = hovering;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700233 memento.policyFlags = entry.policyFlags;
Garfield Tane84e6f92019-08-29 17:28:41 -0700234 mMotionMementos.push_back(memento);
235}
236
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700237void InputState::MotionMemento::setPointers(const MotionEntry& entry) {
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700238 pointerProperties.clear();
239 pointerCoords.clear();
240
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700241 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
Siarhei Vishniakou82dc0422023-02-17 23:12:52 -0800242 if (MotionEvent::getActionMasked(entry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
243 // In POINTER_UP events, the pointer is leaving. Since the action is not stored,
244 // this departing pointer should not be recorded.
245 const uint8_t actionIndex = MotionEvent::getActionIndex(entry.action);
246 if (i == actionIndex) {
247 continue;
248 }
249 }
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700250 pointerProperties.push_back(entry.pointerProperties[i]);
251 pointerCoords.push_back(entry.pointerCoords[i]);
Garfield Tane84e6f92019-08-29 17:28:41 -0700252 }
253}
254
Svet Ganov5d3bc372020-01-26 23:11:07 -0800255void InputState::MotionMemento::mergePointerStateTo(MotionMemento& other) const {
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700256 for (uint32_t i = 0; i < getPointerCount(); i++) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800257 if (other.firstNewPointerIdx < 0) {
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700258 other.firstNewPointerIdx = other.getPointerCount();
Svet Ganov5d3bc372020-01-26 23:11:07 -0800259 }
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700260 other.pointerProperties.push_back(pointerProperties[i]);
261 other.pointerCoords.push_back(pointerCoords[i]);
Svet Ganov5d3bc372020-01-26 23:11:07 -0800262 }
263}
264
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700265size_t InputState::MotionMemento::getPointerCount() const {
266 return pointerProperties.size();
267}
268
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700269std::vector<std::unique_ptr<EventEntry>> InputState::synthesizeCancelationEvents(
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -0700270 nsecs_t currentTime, const CancelationOptions& options) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700271 std::vector<std::unique_ptr<EventEntry>> events;
Garfield Tane84e6f92019-08-29 17:28:41 -0700272 for (KeyMemento& memento : mKeyMementos) {
273 if (shouldCancelKey(memento, options)) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700274 events.push_back(
275 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId,
276 memento.source, memento.displayId,
277 memento.policyFlags, AKEY_EVENT_ACTION_UP,
278 memento.flags | AKEY_EVENT_FLAG_CANCELED,
279 memento.keyCode, memento.scanCode, memento.metaState,
Harry Cutts33476232023-01-30 19:57:29 +0000280 /*repeatCount=*/0, memento.downTime));
Garfield Tane84e6f92019-08-29 17:28:41 -0700281 }
282 }
283
284 for (const MotionMemento& memento : mMotionMementos) {
285 if (shouldCancelMotion(memento, options)) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000286 if (options.pointerIds == std::nullopt) {
287 const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT
288 : AMOTION_EVENT_ACTION_CANCEL;
Siarhei Vishniakou1ae72f12023-01-29 12:55:30 -0800289 int32_t flags = memento.flags;
290 if (action == AMOTION_EVENT_ACTION_CANCEL) {
291 flags |= AMOTION_EVENT_FLAG_CANCELED;
292 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000293 events.push_back(
294 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
295 memento.deviceId, memento.source,
296 memento.displayId, memento.policyFlags,
Harry Cutts33476232023-01-30 19:57:29 +0000297 action, /*actionButton=*/0, flags, AMETA_NONE,
298 /*buttonState=*/0, MotionClassification::NONE,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000299 AMOTION_EVENT_EDGE_FLAG_NONE,
300 memento.xPrecision, memento.yPrecision,
301 memento.xCursorPosition,
302 memento.yCursorPosition, memento.downTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700303 memento.pointerProperties,
304 memento.pointerCoords));
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000305 } else {
306 std::vector<std::unique_ptr<MotionEntry>> pointerCancelEvents =
307 synthesizeCancelationEventsForPointers(memento, options.pointerIds.value(),
308 currentTime);
309 events.insert(events.end(), std::make_move_iterator(pointerCancelEvents.begin()),
310 std::make_move_iterator(pointerCancelEvents.end()));
311 }
Garfield Tane84e6f92019-08-29 17:28:41 -0700312 }
313 }
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -0700314 return events;
Garfield Tane84e6f92019-08-29 17:28:41 -0700315}
316
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700317std::vector<std::unique_ptr<EventEntry>> InputState::synthesizePointerDownEvents(
318 nsecs_t currentTime) {
319 std::vector<std::unique_ptr<EventEntry>> events;
Svet Ganov5d3bc372020-01-26 23:11:07 -0800320 for (MotionMemento& memento : mMotionMementos) {
Siarhei Vishniakouf4043212023-09-18 19:33:03 -0700321 if (!isFromSource(memento.source, AINPUT_SOURCE_CLASS_POINTER)) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800322 continue;
323 }
324
325 if (memento.firstNewPointerIdx < 0) {
326 continue;
327 }
328
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700329 std::vector<PointerProperties> pointerProperties;
330 std::vector<PointerCoords> pointerCoords;
Svet Ganov5d3bc372020-01-26 23:11:07 -0800331
332 // We will deliver all pointers the target already knows about
333 for (uint32_t i = 0; i < static_cast<uint32_t>(memento.firstNewPointerIdx); i++) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700334 pointerProperties.push_back(memento.pointerProperties[i]);
335 pointerCoords.push_back(memento.pointerCoords[i]);
Svet Ganov5d3bc372020-01-26 23:11:07 -0800336 }
337
338 // We will send explicit events for all pointers the target doesn't know about
339 for (uint32_t i = static_cast<uint32_t>(memento.firstNewPointerIdx);
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700340 i < memento.getPointerCount(); i++) {
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700341 pointerProperties.push_back(memento.pointerProperties[i]);
342 pointerCoords.push_back(memento.pointerCoords[i]);
343
344 const size_t pointerCount = pointerProperties.size();
Svet Ganov5d3bc372020-01-26 23:11:07 -0800345
346 // Down only if the first pointer, pointer down otherwise
347 const int32_t action = (pointerCount <= 1)
348 ? AMOTION_EVENT_ACTION_DOWN
349 : AMOTION_EVENT_ACTION_POINTER_DOWN
350 | (i << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
351
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700352 events.push_back(
353 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
354 memento.deviceId, memento.source,
355 memento.displayId, memento.policyFlags, action,
Harry Cutts33476232023-01-30 19:57:29 +0000356 /*actionButton=*/0, memento.flags, AMETA_NONE,
357 /*buttonState=*/0, MotionClassification::NONE,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700358 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
359 memento.yPrecision, memento.xCursorPosition,
360 memento.yCursorPosition, memento.downTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700361 pointerProperties, pointerCoords));
Svet Ganov5d3bc372020-01-26 23:11:07 -0800362 }
363
364 memento.firstNewPointerIdx = INVALID_POINTER_INDEX;
365 }
366
367 return events;
368}
369
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000370std::vector<std::unique_ptr<MotionEntry>> InputState::synthesizeCancelationEventsForPointers(
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800371 const MotionMemento& memento, std::bitset<MAX_POINTER_ID + 1> pointerIds,
372 nsecs_t currentTime) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000373 std::vector<std::unique_ptr<MotionEntry>> events;
374 std::vector<uint32_t> canceledPointerIndices;
375 std::vector<PointerProperties> pointerProperties(MAX_POINTERS);
376 std::vector<PointerCoords> pointerCoords(MAX_POINTERS);
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700377 for (uint32_t pointerIdx = 0; pointerIdx < memento.getPointerCount(); pointerIdx++) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000378 uint32_t pointerId = uint32_t(memento.pointerProperties[pointerIdx].id);
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700379 pointerProperties[pointerIdx] = memento.pointerProperties[pointerIdx];
380 pointerCoords[pointerIdx] = memento.pointerCoords[pointerIdx];
Siarhei Vishniakou8a878352023-01-30 14:05:01 -0800381 if (pointerIds.test(pointerId)) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000382 canceledPointerIndices.push_back(pointerIdx);
383 }
384 }
385
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700386 if (canceledPointerIndices.size() == memento.getPointerCount()) {
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000387 const int32_t action =
388 memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Siarhei Vishniakou1ae72f12023-01-29 12:55:30 -0800389 int32_t flags = memento.flags;
390 if (action == AMOTION_EVENT_ACTION_CANCEL) {
391 flags |= AMOTION_EVENT_FLAG_CANCELED;
392 }
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000393 events.push_back(
394 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId,
395 memento.source, memento.displayId,
Harry Cutts33476232023-01-30 19:57:29 +0000396 memento.policyFlags, action, /*actionButton=*/0,
397 flags, AMETA_NONE, /*buttonState=*/0,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000398 MotionClassification::NONE,
399 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
400 memento.yPrecision, memento.xCursorPosition,
401 memento.yCursorPosition, memento.downTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700402 memento.pointerProperties, memento.pointerCoords));
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000403 } else {
Siarhei Vishniakou1ae72f12023-01-29 12:55:30 -0800404 // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000405 // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the
406 // previously canceled pointers from PointerProperties and PointerCoords, and update
407 // pointerCount appropriately. For convenience, sort the canceled pointer indices so that we
408 // can just slide the remaining pointers to the beginning of the array when a pointer is
409 // canceled.
410 std::sort(canceledPointerIndices.begin(), canceledPointerIndices.end(),
411 std::greater<uint32_t>());
412
Siarhei Vishniakou47a02a12023-10-18 09:56:00 -0700413 uint32_t pointerCount = memento.getPointerCount();
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000414 for (const uint32_t pointerIdx : canceledPointerIndices) {
415 const int32_t action = pointerCount == 1 ? AMOTION_EVENT_ACTION_CANCEL
416 : AMOTION_EVENT_ACTION_POINTER_UP |
417 (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
418 events.push_back(
419 std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
420 memento.deviceId, memento.source,
421 memento.displayId, memento.policyFlags, action,
Harry Cutts33476232023-01-30 19:57:29 +0000422 /*actionButton=*/0,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000423 memento.flags | AMOTION_EVENT_FLAG_CANCELED,
Harry Cutts33476232023-01-30 19:57:29 +0000424 AMETA_NONE, /*buttonState=*/0,
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000425 MotionClassification::NONE,
426 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
427 memento.yPrecision, memento.xCursorPosition,
428 memento.yCursorPosition, memento.downTime,
Siarhei Vishniakouedd61202023-10-18 11:22:40 -0700429 pointerProperties, pointerCoords));
Vaibhav Devmurariff798f32022-05-09 23:45:04 +0000430
431 // Cleanup pointer information
432 pointerProperties.erase(pointerProperties.begin() + pointerIdx);
433 pointerCoords.erase(pointerCoords.begin() + pointerIdx);
434 pointerCount--;
435 }
436 }
437 return events;
438}
439
Garfield Tane84e6f92019-08-29 17:28:41 -0700440void InputState::clear() {
441 mKeyMementos.clear();
442 mMotionMementos.clear();
443 mFallbackKeys.clear();
444}
445
Svet Ganov5d3bc372020-01-26 23:11:07 -0800446void InputState::mergePointerStateTo(InputState& other) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700447 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800448 MotionMemento& memento = mMotionMementos[i];
449 // Since we support split pointers we need to merge touch events
450 // from the same source + device + screen.
Siarhei Vishniakouf4043212023-09-18 19:33:03 -0700451 if (isFromSource(memento.source, AINPUT_SOURCE_CLASS_POINTER)) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800452 bool merged = false;
453 for (size_t j = 0; j < other.mMotionMementos.size(); j++) {
454 MotionMemento& otherMemento = other.mMotionMementos[j];
Garfield Tane84e6f92019-08-29 17:28:41 -0700455 if (memento.deviceId == otherMemento.deviceId &&
456 memento.source == otherMemento.source &&
457 memento.displayId == otherMemento.displayId) {
Svet Ganov5d3bc372020-01-26 23:11:07 -0800458 memento.mergePointerStateTo(otherMemento);
459 merged = true;
460 break;
Garfield Tane84e6f92019-08-29 17:28:41 -0700461 }
462 }
Svet Ganov5d3bc372020-01-26 23:11:07 -0800463 if (!merged) {
464 memento.firstNewPointerIdx = 0;
465 other.mMotionMementos.push_back(memento);
466 }
Garfield Tane84e6f92019-08-29 17:28:41 -0700467 }
468 }
469}
470
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -0700471std::optional<int32_t> InputState::getFallbackKey(int32_t originalKeyCode) {
472 auto it = mFallbackKeys.find(originalKeyCode);
473 if (it == mFallbackKeys.end()) {
474 return {};
475 }
476 return it->second;
Garfield Tane84e6f92019-08-29 17:28:41 -0700477}
478
479void InputState::setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -0700480 mFallbackKeys.insert_or_assign(originalKeyCode, fallbackKeyCode);
Garfield Tane84e6f92019-08-29 17:28:41 -0700481}
482
483void InputState::removeFallbackKey(int32_t originalKeyCode) {
Siarhei Vishniakou0fe01262023-04-17 08:11:37 -0700484 mFallbackKeys.erase(originalKeyCode);
Garfield Tane84e6f92019-08-29 17:28:41 -0700485}
486
487bool InputState::shouldCancelKey(const KeyMemento& memento, const CancelationOptions& options) {
488 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
489 return false;
490 }
491
492 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
493 return false;
494 }
495
496 if (options.displayId && memento.displayId != options.displayId.value()) {
497 return false;
498 }
499
500 switch (options.mode) {
Michael Wrightfb04fd52022-11-24 22:31:11 +0000501 case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
502 case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700503 return true;
Michael Wrightfb04fd52022-11-24 22:31:11 +0000504 case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700505 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
506 default:
507 return false;
508 }
509}
510
511bool InputState::shouldCancelMotion(const MotionMemento& memento,
512 const CancelationOptions& options) {
513 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
514 return false;
515 }
516
517 if (options.displayId && memento.displayId != options.displayId.value()) {
518 return false;
519 }
520
521 switch (options.mode) {
Michael Wrightfb04fd52022-11-24 22:31:11 +0000522 case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700523 return true;
Michael Wrightfb04fd52022-11-24 22:31:11 +0000524 case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700525 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
Michael Wrightfb04fd52022-11-24 22:31:11 +0000526 case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
Garfield Tane84e6f92019-08-29 17:28:41 -0700527 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
528 default:
529 return false;
530 }
531}
532
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700533std::ostream& operator<<(std::ostream& out, const InputState& state) {
534 if (!state.mMotionMementos.empty()) {
535 out << "mMotionMementos: ";
536 for (const InputState::MotionMemento& memento : state.mMotionMementos) {
537 out << "{deviceId= " << memento.deviceId << ", hovering=" << memento.hovering << "}, ";
538 }
539 }
540 return out;
541}
542
Garfield Tane84e6f92019-08-29 17:28:41 -0700543} // namespace android::inputdispatcher