1 /*
2 * Copyright (C) 2010 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
17 #define LOG_TAG "InputDispatcher"
18 #define ATRACE_TAG ATRACE_TAG_INPUT
19
20 #define LOG_NDEBUG 1
21
22 #include <android-base/chrono_utils.h>
23 #include <android-base/logging.h>
24 #include <android-base/properties.h>
25 #include <android-base/stringprintf.h>
26 #include <android/os/IInputConstants.h>
27 #include <binder/Binder.h>
28 #include <com_android_input_flags.h>
29 #include <ftl/enum.h>
30 #include <log/log_event_list.h>
31 #if defined(__ANDROID__)
32 #include <gui/SurfaceComposerClient.h>
33 #endif
34 #include <input/InputDevice.h>
35 #include <input/InputFlags.h>
36 #include <input/PrintTools.h>
37 #include <input/TraceTools.h>
38 #include <openssl/mem.h>
39 #include <private/android_filesystem_config.h>
40 #include <unistd.h>
41 #include <utils/Trace.h>
42
43 #include <cerrno>
44 #include <cinttypes>
45 #include <climits>
46 #include <cstddef>
47 #include <ctime>
48 #include <queue>
49 #include <sstream>
50 #include <variant>
51
52 #include "../InputDeviceMetricsSource.h"
53
54 #include "Connection.h"
55 #include "DebugConfig.h"
56 #include "InputDispatcher.h"
57 #include "InputEventTimeline.h"
58 #include "trace/InputTracer.h"
59 #include "trace/InputTracingPerfettoBackend.h"
60 #include "trace/ThreadedBackend.h"
61
62 #define INDENT " "
63 #define INDENT2 " "
64 #define INDENT3 " "
65 #define INDENT4 " "
66
67 using namespace android::ftl::flag_operators;
68 using android::base::Error;
69 using android::base::HwTimeoutMultiplier;
70 using android::base::Result;
71 using android::base::StringPrintf;
72 using android::gui::DisplayInfo;
73 using android::gui::FocusRequest;
74 using android::gui::TouchOcclusionMode;
75 using android::gui::WindowInfo;
76 using android::gui::WindowInfoHandle;
77 using android::os::InputEventInjectionResult;
78 using android::os::InputEventInjectionSync;
79 namespace input_flags = com::android::input::flags;
80
81 namespace android::inputdispatcher {
82
83 namespace {
84
85 // Input tracing is only available on debuggable builds (userdebug and eng) when the feature
86 // flag is enabled. When the flag is changed, tracing will only be available after reboot.
isInputTracingEnabled()87 bool isInputTracingEnabled() {
88 static const std::string buildType = base::GetProperty("ro.build.type", "user");
89 static const bool isUserdebugOrEng = buildType == "userdebug" || buildType == "eng";
90 return input_flags::enable_input_event_tracing() && isUserdebugOrEng;
91 }
92
93 // Create the input tracing backend that writes to perfetto from a single thread.
createInputTracingBackendIfEnabled()94 std::unique_ptr<trace::InputTracingBackendInterface> createInputTracingBackendIfEnabled() {
95 if (!isInputTracingEnabled()) {
96 return nullptr;
97 }
98 return std::make_unique<trace::impl::ThreadedBackend<trace::impl::PerfettoBackend>>(
99 trace::impl::PerfettoBackend());
100 }
101
102 template <class Entry>
ensureEventTraced(const Entry & entry)103 void ensureEventTraced(const Entry& entry) {
104 if (!entry.traceTracker) {
105 LOG(FATAL) << "Expected event entry to be traced, but it wasn't: " << entry;
106 }
107 }
108
109 // Helper to get a trace tracker from a traced key or motion entry.
getTraceTracker(const EventEntry & entry)110 const std::unique_ptr<trace::EventTrackerInterface>& getTraceTracker(const EventEntry& entry) {
111 switch (entry.type) {
112 case EventEntry::Type::MOTION: {
113 const auto& motion = static_cast<const MotionEntry&>(entry);
114 ensureEventTraced(motion);
115 return motion.traceTracker;
116 }
117 case EventEntry::Type::KEY: {
118 const auto& key = static_cast<const KeyEntry&>(entry);
119 ensureEventTraced(key);
120 return key.traceTracker;
121 }
122 default: {
123 const static std::unique_ptr<trace::EventTrackerInterface> kNullTracker;
124 return kNullTracker;
125 }
126 }
127 }
128
129 // Temporarily releases a held mutex for the lifetime of the instance.
130 // Named to match std::scoped_lock
131 class scoped_unlock {
132 public:
scoped_unlock(std::mutex & mutex)133 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
~scoped_unlock()134 ~scoped_unlock() { mMutex.lock(); }
135
136 private:
137 std::mutex& mMutex;
138 };
139
140 // Default input dispatching timeout if there is no focused application or paused window
141 // from which to determine an appropriate dispatching timeout.
142 const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
143 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
144 HwTimeoutMultiplier());
145
146 // The default minimum time gap between two user activity poke events.
147 const std::chrono::milliseconds DEFAULT_USER_ACTIVITY_POKE_INTERVAL = 100ms;
148
149 const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
150
151 // Log a warning when an event takes longer than this to process, even if an ANR does not occur.
152 constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
153
154 // Log a warning when an interception call takes longer than this to process.
155 constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
156
157 // Number of recent events to keep for debugging purposes.
158 constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
159
160 // Interval at which we should push the atom gathering input event latencies in
161 // LatencyAggregatorWithHistograms
162 constexpr nsecs_t LATENCY_STATISTICS_PUSH_INTERVAL = 6 * 3600 * 1000000000LL; // 6 hours
163
164 // Event log tags. See EventLogTags.logtags for reference.
165 constexpr int LOGTAG_INPUT_INTERACTION = 62000;
166 constexpr int LOGTAG_INPUT_FOCUS = 62001;
167 constexpr int LOGTAG_INPUT_CANCEL = 62003;
168
169 const ui::Transform kIdentityTransform;
170
now()171 inline nsecs_t now() {
172 return systemTime(SYSTEM_TIME_MONOTONIC);
173 }
174
binderToString(const sp<IBinder> & binder)175 inline const std::string binderToString(const sp<IBinder>& binder) {
176 if (binder == nullptr) {
177 return "<null>";
178 }
179 return StringPrintf("%p", binder.get());
180 }
181
uidString(const gui::Uid & uid)182 static std::string uidString(const gui::Uid& uid) {
183 return uid.toString();
184 }
185
checkKeyAction(int32_t action)186 Result<void> checkKeyAction(int32_t action) {
187 switch (action) {
188 case AKEY_EVENT_ACTION_DOWN:
189 case AKEY_EVENT_ACTION_UP:
190 return {};
191 default:
192 return Error() << "Key event has invalid action code " << action;
193 }
194 }
195
validateKeyEvent(int32_t action)196 Result<void> validateKeyEvent(int32_t action) {
197 return checkKeyAction(action);
198 }
199
checkMotionAction(int32_t action,int32_t actionButton,int32_t pointerCount)200 Result<void> checkMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
201 switch (MotionEvent::getActionMasked(action)) {
202 case AMOTION_EVENT_ACTION_DOWN:
203 case AMOTION_EVENT_ACTION_UP: {
204 if (pointerCount != 1) {
205 return Error() << "invalid pointer count " << pointerCount;
206 }
207 return {};
208 }
209 case AMOTION_EVENT_ACTION_MOVE:
210 case AMOTION_EVENT_ACTION_HOVER_ENTER:
211 case AMOTION_EVENT_ACTION_HOVER_MOVE:
212 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
213 if (pointerCount < 1) {
214 return Error() << "invalid pointer count " << pointerCount;
215 }
216 return {};
217 }
218 case AMOTION_EVENT_ACTION_CANCEL:
219 case AMOTION_EVENT_ACTION_OUTSIDE:
220 case AMOTION_EVENT_ACTION_SCROLL:
221 return {};
222 case AMOTION_EVENT_ACTION_POINTER_DOWN:
223 case AMOTION_EVENT_ACTION_POINTER_UP: {
224 const int32_t index = MotionEvent::getActionIndex(action);
225 if (index < 0) {
226 return Error() << "invalid index " << index << " for "
227 << MotionEvent::actionToString(action);
228 }
229 if (index >= pointerCount) {
230 return Error() << "invalid index " << index << " for pointerCount " << pointerCount;
231 }
232 if (pointerCount <= 1) {
233 return Error() << "invalid pointer count " << pointerCount << " for "
234 << MotionEvent::actionToString(action);
235 }
236 return {};
237 }
238 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
239 case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
240 if (actionButton == 0) {
241 return Error() << "action button should be nonzero for "
242 << MotionEvent::actionToString(action);
243 }
244 return {};
245 }
246 default:
247 return Error() << "invalid action " << action;
248 }
249 }
250
millis(std::chrono::nanoseconds t)251 int64_t millis(std::chrono::nanoseconds t) {
252 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
253 }
254
validateMotionEvent(int32_t action,int32_t actionButton,size_t pointerCount,const PointerProperties * pointerProperties)255 Result<void> validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
256 const PointerProperties* pointerProperties) {
257 Result<void> actionCheck = checkMotionAction(action, actionButton, pointerCount);
258 if (!actionCheck.ok()) {
259 return actionCheck;
260 }
261 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
262 return Error() << "Motion event has invalid pointer count " << pointerCount
263 << "; value must be between 1 and " << MAX_POINTERS << ".";
264 }
265 std::bitset<MAX_POINTER_ID + 1> pointerIdBits;
266 for (size_t i = 0; i < pointerCount; i++) {
267 int32_t id = pointerProperties[i].id;
268 if (id < 0 || id > MAX_POINTER_ID) {
269 return Error() << "Motion event has invalid pointer id " << id
270 << "; value must be between 0 and " << MAX_POINTER_ID;
271 }
272 if (pointerIdBits.test(id)) {
273 return Error() << "Motion event has duplicate pointer id " << id;
274 }
275 pointerIdBits.set(id);
276 }
277 return {};
278 }
279
validateInputEvent(const InputEvent & event)280 Result<void> validateInputEvent(const InputEvent& event) {
281 switch (event.getType()) {
282 case InputEventType::KEY: {
283 const KeyEvent& key = static_cast<const KeyEvent&>(event);
284 const int32_t action = key.getAction();
285 return validateKeyEvent(action);
286 }
287 case InputEventType::MOTION: {
288 const MotionEvent& motion = static_cast<const MotionEvent&>(event);
289 const int32_t action = motion.getAction();
290 const size_t pointerCount = motion.getPointerCount();
291 const PointerProperties* pointerProperties = motion.getPointerProperties();
292 const int32_t actionButton = motion.getActionButton();
293 return validateMotionEvent(action, actionButton, pointerCount, pointerProperties);
294 }
295 default: {
296 return {};
297 }
298 }
299 }
300
getPointerIds(const std::vector<PointerProperties> & pointers)301 std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) {
302 std::bitset<MAX_POINTER_ID + 1> pointerIds;
303 for (const PointerProperties& pointer : pointers) {
304 pointerIds.set(pointer.id);
305 }
306 return pointerIds;
307 }
308
dumpRegion(const Region & region)309 std::string dumpRegion(const Region& region) {
310 if (region.isEmpty()) {
311 return "<empty>";
312 }
313
314 std::string dump;
315 bool first = true;
316 Region::const_iterator cur = region.begin();
317 Region::const_iterator const tail = region.end();
318 while (cur != tail) {
319 if (first) {
320 first = false;
321 } else {
322 dump += "|";
323 }
324 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
325 cur++;
326 }
327 return dump;
328 }
329
dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>> & queue,nsecs_t currentTime)330 std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
331 nsecs_t currentTime) {
332 constexpr size_t maxEntries = 50; // max events to print
333 constexpr size_t skipBegin = maxEntries / 2;
334 const size_t skipEnd = queue.size() - maxEntries / 2;
335 // skip from maxEntries / 2 ... size() - maxEntries/2
336 // only print from 0 .. skipBegin and then from skipEnd .. size()
337
338 std::string dump;
339 for (size_t i = 0; i < queue.size(); i++) {
340 const DispatchEntry& entry = *queue[i];
341 if (i >= skipBegin && i < skipEnd) {
342 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
343 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
344 continue;
345 }
346 dump.append(INDENT4);
347 dump += entry.eventEntry->getDescription();
348 dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, age=%" PRId64 "ms", entry.seq,
349 entry.targetFlags.string().c_str(),
350 ns2ms(currentTime - entry.eventEntry->eventTime));
351 if (entry.deliveryTime != 0) {
352 // This entry was delivered, so add information on how long we've been waiting
353 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
354 }
355 dump.append("\n");
356 }
357 return dump;
358 }
359
360 /**
361 * Find the entry in std::unordered_map by key, and return it.
362 * If the entry is not found, return a default constructed entry.
363 *
364 * Useful when the entries are vectors, since an empty vector will be returned
365 * if the entry is not found.
366 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
367 */
368 template <typename K, typename V>
getValueByKey(const std::unordered_map<K,V> & map,K key)369 V getValueByKey(const std::unordered_map<K, V>& map, K key) {
370 auto it = map.find(key);
371 return it != map.end() ? it->second : V{};
372 }
373
haveSameToken(const sp<WindowInfoHandle> & first,const sp<WindowInfoHandle> & second)374 bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
375 if (first == second) {
376 return true;
377 }
378
379 if (first == nullptr || second == nullptr) {
380 return false;
381 }
382
383 return first->getToken() == second->getToken();
384 }
385
haveSameApplicationToken(const WindowInfo * first,const WindowInfo * second)386 bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
387 if (first == nullptr || second == nullptr) {
388 return false;
389 }
390 return first->applicationInfo.token != nullptr &&
391 first->applicationInfo.token == second->applicationInfo.token;
392 }
393
394 template <typename T>
firstMarkedBit(T set)395 size_t firstMarkedBit(T set) {
396 // TODO: replace with std::countr_zero from <bit> when that's available
397 LOG_ALWAYS_FATAL_IF(set.none());
398 size_t i = 0;
399 while (!set.test(i)) {
400 i++;
401 }
402 return i;
403 }
404
createDispatchEntry(const IdGenerator & idGenerator,const InputTarget & inputTarget,std::shared_ptr<const EventEntry> eventEntry,ftl::Flags<InputTarget::Flags> inputTargetFlags,int64_t vsyncId,trace::InputTracerInterface * tracer)405 std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerator,
406 const InputTarget& inputTarget,
407 std::shared_ptr<const EventEntry> eventEntry,
408 ftl::Flags<InputTarget::Flags> inputTargetFlags,
409 int64_t vsyncId,
410 trace::InputTracerInterface* tracer) {
411 const bool zeroCoords = inputTargetFlags.test(InputTarget::Flags::ZERO_COORDS);
412 const sp<WindowInfoHandle> win = inputTarget.windowHandle;
413 const std::optional<int32_t> windowId =
414 win ? std::make_optional(win->getInfo()->id) : std::nullopt;
415 // Assume the only targets that are not associated with a window are global monitors, and use
416 // the system UID for global monitors for tracing purposes.
417 const gui::Uid uid = win ? win->getInfo()->ownerUid : gui::Uid(AID_SYSTEM);
418
419 if (inputTarget.useDefaultPointerTransform() && !zeroCoords) {
420 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
421 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
422 inputTarget.rawTransform,
423 inputTarget.globalScaleFactor, uid, vsyncId,
424 windowId);
425 }
426
427 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
428 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
429
430 std::vector<PointerCoords> pointerCoords{motionEntry.getPointerCount()};
431
432 const ui::Transform* transform = &kIdentityTransform;
433 const ui::Transform* displayTransform = &kIdentityTransform;
434 if (zeroCoords) {
435 std::for_each(pointerCoords.begin(), pointerCoords.end(), [](auto& pc) { pc.clear(); });
436 } else {
437 // Use the first pointer information to normalize all other pointers. This could be any
438 // pointer as long as all other pointers are normalized to the same value and the final
439 // DispatchEntry uses the transform for the normalized pointer.
440 transform =
441 &inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds()));
442 const ui::Transform inverseTransform = transform->inverse();
443 displayTransform = &inputTarget.rawTransform;
444
445 // Iterate through all pointers in the event to normalize against the first.
446 for (size_t i = 0; i < motionEntry.getPointerCount(); i++) {
447 PointerCoords& newCoords = pointerCoords[i];
448 const auto pointerId = motionEntry.pointerProperties[i].id;
449 const ui::Transform& currTransform = inputTarget.getTransformForPointer(pointerId);
450
451 newCoords.copyFrom(motionEntry.pointerCoords[i]);
452 // First, apply the current pointer's transform to update the coordinates into
453 // window space.
454 MotionEvent::calculateTransformedCoordsInPlace(newCoords, motionEntry.source,
455 motionEntry.flags, currTransform);
456 // Next, apply the inverse transform of the normalized coordinates so the
457 // current coordinates are transformed into the normalized coordinate space.
458 MotionEvent::calculateTransformedCoordsInPlace(newCoords, motionEntry.source,
459 motionEntry.flags, inverseTransform);
460 }
461 }
462
463 std::unique_ptr<MotionEntry> combinedMotionEntry =
464 std::make_unique<MotionEntry>(idGenerator.nextId(), motionEntry.injectionState,
465 motionEntry.eventTime, motionEntry.deviceId,
466 motionEntry.source, motionEntry.displayId,
467 motionEntry.policyFlags, motionEntry.action,
468 motionEntry.actionButton, motionEntry.flags,
469 motionEntry.metaState, motionEntry.buttonState,
470 motionEntry.classification, motionEntry.edgeFlags,
471 motionEntry.xPrecision, motionEntry.yPrecision,
472 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
473 motionEntry.downTime, motionEntry.pointerProperties,
474 pointerCoords);
475 if (tracer) {
476 combinedMotionEntry->traceTracker =
477 tracer->traceDerivedEvent(*combinedMotionEntry, *motionEntry.traceTracker);
478 }
479
480 std::unique_ptr<DispatchEntry> dispatchEntry =
481 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
482 *transform, *displayTransform,
483 inputTarget.globalScaleFactor, uid, vsyncId, windowId);
484 return dispatchEntry;
485 }
486
487 template <typename T>
sharedPointersEqual(const std::shared_ptr<T> & lhs,const std::shared_ptr<T> & rhs)488 bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
489 if (lhs == nullptr && rhs == nullptr) {
490 return true;
491 }
492 if (lhs == nullptr || rhs == nullptr) {
493 return false;
494 }
495 return *lhs == *rhs;
496 }
497
createKeyEvent(const KeyEntry & entry)498 KeyEvent createKeyEvent(const KeyEntry& entry) {
499 KeyEvent event;
500 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
501 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
502 entry.repeatCount, entry.downTime, entry.eventTime);
503 return event;
504 }
505
shouldReportMetricsForConnection(const Connection & connection)506 bool shouldReportMetricsForConnection(const Connection& connection) {
507 // Do not keep track of gesture monitors. They receive every event and would disproportionately
508 // affect the statistics.
509 if (connection.monitor) {
510 return false;
511 }
512 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
513 if (!connection.responsive) {
514 return false;
515 }
516 return true;
517 }
518
shouldReportFinishedEvent(const DispatchEntry & dispatchEntry,const Connection & connection)519 bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
520 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
521 const int32_t& inputEventId = eventEntry.id;
522 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
523 return false;
524 }
525 // Only track latency for events that originated from hardware
526 if (eventEntry.isSynthesized()) {
527 return false;
528 }
529 const EventEntry::Type& inputEventEntryType = eventEntry.type;
530 if (inputEventEntryType == EventEntry::Type::KEY) {
531 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
532 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
533 return false;
534 }
535 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
536 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
537 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
538 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
539 return false;
540 }
541 } else {
542 // Not a key or a motion
543 return false;
544 }
545 if (!shouldReportMetricsForConnection(connection)) {
546 return false;
547 }
548 return true;
549 }
550
551 /**
552 * Connection is responsive if it has no events in the waitQueue that are older than the
553 * current time.
554 */
isConnectionResponsive(const Connection & connection)555 bool isConnectionResponsive(const Connection& connection) {
556 const nsecs_t currentTime = now();
557 for (const auto& dispatchEntry : connection.waitQueue) {
558 if (dispatchEntry->timeoutTime < currentTime) {
559 return false;
560 }
561 }
562 return true;
563 }
564
565 // Returns true if the event type passed as argument represents a user activity.
isUserActivityEvent(const EventEntry & eventEntry)566 bool isUserActivityEvent(const EventEntry& eventEntry) {
567 switch (eventEntry.type) {
568 case EventEntry::Type::DEVICE_RESET:
569 case EventEntry::Type::DRAG:
570 case EventEntry::Type::FOCUS:
571 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
572 case EventEntry::Type::SENSOR:
573 case EventEntry::Type::TOUCH_MODE_CHANGED:
574 return false;
575 case EventEntry::Type::KEY:
576 case EventEntry::Type::MOTION:
577 return true;
578 }
579 }
580
581 // Returns true if the given window can accept pointer events at the given display location.
windowAcceptsTouchAt(const WindowInfo & windowInfo,ui::LogicalDisplayId displayId,float x,float y,bool isStylus,const ui::Transform & displayTransform)582 bool windowAcceptsTouchAt(const WindowInfo& windowInfo, ui::LogicalDisplayId displayId, float x,
583 float y, bool isStylus, const ui::Transform& displayTransform) {
584 const auto inputConfig = windowInfo.inputConfig;
585 if (windowInfo.displayId != displayId ||
586 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
587 return false;
588 }
589 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
590 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
591 return false;
592 }
593
594 // Window Manager works in the logical display coordinate space. When it specifies bounds for a
595 // window as (l, t, r, b), the range of x in [l, r) and y in [t, b) are considered to be inside
596 // the window. Points on the right and bottom edges should not be inside the window, so we need
597 // to be careful about performing a hit test when the display is rotated, since the "right" and
598 // "bottom" of the window will be different in the display (un-rotated) space compared to in the
599 // logical display in which WM determined the bounds. Perform the hit test in the logical
600 // display space to ensure these edges are considered correctly in all orientations.
601 const auto touchableRegion = displayTransform.transform(windowInfo.touchableRegion);
602 const auto p = displayTransform.transform(x, y);
603 if (!touchableRegion.contains(std::floor(p.x), std::floor(p.y))) {
604 return false;
605 }
606 return true;
607 }
608
609 // Returns true if the given window's frame can occlude pointer events at the given display
610 // location.
windowOccludesTouchAt(const WindowInfo & windowInfo,ui::LogicalDisplayId displayId,float x,float y,const ui::Transform & displayTransform)611 bool windowOccludesTouchAt(const WindowInfo& windowInfo, ui::LogicalDisplayId displayId, float x,
612 float y, const ui::Transform& displayTransform) {
613 if (windowInfo.displayId != displayId) {
614 return false;
615 }
616 const auto frame = displayTransform.transform(windowInfo.frame);
617 const auto p = floor(displayTransform.transform(x, y));
618 return p.x >= frame.left && p.x < frame.right && p.y >= frame.top && p.y < frame.bottom;
619 }
620
isPointerFromStylus(const MotionEntry & entry,int32_t pointerIndex)621 bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
622 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
623 isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
624 }
625
626 // Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
627 // Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
628 // such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
629 // be sent to such a window, but it is not a foreground event and doesn't use
630 // InputTarget::Flags::FOREGROUND.
canReceiveForegroundTouches(const WindowInfo & info)631 bool canReceiveForegroundTouches(const WindowInfo& info) {
632 // A non-touchable window can still receive touch events (e.g. in the case of
633 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
634 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
635 }
636
isWindowOwnedBy(const sp<WindowInfoHandle> & windowHandle,gui::Pid pid,gui::Uid uid)637 bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, gui::Pid pid, gui::Uid uid) {
638 if (windowHandle == nullptr) {
639 return false;
640 }
641 const WindowInfo* windowInfo = windowHandle->getInfo();
642 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
643 return true;
644 }
645 return false;
646 }
647
648 // Checks targeted injection using the window's owner's uid.
649 // Returns an empty string if an entry can be sent to the given window, or an error message if the
650 // entry is a targeted injection whose uid target doesn't match the window owner.
verifyTargetedInjection(const sp<WindowInfoHandle> & window,const EventEntry & entry)651 std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
652 const EventEntry& entry) {
653 if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
654 // The event was not injected, or the injected event does not target a window.
655 return {};
656 }
657 const auto uid = *entry.injectionState->targetUid;
658 if (window == nullptr) {
659 return StringPrintf("No valid window target for injection into uid %s.",
660 uid.toString().c_str());
661 }
662 if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
663 return StringPrintf("Injected event targeted at uid %s would be dispatched to window '%s' "
664 "owned by uid %s.",
665 uid.toString().c_str(), window->getName().c_str(),
666 window->getInfo()->ownerUid.toString().c_str());
667 }
668 return {};
669 }
670
resolveTouchedPosition(const MotionEntry & entry)671 std::pair<float, float> resolveTouchedPosition(const MotionEntry& entry) {
672 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
673 // Always dispatch mouse events to cursor position.
674 if (isFromMouse) {
675 return {entry.xCursorPosition, entry.yCursorPosition};
676 }
677
678 const int32_t pointerIndex = MotionEvent::getActionIndex(entry.action);
679 return {entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X),
680 entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)};
681 }
682
getDownTime(const EventEntry & eventEntry)683 std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
684 if (eventEntry.type == EventEntry::Type::KEY) {
685 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
686 return keyEntry.downTime;
687 } else if (eventEntry.type == EventEntry::Type::MOTION) {
688 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
689 return motionEntry.downTime;
690 }
691 return std::nullopt;
692 }
693
694 /**
695 * Compare the old touch state to the new touch state, and generate the corresponding touched
696 * windows (== input targets).
697 * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
698 * If the pointer just entered the new window, produce HOVER_ENTER.
699 * For pointers remaining in the window, produce HOVER_MOVE.
700 */
getHoveringWindowsLocked(const TouchState * oldState,const TouchState & newTouchState,const MotionEntry & entry,std::function<void ()> dump)701 std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
702 const TouchState& newTouchState,
703 const MotionEntry& entry,
704 std::function<void()> dump) {
705 const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
706
707 if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
708 // ACTION_SCROLL events should not affect the hovering pointer dispatch
709 return {};
710 }
711 std::vector<TouchedWindow> out;
712
713 // We should consider all hovering pointers here. But for now, just use the first one
714 const PointerProperties& pointer = entry.pointerProperties[0];
715
716 std::set<sp<WindowInfoHandle>> oldWindows;
717 if (oldState != nullptr) {
718 oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
719 }
720
721 std::set<sp<WindowInfoHandle>> newWindows =
722 newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
723
724 // If the pointer is no longer in the new window set, send HOVER_EXIT.
725 for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
726 if (newWindows.find(oldWindow) == newWindows.end()) {
727 TouchedWindow touchedWindow;
728 touchedWindow.windowHandle = oldWindow;
729 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_EXIT;
730 out.push_back(touchedWindow);
731 }
732 }
733
734 for (const sp<WindowInfoHandle>& newWindow : newWindows) {
735 TouchedWindow touchedWindow;
736 touchedWindow.windowHandle = newWindow;
737 if (oldWindows.find(newWindow) == oldWindows.end()) {
738 // Any windows that have this pointer now, and didn't have it before, should get
739 // HOVER_ENTER
740 touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_ENTER;
741 } else {
742 // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
743 if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) {
744 android::base::LogSeverity severity = android::base::LogSeverity::FATAL;
745 if (!input_flags::a11y_crash_on_inconsistent_event_stream() &&
746 entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) {
747 // The Accessibility injected touch exploration event stream
748 // has known inconsistencies, so log ERROR instead of
749 // crashing the device with FATAL.
750 severity = android::base::LogSeverity::ERROR;
751 }
752 dump();
753 LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription();
754 }
755 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
756 }
757 const auto [x, y] = resolveTouchedPosition(entry);
758 touchedWindow.addHoveringPointer(entry.deviceId, pointer, x, y);
759 if (canReceiveForegroundTouches(*newWindow->getInfo())) {
760 touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
761 }
762 out.push_back(touchedWindow);
763 }
764 return out;
765 }
766
767 template <typename T>
operator +=(std::vector<T> & left,const std::vector<T> & right)768 std::vector<T>& operator+=(std::vector<T>& left, const std::vector<T>& right) {
769 left.insert(left.end(), right.begin(), right.end());
770 return left;
771 }
772
773 // Filter windows in a TouchState and targets in a vector to remove untrusted windows/targets from
774 // both.
filterUntrustedTargets(TouchState & touchState,std::vector<InputTarget> & targets)775 void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& targets) {
776 std::erase_if(touchState.windows, [&](const TouchedWindow& window) {
777 if (!window.windowHandle->getInfo()->inputConfig.test(
778 WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
779 // In addition to TouchState, erase this window from the input targets! We don't have a
780 // good way to do this today except by adding a nested loop.
781 // TODO(b/282025641): simplify this code once InputTargets are being identified
782 // separately from TouchedWindows.
783 std::erase_if(targets, [&](const InputTarget& target) {
784 return target.connection->getToken() == window.windowHandle->getToken();
785 });
786 return true;
787 }
788 return false;
789 });
790 }
791
shouldSplitTouch(int32_t source)792 bool shouldSplitTouch(int32_t source) {
793 // We should never split mouse events. This is because the events that are produced by touchpad
794 // are sent to InputDispatcher as two fingers (for example, pinch zoom), but they need to be
795 // dispatched to the same window. In those cases, the behaviour is also slightly different from
796 // default because the events should be sent to the cursor position rather than the x,y values
797 // of each of the fingers.
798 // The "normal" (uncaptured) events produced by touchpad and by mouse have SOURCE_MOUSE.
799 return !isFromSource(source, AINPUT_SOURCE_MOUSE);
800 }
801
validateWindowInfosUpdate(const gui::WindowInfosUpdate & update)802 Result<void> validateWindowInfosUpdate(const gui::WindowInfosUpdate& update) {
803 std::unordered_set<int32_t> windowIds;
804 for (const WindowInfo& info : update.windowInfos) {
805 const auto [_, inserted] = windowIds.insert(info.id);
806 if (!inserted) {
807 return Error() << "Duplicate entry for " << info;
808 }
809 }
810 return {};
811 }
812
getUserActivityEventType(const EventEntry & eventEntry)813 int32_t getUserActivityEventType(const EventEntry& eventEntry) {
814 switch (eventEntry.type) {
815 case EventEntry::Type::KEY: {
816 return USER_ACTIVITY_EVENT_BUTTON;
817 }
818 case EventEntry::Type::MOTION: {
819 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
820 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
821 return USER_ACTIVITY_EVENT_TOUCH;
822 }
823 return USER_ACTIVITY_EVENT_OTHER;
824 }
825 default: {
826 LOG_ALWAYS_FATAL("%s events are not user activity",
827 ftl::enum_string(eventEntry.type).c_str());
828 }
829 }
830 }
831
expandCancellationMode(CancelationOptions::Mode mode)832 std::pair<bool /*cancelPointers*/, bool /*cancelNonPointers*/> expandCancellationMode(
833 CancelationOptions::Mode mode) {
834 switch (mode) {
835 case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
836 return {true, true};
837 case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
838 return {true, false};
839 case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
840 return {false, true};
841 case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS:
842 return {false, true};
843 case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
844 return {true, false};
845 }
846 }
847
848 class ScopedSyntheticEventTracer {
849 public:
ScopedSyntheticEventTracer(std::unique_ptr<trace::InputTracerInterface> & tracer)850 ScopedSyntheticEventTracer(std::unique_ptr<trace::InputTracerInterface>& tracer)
851 : mTracer(tracer), mProcessingTimestamp(now()) {
852 if (mTracer) {
853 mEventTracker = mTracer->createTrackerForSyntheticEvent();
854 }
855 }
856
~ScopedSyntheticEventTracer()857 ~ScopedSyntheticEventTracer() {
858 if (mTracer) {
859 mTracer->eventProcessingComplete(*mEventTracker, mProcessingTimestamp);
860 }
861 }
862
getTracker() const863 const std::unique_ptr<trace::EventTrackerInterface>& getTracker() const {
864 return mEventTracker;
865 }
866
867 private:
868 const std::unique_ptr<trace::InputTracerInterface>& mTracer;
869 std::unique_ptr<trace::EventTrackerInterface> mEventTracker;
870 const nsecs_t mProcessingTimestamp;
871 };
872
873 /**
874 * This is needed to help use "InputEventInjectionResult" with base::Result.
875 */
876 template <typename T>
877 struct EnumErrorWrapper {
878 T mVal;
EnumErrorWrapperandroid::inputdispatcher::__anonf8d2f0b20111::EnumErrorWrapper879 EnumErrorWrapper(T&& e) : mVal(std::forward<T>(e)) {}
operator const T&android::inputdispatcher::__anonf8d2f0b20111::EnumErrorWrapper880 operator const T&() const { return mVal; }
valueandroid::inputdispatcher::__anonf8d2f0b20111::EnumErrorWrapper881 T value() const { return mVal; }
printandroid::inputdispatcher::__anonf8d2f0b20111::EnumErrorWrapper882 std::string print() const { return ftl::enum_string(mVal); }
883 };
884
injectionError(InputEventInjectionResult && e)885 Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInjectionResult&& e) {
886 LOG_ALWAYS_FATAL_IF(e == InputEventInjectionResult::SUCCEEDED);
887 return Error<EnumErrorWrapper<InputEventInjectionResult>>(
888 std::forward<InputEventInjectionResult>(e));
889 }
890
createInputTarget(const std::shared_ptr<Connection> & connection,const sp<android::gui::WindowInfoHandle> & windowHandle,InputTarget::DispatchMode dispatchMode,ftl::Flags<InputTarget::Flags> targetFlags,const ui::Transform & rawTransform,std::optional<nsecs_t> firstDownTimeInTarget)891 InputTarget createInputTarget(const std::shared_ptr<Connection>& connection,
892 const sp<android::gui::WindowInfoHandle>& windowHandle,
893 InputTarget::DispatchMode dispatchMode,
894 ftl::Flags<InputTarget::Flags> targetFlags,
895 const ui::Transform& rawTransform,
896 std::optional<nsecs_t> firstDownTimeInTarget) {
897 LOG_ALWAYS_FATAL_IF(connection == nullptr);
898 InputTarget inputTarget{connection};
899 inputTarget.windowHandle = windowHandle;
900 inputTarget.dispatchMode = dispatchMode;
901 inputTarget.flags = targetFlags;
902 inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
903 inputTarget.rawTransform = rawTransform;
904 inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
905 return inputTarget;
906 }
907
dumpWindowForTouchOcclusion(const WindowInfo & info,bool isTouchedWindow)908 std::string dumpWindowForTouchOcclusion(const WindowInfo& info, bool isTouchedWindow) {
909 return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
910 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
911 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
912 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
913 isTouchedWindow ? "[TOUCHED] " : "", info.packageName.c_str(),
914 info.ownerUid.toString().c_str(), info.id,
915 toString(info.touchOcclusionMode).c_str(), info.alpha, info.frame.left,
916 info.frame.top, info.frame.right, info.frame.bottom,
917 dumpRegion(info.touchableRegion).c_str(), info.name.c_str(),
918 info.inputConfig.string().c_str(), toString(info.token != nullptr),
919 info.applicationInfo.name.c_str(),
920 binderToString(info.applicationInfo.token).c_str());
921 }
922
923 } // namespace
924
925 // --- InputDispatcher ---
926
InputDispatcher(InputDispatcherPolicyInterface & policy)927 InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
928 : InputDispatcher(policy, createInputTracingBackendIfEnabled()) {}
929
InputDispatcher(InputDispatcherPolicyInterface & policy,std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)930 InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
931 std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)
932 : mPolicy(policy),
933 mLooper(sp<Looper>::make(false)),
934 mPendingEvent(nullptr),
935 mLastDropReason(DropReason::NOT_DROPPED),
936 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
937 mWindowInfosVsyncId(-1),
938 mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL),
939 mConnectionManager(mLooper),
940 mTouchStates(mWindowInfos, mConnectionManager),
941 mNextUnblockedEvent(nullptr),
942 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
943 mDispatchEnabled(false),
944 mDispatchFrozen(false),
945 mInputFilterEnabled(false),
946 mFocusedDisplayId(ui::LogicalDisplayId::DEFAULT),
947 mWindowTokenWithPointerCapture(nullptr),
948 mAwaitedApplicationDisplayId(ui::LogicalDisplayId::INVALID),
949 mInputEventTimelineProcessor(
950 input_flags::enable_per_device_input_latency_metrics()
951 ? std::move(std::unique_ptr<InputEventTimelineProcessor>(
952 new LatencyAggregatorWithHistograms()))
953 : std::move(std::unique_ptr<InputEventTimelineProcessor>(
954 new LatencyAggregator()))),
955 mLatencyTracker(*mInputEventTimelineProcessor, mInputDevices) {
956 mReporter = createInputReporter();
957
958 mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
959 #if defined(__ANDROID__)
960 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
961 #endif
962 mKeyRepeatState.lastKeyEntry = nullptr;
963
964 if (traceBackend) {
965 mTracer = std::make_unique<trace::impl::InputTracer>(std::move(traceBackend));
966 }
967
968 mLastUserActivityTimes.fill(0);
969 }
970
~InputDispatcher()971 InputDispatcher::~InputDispatcher() {
972 std::scoped_lock _l(mLock);
973
974 resetKeyRepeatLocked();
975 releasePendingEventLocked();
976 drainInboundQueueLocked();
977 #if defined(__ANDROID__)
978 SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener);
979 #endif
980 mCommandQueue.clear();
981 }
982
start()983 status_t InputDispatcher::start() {
984 if (mThread) {
985 return ALREADY_EXISTS;
986 }
987 mThread = std::make_unique<InputThread>(
988 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); },
989 /*isInCriticalPath=*/true);
990 return OK;
991 }
992
stop()993 status_t InputDispatcher::stop() {
994 if (mThread && mThread->isCallingThread()) {
995 ALOGE("InputDispatcher cannot be stopped from its own thread!");
996 return INVALID_OPERATION;
997 }
998 mThread.reset();
999 return OK;
1000 }
1001
dispatchOnce()1002 void InputDispatcher::dispatchOnce() {
1003 nsecs_t nextWakeupTime = LLONG_MAX;
1004 { // acquire lock
1005 std::scoped_lock _l(mLock);
1006 mDispatcherIsAlive.notify_all();
1007
1008 // Run a dispatch loop if there are no pending commands.
1009 // The dispatch loop might enqueue commands to run afterwards.
1010 if (!haveCommandsLocked()) {
1011 dispatchOnceInnerLocked(/*byref*/ nextWakeupTime);
1012 }
1013
1014 // Run all pending commands if there are any.
1015 // If any commands were run then force the next poll to wake up immediately.
1016 if (runCommandsLockedInterruptable()) {
1017 nextWakeupTime = LLONG_MIN;
1018 }
1019
1020 // If we are still waiting for ack on some events,
1021 // we might have to wake up earlier to check if an app is anr'ing.
1022 const nsecs_t nextAnrCheck = processAnrsLocked();
1023 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
1024
1025 if (mPerDeviceInputLatencyMetricsFlag) {
1026 processLatencyStatisticsLocked();
1027 }
1028
1029 // We are about to enter an infinitely long sleep, because we have no commands or
1030 // pending or queued events
1031 if (nextWakeupTime == LLONG_MAX) {
1032 mDispatcherEnteredIdle.notify_all();
1033 }
1034 } // release lock
1035
1036 // Wait for callback or timeout or wake. (make sure we round up, not down)
1037 nsecs_t currentTime = now();
1038 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
1039 mLooper->pollOnce(timeoutMillis);
1040 }
1041
1042 /**
1043 * Raise ANR if there is no focused window.
1044 * Before the ANR is raised, do a final state check:
1045 * 1. The currently focused application must be the same one we are waiting for.
1046 * 2. Ensure we still don't have a focused window.
1047 */
processNoFocusedWindowAnrLocked()1048 void InputDispatcher::processNoFocusedWindowAnrLocked() {
1049 // Check if the application that we are waiting for is still focused.
1050 std::shared_ptr<InputApplicationHandle> focusedApplication =
1051 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
1052 if (focusedApplication == nullptr ||
1053 focusedApplication->getApplicationToken() !=
1054 mAwaitedFocusedApplication->getApplicationToken()) {
1055 // Unexpected because we should have reset the ANR timer when focused application changed
1056 ALOGE("Waited for a focused window, but focused application has already changed to %s",
1057 focusedApplication->getName().c_str());
1058 return; // The focused application has changed.
1059 }
1060
1061 const sp<WindowInfoHandle>& focusedWindowHandle =
1062 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
1063 if (focusedWindowHandle != nullptr) {
1064 return; // We now have a focused window. No need for ANR.
1065 }
1066 onAnrLocked(mAwaitedFocusedApplication);
1067 }
1068
1069 /**
1070 * Check if any of the connections' wait queues have events that are too old.
1071 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
1072 * Return the time at which we should wake up next.
1073 */
processAnrsLocked()1074 nsecs_t InputDispatcher::processAnrsLocked() {
1075 const nsecs_t currentTime = now();
1076 nsecs_t nextAnrCheck = LLONG_MAX;
1077 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
1078 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
1079 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
1080 processNoFocusedWindowAnrLocked();
1081 mAwaitedFocusedApplication.reset();
1082 mNoFocusedWindowTimeoutTime = std::nullopt;
1083 return LLONG_MIN;
1084 } else {
1085 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
1086 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
1087 }
1088 }
1089
1090 // Check if any connection ANRs are due
1091 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
1092 if (currentTime < nextAnrCheck) { // most likely scenario
1093 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
1094 }
1095
1096 // If we reached here, we have an unresponsive connection.
1097 std::shared_ptr<Connection> connection =
1098 mConnectionManager.getConnection(mAnrTracker.firstToken());
1099 if (connection == nullptr) {
1100 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
1101 // As we no longer have entry for this connection, remove it form Anr tracker to prevent
1102 // samme error being logged multiple times.
1103 mAnrTracker.eraseToken(mAnrTracker.firstToken());
1104 return nextAnrCheck;
1105 }
1106 connection->responsive = false;
1107 // Stop waking up for this unresponsive connection
1108 mAnrTracker.eraseToken(connection->getToken());
1109 onAnrLocked(connection);
1110 return LLONG_MIN;
1111 }
1112
1113 /**
1114 * Check if enough time has passed since the last latency statistics push.
1115 */
processLatencyStatisticsLocked()1116 void InputDispatcher::processLatencyStatisticsLocked() {
1117 const nsecs_t currentTime = now();
1118 // Log the atom recording latency statistics if more than 6 hours passed from the last
1119 // push
1120 if (currentTime - mLastStatisticPushTime >= LATENCY_STATISTICS_PUSH_INTERVAL) {
1121 mInputEventTimelineProcessor->pushLatencyStatistics();
1122 mLastStatisticPushTime = currentTime;
1123 }
1124 }
1125
getDispatchingTimeoutLocked(const std::shared_ptr<Connection> & connection)1126 std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
1127 const std::shared_ptr<Connection>& connection) {
1128 if (connection->monitor) {
1129 return mMonitorDispatchingTimeout;
1130 }
1131 const sp<WindowInfoHandle> window = mWindowInfos.findWindowHandle(connection->getToken());
1132 if (window != nullptr) {
1133 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1134 }
1135 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1136 }
1137
dispatchOnceInnerLocked(nsecs_t & nextWakeupTime)1138 void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) {
1139 nsecs_t currentTime = now();
1140
1141 // Reset the key repeat timer whenever normal dispatch is suspended while the
1142 // device is in a non-interactive state. This is to ensure that we abort a key
1143 // repeat if the device is just coming out of sleep.
1144 if (!mDispatchEnabled) {
1145 resetKeyRepeatLocked();
1146 }
1147
1148 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
1149 if (mDispatchFrozen) {
1150 LOG_IF(INFO, DEBUG_FOCUS) << "Dispatch frozen. Waiting some more.";
1151 return;
1152 }
1153
1154 // Ready to start a new event.
1155 // If we don't already have a pending event, go grab one.
1156 if (!mPendingEvent) {
1157 if (mInboundQueue.empty()) {
1158 // Synthesize a key repeat if appropriate.
1159 if (mKeyRepeatState.lastKeyEntry) {
1160 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
1161 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
1162 } else {
1163 nextWakeupTime = std::min(nextWakeupTime, mKeyRepeatState.nextRepeatTime);
1164 }
1165 }
1166
1167 // Nothing to do if there is no pending event.
1168 if (!mPendingEvent) {
1169 return;
1170 }
1171 } else {
1172 // Inbound queue has at least one entry.
1173 mPendingEvent = mInboundQueue.front();
1174 mInboundQueue.pop_front();
1175 traceInboundQueueLengthLocked();
1176 }
1177
1178 // Poke user activity for this event.
1179 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
1180 pokeUserActivityLocked(*mPendingEvent);
1181 }
1182 }
1183
1184 // Now we have an event to dispatch.
1185 // All events are eventually dequeued and processed this way, even if we intend to drop them.
1186 ALOG_ASSERT(mPendingEvent != nullptr);
1187 bool done = false;
1188 DropReason dropReason = DropReason::NOT_DROPPED;
1189 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
1190 dropReason = DropReason::POLICY;
1191 } else if (!mDispatchEnabled) {
1192 dropReason = DropReason::DISABLED;
1193 }
1194
1195 if (mNextUnblockedEvent == mPendingEvent) {
1196 mNextUnblockedEvent = nullptr;
1197 }
1198
1199 switch (mPendingEvent->type) {
1200 case EventEntry::Type::DEVICE_RESET: {
1201 const DeviceResetEntry& typedEntry =
1202 static_cast<const DeviceResetEntry&>(*mPendingEvent);
1203 done = dispatchDeviceResetLocked(currentTime, typedEntry);
1204 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
1205 break;
1206 }
1207
1208 case EventEntry::Type::FOCUS: {
1209 std::shared_ptr<const FocusEntry> typedEntry =
1210 std::static_pointer_cast<const FocusEntry>(mPendingEvent);
1211 dispatchFocusLocked(currentTime, typedEntry);
1212 done = true;
1213 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
1214 break;
1215 }
1216
1217 case EventEntry::Type::TOUCH_MODE_CHANGED: {
1218 const auto typedEntry = std::static_pointer_cast<const TouchModeEntry>(mPendingEvent);
1219 dispatchTouchModeChangeLocked(currentTime, typedEntry);
1220 done = true;
1221 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
1222 break;
1223 }
1224
1225 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1226 const auto typedEntry =
1227 std::static_pointer_cast<const PointerCaptureChangedEntry>(mPendingEvent);
1228 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
1229 done = true;
1230 break;
1231 }
1232
1233 case EventEntry::Type::DRAG: {
1234 std::shared_ptr<const DragEntry> typedEntry =
1235 std::static_pointer_cast<const DragEntry>(mPendingEvent);
1236 dispatchDragLocked(currentTime, typedEntry);
1237 done = true;
1238 break;
1239 }
1240
1241 case EventEntry::Type::KEY: {
1242 std::shared_ptr<const KeyEntry> keyEntry =
1243 std::static_pointer_cast<const KeyEntry>(mPendingEvent);
1244 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
1245 dropReason = DropReason::STALE;
1246 }
1247 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1248 dropReason = DropReason::BLOCKED;
1249 }
1250 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
1251 break;
1252 }
1253
1254 case EventEntry::Type::MOTION: {
1255 std::shared_ptr<const MotionEntry> motionEntry =
1256 std::static_pointer_cast<const MotionEntry>(mPendingEvent);
1257 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
1258 // The event is stale. However, only drop stale events if there isn't an ongoing
1259 // gesture. That would allow us to complete the processing of the current stroke.
1260 if (!mTouchStates.hasTouchingOrHoveringPointers(motionEntry->displayId,
1261 motionEntry->deviceId)) {
1262 dropReason = DropReason::STALE;
1263 }
1264 }
1265 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1266 if (!isFromSource(motionEntry->source, AINPUT_SOURCE_CLASS_POINTER)) {
1267 // Only drop events that are focus-dispatched.
1268 dropReason = DropReason::BLOCKED;
1269 }
1270 }
1271 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
1272 break;
1273 }
1274
1275 case EventEntry::Type::SENSOR: {
1276 std::shared_ptr<const SensorEntry> sensorEntry =
1277 std::static_pointer_cast<const SensorEntry>(mPendingEvent);
1278
1279 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
1280 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
1281 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
1282 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
1283 dropReason = DropReason::STALE;
1284 }
1285 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
1286 done = true;
1287 break;
1288 }
1289 }
1290
1291 if (done) {
1292 if (dropReason != DropReason::NOT_DROPPED) {
1293 dropInboundEventLocked(*mPendingEvent, dropReason);
1294 }
1295 mLastDropReason = dropReason;
1296
1297 if (mTracer) {
1298 if (auto& traceTracker = getTraceTracker(*mPendingEvent); traceTracker != nullptr) {
1299 mTracer->eventProcessingComplete(*traceTracker, currentTime);
1300 }
1301 }
1302
1303 releasePendingEventLocked();
1304 nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
1305 }
1306 }
1307
isStaleEvent(nsecs_t currentTime,const EventEntry & entry)1308 bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
1309 return mPolicy.isStaleEvent(currentTime, entry.eventTime);
1310 }
1311
1312 /**
1313 * Return true if the events preceding this incoming motion event should be dropped
1314 * Return false otherwise (the default behaviour)
1315 */
shouldPruneInboundQueueLocked(const MotionEntry & motionEntry) const1316 bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) const {
1317 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
1318 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
1319
1320 // Optimize case where the current application is unresponsive and the user
1321 // decides to touch a window in a different application.
1322 // If the application takes too long to catch up then we drop all events preceding
1323 // the touch into the other window.
1324 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
1325 const ui::LogicalDisplayId displayId = motionEntry.displayId;
1326 const auto [x, y] = resolveTouchedPosition(motionEntry);
1327 const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0);
1328
1329 sp<WindowInfoHandle> touchedWindowHandle =
1330 mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
1331 if (touchedWindowHandle != nullptr &&
1332 touchedWindowHandle->getApplicationToken() !=
1333 mAwaitedFocusedApplication->getApplicationToken()) {
1334 // User touched a different application than the one we are waiting on.
1335 ALOGI("Pruning input queue because user touched a different application while waiting "
1336 "for %s",
1337 mAwaitedFocusedApplication->getName().c_str());
1338 return true;
1339 }
1340
1341 // Alternatively, maybe there's a spy window that could handle this event.
1342 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1343 findTouchedSpyWindowsAt(displayId, x, y, isStylus, motionEntry.deviceId,
1344 mWindowInfos);
1345 for (const auto& windowHandle : touchedSpies) {
1346 const std::shared_ptr<Connection> connection =
1347 mConnectionManager.getConnection(windowHandle->getToken());
1348 if (connection != nullptr && connection->responsive) {
1349 // This spy window could take more input. Drop all events preceding this
1350 // event, so that the spy window can get a chance to receive the stream.
1351 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
1352 "responsive spy window that may handle the event.",
1353 mAwaitedFocusedApplication->getName().c_str());
1354 return true;
1355 }
1356 }
1357 }
1358
1359 return false;
1360 }
1361
enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry)1362 bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
1363 bool needWake = mInboundQueue.empty();
1364 mInboundQueue.push_back(std::move(newEntry));
1365 const EventEntry& entry = *(mInboundQueue.back());
1366 traceInboundQueueLengthLocked();
1367
1368 switch (entry.type) {
1369 case EventEntry::Type::KEY: {
1370 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1371 "Unexpected untrusted event.");
1372
1373 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1374 if (mTracer) {
1375 ensureEventTraced(keyEntry);
1376 }
1377
1378 // If a new up event comes in, and the pending event with same key code has been asked
1379 // to try again later because of the policy. We have to reset the intercept key wake up
1380 // time for it may have been handled in the policy and could be dropped.
1381 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1382 mPendingEvent->type == EventEntry::Type::KEY) {
1383 const KeyEntry& pendingKey = static_cast<const KeyEntry&>(*mPendingEvent);
1384 if (pendingKey.keyCode == keyEntry.keyCode &&
1385 pendingKey.interceptKeyResult ==
1386 KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1387 pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
1388 pendingKey.interceptKeyWakeupTime = 0;
1389 needWake = true;
1390 }
1391 }
1392 break;
1393 }
1394
1395 case EventEntry::Type::MOTION: {
1396 LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1397 "Unexpected untrusted event.");
1398 const auto& motionEntry = static_cast<const MotionEntry&>(entry);
1399 if (mTracer) {
1400 ensureEventTraced(motionEntry);
1401 }
1402 if (shouldPruneInboundQueueLocked(motionEntry)) {
1403 mNextUnblockedEvent = mInboundQueue.back();
1404 needWake = true;
1405 }
1406
1407 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
1408 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
1409 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1410 // Prevent waiting too long for unprocessed events: if we have a pending key event,
1411 // and some other events have not yet been processed, the dispatcher will wait for
1412 // these events to be processed before dispatching the key event. This is because
1413 // the unprocessed events may cause the focus to change (for example, by launching a
1414 // new window or tapping a different window). To prevent waiting too long, we force
1415 // the key to be sent to the currently focused window when a new tap comes in.
1416 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1417 "just send the pending key event to the currently focused window.");
1418 mKeyIsWaitingForEventsTimeout = now();
1419 needWake = true;
1420 }
1421 break;
1422 }
1423 case EventEntry::Type::FOCUS: {
1424 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1425 break;
1426 }
1427 case EventEntry::Type::TOUCH_MODE_CHANGED:
1428 case EventEntry::Type::DEVICE_RESET:
1429 case EventEntry::Type::SENSOR:
1430 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1431 case EventEntry::Type::DRAG: {
1432 // nothing to do
1433 break;
1434 }
1435 }
1436
1437 return needWake;
1438 }
1439
addRecentEventLocked(std::shared_ptr<const EventEntry> entry)1440 void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> entry) {
1441 // Do not store sensor event in recent queue to avoid flooding the queue.
1442 if (entry->type != EventEntry::Type::SENSOR) {
1443 mRecentQueue.push_back(entry);
1444 }
1445 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
1446 mRecentQueue.pop_front();
1447 }
1448 }
1449
findTouchedWindowAt(ui::LogicalDisplayId displayId,float x,float y,bool isStylus,const sp<android::gui::WindowInfoHandle> ignoreWindow) const1450 sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findTouchedWindowAt(
1451 ui::LogicalDisplayId displayId, float x, float y, bool isStylus,
1452 const sp<android::gui::WindowInfoHandle> ignoreWindow) const {
1453 // Traverse windows from front to back to find touched window.
1454 const auto& windowHandles = getWindowHandlesForDisplay(displayId);
1455 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1456 if (ignoreWindow && haveSameToken(windowHandle, ignoreWindow)) {
1457 continue;
1458 }
1459
1460 const WindowInfo& info = *windowHandle->getInfo();
1461 if (!info.isSpy() &&
1462 windowAcceptsTouchAt(info, displayId, x, y, isStylus, getDisplayTransform(displayId))) {
1463 return windowHandle;
1464 }
1465 }
1466 return nullptr;
1467 }
1468
findOutsideTargets(ui::LogicalDisplayId displayId,const sp<gui::WindowInfoHandle> & touchedWindow,int32_t pointerId,std::function<void ()> dump)1469 std::vector<InputTarget> InputDispatcher::DispatcherTouchState::findOutsideTargets(
1470 ui::LogicalDisplayId displayId, const sp<gui::WindowInfoHandle>& touchedWindow,
1471 int32_t pointerId, std::function<void()> dump) {
1472 if (touchedWindow == nullptr) {
1473 return {};
1474 }
1475 // Traverse windows from front to back until we encounter the touched window.
1476 std::vector<InputTarget> outsideTargets;
1477 const auto& windowHandles = mWindowInfos.getWindowHandlesForDisplay(displayId);
1478 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1479 if (windowHandle == touchedWindow) {
1480 // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
1481 // below the touched window will not get ACTION_OUTSIDE event.
1482 return outsideTargets;
1483 }
1484
1485 const WindowInfo& info = *windowHandle->getInfo();
1486 if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
1487 std::bitset<MAX_POINTER_ID + 1> pointerIds;
1488 pointerIds.set(pointerId);
1489 addPointerWindowTarget(windowHandle, InputTarget::DispatchMode::OUTSIDE,
1490 ftl::Flags<InputTarget::Flags>(), pointerIds,
1491 /*firstDownTimeInTarget=*/std::nullopt,
1492 /*pointerDisplayId=*/std::nullopt, dump, outsideTargets);
1493 }
1494 }
1495 return outsideTargets;
1496 }
1497
findTouchedSpyWindowsAt(ui::LogicalDisplayId displayId,float x,float y,bool isStylus,DeviceId deviceId,const DispatcherWindowInfo & windowInfos)1498 std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAt(
1499 ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
1500 const DispatcherWindowInfo& windowInfos) {
1501 // Traverse windows from front to back and gather the touched spy windows.
1502 std::vector<sp<WindowInfoHandle>> spyWindows;
1503 const ui::Transform displayTransform = windowInfos.getDisplayTransform(displayId);
1504 const auto& windowHandles = windowInfos.getWindowHandlesForDisplay(displayId);
1505 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1506 const WindowInfo& info = *windowHandle->getInfo();
1507 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, displayTransform)) {
1508 // Skip if the pointer is outside of the window.
1509 continue;
1510 }
1511 if (!info.isSpy()) {
1512 // The first touched non-spy window was found, so return the spy windows touched so far.
1513 return spyWindows;
1514 }
1515 spyWindows.push_back(windowHandle);
1516 }
1517 return spyWindows;
1518 }
1519
dropInboundEventLocked(const EventEntry & entry,DropReason dropReason)1520 void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
1521 const char* reason;
1522 switch (dropReason) {
1523 case DropReason::POLICY:
1524 LOG_IF(INFO, debugInboundEventDetails()) << "Dropped event because policy consumed it.";
1525 reason = "inbound event was dropped because the policy consumed it";
1526 break;
1527 case DropReason::DISABLED:
1528 if (mLastDropReason != DropReason::DISABLED) {
1529 ALOGI("Dropped event because input dispatch is disabled.");
1530 }
1531 reason = "inbound event was dropped because input dispatch is disabled";
1532 break;
1533 case DropReason::BLOCKED:
1534 LOG(INFO) << "Dropping because the current application is not responding and the user "
1535 "has started interacting with a different application: "
1536 << entry.getDescription();
1537 reason = "inbound event was dropped because the current application is not responding "
1538 "and the user has started interacting with a different application";
1539 break;
1540 case DropReason::STALE:
1541 ALOGI("Dropped event because it is stale.");
1542 reason = "inbound event was dropped because it is stale";
1543 break;
1544 case DropReason::NO_POINTER_CAPTURE:
1545 ALOGI("Dropped event because there is no window with Pointer Capture.");
1546 reason = "inbound event was dropped because there is no window with Pointer Capture";
1547 break;
1548 case DropReason::NOT_DROPPED: {
1549 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
1550 return;
1551 }
1552 }
1553
1554 switch (entry.type) {
1555 case EventEntry::Type::KEY: {
1556 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1557 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason,
1558 keyEntry.traceTracker);
1559 options.displayId = keyEntry.displayId;
1560 options.deviceId = keyEntry.deviceId;
1561 synthesizeCancelationEventsForAllConnectionsLocked(options);
1562 break;
1563 }
1564 case EventEntry::Type::MOTION: {
1565 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1566 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
1567 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason,
1568 motionEntry.traceTracker);
1569 options.displayId = motionEntry.displayId;
1570 options.deviceId = motionEntry.deviceId;
1571 synthesizeCancelationEventsForAllConnectionsLocked(options);
1572 } else {
1573 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1574 reason, motionEntry.traceTracker);
1575 options.displayId = motionEntry.displayId;
1576 options.deviceId = motionEntry.deviceId;
1577 synthesizeCancelationEventsForAllConnectionsLocked(options);
1578 }
1579 break;
1580 }
1581 case EventEntry::Type::SENSOR: {
1582 break;
1583 }
1584 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1585 case EventEntry::Type::DRAG: {
1586 break;
1587 }
1588 case EventEntry::Type::FOCUS:
1589 case EventEntry::Type::TOUCH_MODE_CHANGED:
1590 case EventEntry::Type::DEVICE_RESET: {
1591 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
1592 break;
1593 }
1594 }
1595 }
1596
haveCommandsLocked() const1597 bool InputDispatcher::haveCommandsLocked() const {
1598 return !mCommandQueue.empty();
1599 }
1600
runCommandsLockedInterruptable()1601 bool InputDispatcher::runCommandsLockedInterruptable() {
1602 if (mCommandQueue.empty()) {
1603 return false;
1604 }
1605
1606 do {
1607 auto command = std::move(mCommandQueue.front());
1608 mCommandQueue.pop_front();
1609 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1610 command();
1611 } while (!mCommandQueue.empty());
1612 return true;
1613 }
1614
postCommandLocked(Command && command)1615 void InputDispatcher::postCommandLocked(Command&& command) {
1616 mCommandQueue.push_back(command);
1617 }
1618
drainInboundQueueLocked()1619 void InputDispatcher::drainInboundQueueLocked() {
1620 while (!mInboundQueue.empty()) {
1621 std::shared_ptr<const EventEntry> entry = mInboundQueue.front();
1622 mInboundQueue.pop_front();
1623 releaseInboundEventLocked(entry);
1624 }
1625 traceInboundQueueLengthLocked();
1626 }
1627
releasePendingEventLocked()1628 void InputDispatcher::releasePendingEventLocked() {
1629 if (mPendingEvent) {
1630 releaseInboundEventLocked(mPendingEvent);
1631 mPendingEvent = nullptr;
1632 }
1633 }
1634
releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry)1635 void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
1636 const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
1637 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
1638 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "Injected inbound event was dropped.";
1639 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
1640 }
1641 if (entry == mNextUnblockedEvent) {
1642 mNextUnblockedEvent = nullptr;
1643 }
1644 addRecentEventLocked(entry);
1645 }
1646
resetKeyRepeatLocked()1647 void InputDispatcher::resetKeyRepeatLocked() {
1648 if (mKeyRepeatState.lastKeyEntry) {
1649 mKeyRepeatState.lastKeyEntry = nullptr;
1650 }
1651 }
1652
synthesizeKeyRepeatLocked(nsecs_t currentTime)1653 std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1654 std::shared_ptr<const KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
1655
1656 uint32_t policyFlags = entry->policyFlags &
1657 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
1658
1659 std::shared_ptr<KeyEntry> newEntry =
1660 std::make_unique<KeyEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
1661 currentTime, entry->deviceId, entry->source,
1662 entry->displayId, policyFlags, entry->action, entry->flags,
1663 entry->keyCode, entry->scanCode, entry->metaState,
1664 entry->repeatCount + 1, entry->downTime);
1665
1666 newEntry->syntheticRepeat = true;
1667 if (mTracer) {
1668 newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
1669 }
1670
1671 mKeyRepeatState.lastKeyEntry = newEntry;
1672 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
1673 return newEntry;
1674 }
1675
dispatchDeviceResetLocked(nsecs_t currentTime,const DeviceResetEntry & entry)1676 bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1677 const DeviceResetEntry& entry) {
1678 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
1679 << "dispatchDeviceReset - eventTime=" << entry.eventTime
1680 << ", deviceId=" << entry.deviceId;
1681
1682 // Reset key repeating in case a keyboard device was disabled or enabled.
1683 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1684 resetKeyRepeatLocked();
1685 }
1686
1687 ScopedSyntheticEventTracer traceContext(mTracer);
1688 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset",
1689 traceContext.getTracker());
1690 options.deviceId = entry.deviceId;
1691 synthesizeCancelationEventsForAllConnectionsLocked(options);
1692
1693 // Remove all active pointers from this device
1694 mTouchStates.removeAllPointersForDevice(entry.deviceId);
1695 return true;
1696 }
1697
enqueueFocusEventLocked(const sp<IBinder> & windowToken,bool hasFocus,const std::string & reason)1698 void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
1699 const std::string& reason) {
1700 if (mPendingEvent != nullptr) {
1701 // Move the pending event to the front of the queue. This will give the chance
1702 // for the pending event to get dispatched to the newly focused window
1703 mInboundQueue.push_front(mPendingEvent);
1704 mPendingEvent = nullptr;
1705 }
1706
1707 std::unique_ptr<FocusEntry> focusEntry =
1708 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1709 reason);
1710
1711 // This event should go to the front of the queue, but behind all other focus events
1712 // Find the last focus event, and insert right after it
1713 auto it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1714 [](const std::shared_ptr<const EventEntry>& event) {
1715 return event->type == EventEntry::Type::FOCUS;
1716 });
1717
1718 // Maintain the order of focus events. Insert the entry after all other focus events.
1719 mInboundQueue.insert(it.base(), std::move(focusEntry));
1720 }
1721
dispatchFocusLocked(nsecs_t currentTime,std::shared_ptr<const FocusEntry> entry)1722 void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
1723 std::shared_ptr<const FocusEntry> entry) {
1724 std::shared_ptr<Connection> connection =
1725 mConnectionManager.getConnection(entry->connectionToken);
1726 if (connection == nullptr) {
1727 return; // Connection has gone away
1728 }
1729 entry->dispatchInProgress = true;
1730 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1731 connection->getInputChannelName();
1732 std::string reason = std::string("reason=").append(entry->reason);
1733 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
1734 dispatchEventLocked(currentTime, entry, {{connection}});
1735 }
1736
dispatchPointerCaptureChangedLocked(nsecs_t currentTime,const std::shared_ptr<const PointerCaptureChangedEntry> & entry,DropReason & dropReason)1737 void InputDispatcher::dispatchPointerCaptureChangedLocked(
1738 nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
1739 DropReason& dropReason) {
1740 dropReason = DropReason::NOT_DROPPED;
1741
1742 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1743 sp<IBinder> token;
1744
1745 if (entry->pointerCaptureRequest.isEnable()) {
1746 // Enable Pointer Capture.
1747 if (haveWindowWithPointerCapture &&
1748 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1749 // This can happen if pointer capture is disabled and re-enabled before we notify the
1750 // app of the state change, so there is no need to notify the app.
1751 ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1752 return;
1753 }
1754 if (!mCurrentPointerCaptureRequest.isEnable()) {
1755 // This can happen if a window requests capture and immediately releases capture.
1756 ALOGW("No window requested Pointer Capture.");
1757 dropReason = DropReason::NO_POINTER_CAPTURE;
1758 return;
1759 }
1760 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1761 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1762 return;
1763 }
1764
1765 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
1766 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1767 LOG_ALWAYS_FATAL_IF(token != entry->pointerCaptureRequest.window,
1768 "Unexpected requested window for Pointer Capture.");
1769 mWindowTokenWithPointerCapture = token;
1770 } else {
1771 // Disable Pointer Capture.
1772 // We do not check if the sequence number matches for requests to disable Pointer Capture
1773 // for two reasons:
1774 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1775 // to disable capture with the same sequence number: one generated by
1776 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1777 // Capture being disabled in InputReader.
1778 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1779 // actual Pointer Capture state that affects events being generated by input devices is
1780 // in InputReader.
1781 if (!haveWindowWithPointerCapture) {
1782 // Pointer capture was already forcefully disabled because of focus change.
1783 dropReason = DropReason::NOT_DROPPED;
1784 return;
1785 }
1786 token = mWindowTokenWithPointerCapture;
1787 mWindowTokenWithPointerCapture = nullptr;
1788 if (mCurrentPointerCaptureRequest.isEnable()) {
1789 setPointerCaptureLocked(nullptr);
1790 }
1791 }
1792
1793 auto connection = mConnectionManager.getConnection(token);
1794 if (connection == nullptr) {
1795 // Window has gone away, clean up Pointer Capture state.
1796 mWindowTokenWithPointerCapture = nullptr;
1797 if (mCurrentPointerCaptureRequest.isEnable()) {
1798 setPointerCaptureLocked(nullptr);
1799 }
1800 return;
1801 }
1802 entry->dispatchInProgress = true;
1803 dispatchEventLocked(currentTime, entry, {{connection}});
1804
1805 dropReason = DropReason::NOT_DROPPED;
1806 }
1807
dispatchTouchModeChangeLocked(nsecs_t currentTime,const std::shared_ptr<const TouchModeEntry> & entry)1808 void InputDispatcher::dispatchTouchModeChangeLocked(
1809 nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
1810 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1811 mWindowInfos.getWindowHandlesForDisplay(entry->displayId);
1812 if (windowHandles.empty()) {
1813 return;
1814 }
1815 const std::vector<InputTarget> inputTargets =
1816 getInputTargetsFromWindowHandlesLocked(windowHandles);
1817 if (inputTargets.empty()) {
1818 return;
1819 }
1820 entry->dispatchInProgress = true;
1821 dispatchEventLocked(currentTime, entry, inputTargets);
1822 }
1823
getInputTargetsFromWindowHandlesLocked(const std::vector<sp<WindowInfoHandle>> & windowHandles) const1824 std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1825 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1826 std::vector<InputTarget> inputTargets;
1827 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1828 const sp<IBinder>& token = handle->getToken();
1829 if (token == nullptr) {
1830 continue;
1831 }
1832 std::shared_ptr<Connection> connection = mConnectionManager.getConnection(token);
1833 if (connection == nullptr) {
1834 continue; // Connection has gone away
1835 }
1836 inputTargets.emplace_back(connection);
1837 }
1838 return inputTargets;
1839 }
1840
dispatchKeyLocked(nsecs_t currentTime,std::shared_ptr<const KeyEntry> entry,DropReason * dropReason,nsecs_t & nextWakeupTime)1841 bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
1842 DropReason* dropReason, nsecs_t& nextWakeupTime) {
1843 // Preprocessing.
1844 if (!entry->dispatchInProgress) {
1845 if (!entry->syntheticRepeat && entry->action == AKEY_EVENT_ACTION_DOWN &&
1846 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1847 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1848 if (mKeyRepeatState.lastKeyEntry &&
1849 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
1850 // We have seen two identical key downs in a row which indicates that the device
1851 // driver is automatically generating key repeats itself. We take note of the
1852 // repeat here, but we disable our own next key repeat timer since it is clear that
1853 // we will not need to synthesize key repeats ourselves.
1854 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1855 // Make sure we don't get key down from a different device. If a different
1856 // device Id has same key pressed down, the new device Id will replace the
1857 // current one to hold the key repeat with repeat count reset.
1858 // In the future when got a KEY_UP on the device id, drop it and do not
1859 // stop the key repeat on current device.
1860 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1861 resetKeyRepeatLocked();
1862 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
1863 } else {
1864 // Not a repeat. Save key down state in case we do see a repeat later.
1865 resetKeyRepeatLocked();
1866 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1867 }
1868 mKeyRepeatState.lastKeyEntry = entry;
1869 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1870 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
1871 // The key on device 'deviceId' is still down, do not stop key repeat
1872 LOG_IF(INFO, debugInboundEventDetails())
1873 << "deviceId=" << entry->deviceId << " got KEY_UP as stale";
1874 } else if (!entry->syntheticRepeat) {
1875 resetKeyRepeatLocked();
1876 }
1877
1878 if (entry->repeatCount == 1) {
1879 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1880 } else {
1881 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1882 }
1883
1884 entry->dispatchInProgress = true;
1885
1886 logOutboundKeyDetails("dispatchKey - ", *entry);
1887 }
1888
1889 // Handle case where the policy asked us to try again later last time.
1890 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1891 if (currentTime < entry->interceptKeyWakeupTime) {
1892 nextWakeupTime = std::min(nextWakeupTime, entry->interceptKeyWakeupTime);
1893 return false; // wait until next wakeup
1894 }
1895 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
1896 entry->interceptKeyWakeupTime = 0;
1897 }
1898
1899 // Give the policy a chance to intercept the key.
1900 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
1901 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
1902 sp<IBinder> focusedWindowToken =
1903 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
1904
1905 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1906 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1907 };
1908 postCommandLocked(std::move(command));
1909 return false; // wait for the command to run
1910 } else {
1911 entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
1912 }
1913 } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
1914 if (*dropReason == DropReason::NOT_DROPPED) {
1915 *dropReason = DropReason::POLICY;
1916 }
1917 }
1918
1919 // Clean up if dropping the event.
1920 if (*dropReason != DropReason::NOT_DROPPED) {
1921 setInjectionResult(*entry,
1922 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1923 : InputEventInjectionResult::FAILED);
1924 mReporter->reportDroppedKey(entry->id);
1925 // Poke user activity for consumed keys, as it may have not been reported due to
1926 // the focused window requesting user activity to be disabled
1927 if (*dropReason == DropReason::POLICY &&
1928 mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
1929 pokeUserActivityLocked(*entry);
1930 }
1931 return true;
1932 }
1933
1934 // Identify targets.
1935 Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
1936 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
1937
1938 if (!result.ok()) {
1939 if (result.error().code() == InputEventInjectionResult::PENDING) {
1940 return false;
1941 }
1942 setInjectionResult(*entry, result.error().code());
1943 return true;
1944 }
1945 sp<WindowInfoHandle>& focusedWindow = *result;
1946 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1947
1948 setInjectionResult(*entry, InputEventInjectionResult::SUCCEEDED);
1949
1950 std::vector<InputTarget> inputTargets;
1951 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1952 InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
1953
1954 // Add monitor channels from event's or focused display.
1955 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
1956
1957 if (mTracer) {
1958 ensureEventTraced(*entry);
1959 for (const auto& target : inputTargets) {
1960 mTracer->dispatchToTargetHint(*entry->traceTracker, target);
1961 }
1962 }
1963
1964 if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::FALLBACK) {
1965 findAndDispatchFallbackEvent(currentTime, entry, inputTargets);
1966 // Drop the key.
1967 return true;
1968 }
1969
1970 // Dispatch the key.
1971 dispatchEventLocked(currentTime, entry, inputTargets);
1972 return true;
1973 }
1974
findAndDispatchFallbackEvent(nsecs_t currentTime,std::shared_ptr<const KeyEntry> entry,std::vector<InputTarget> & inputTargets)1975 void InputDispatcher::findAndDispatchFallbackEvent(nsecs_t currentTime,
1976 std::shared_ptr<const KeyEntry> entry,
1977 std::vector<InputTarget>& inputTargets) {
1978 // Find the fallback associated with the incoming key event and dispatch it.
1979 KeyEvent event = createKeyEvent(*entry);
1980 const int32_t originalKeyCode = entry->keyCode;
1981
1982 // Fetch the fallback event.
1983 KeyCharacterMap::FallbackAction fallback;
1984 for (const InputDeviceInfo& deviceInfo : mInputDevices) {
1985 if (deviceInfo.getId() == entry->deviceId) {
1986 const KeyCharacterMap* map = deviceInfo.getKeyCharacterMap();
1987
1988 LOG_ALWAYS_FATAL_IF(map == nullptr, "No KeyCharacterMap for device %d",
1989 entry->deviceId);
1990 map->getFallbackAction(entry->keyCode, entry->metaState, &fallback);
1991 break;
1992 }
1993 }
1994
1995 if (fallback.keyCode == AKEYCODE_UNKNOWN) {
1996 // No fallback detected.
1997 return;
1998 }
1999
2000 std::unique_ptr<KeyEntry> fallbackKeyEntry =
2001 std::make_unique<KeyEntry>(mIdGenerator.nextId(), entry->injectionState,
2002 event.getEventTime(), event.getDeviceId(), event.getSource(),
2003 event.getDisplayId(), entry->policyFlags, entry->action,
2004 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
2005 fallback.keyCode, event.getScanCode(), /*metaState=*/0,
2006 event.getRepeatCount(), event.getDownTime());
2007
2008 if (mTracer) {
2009 fallbackKeyEntry->traceTracker =
2010 mTracer->traceDerivedEvent(*fallbackKeyEntry, *entry->traceTracker);
2011 }
2012
2013 for (const InputTarget& inputTarget : inputTargets) {
2014 std::shared_ptr<Connection> connection = inputTarget.connection;
2015 if (!connection->responsive || (connection->status != Connection::Status::NORMAL)) {
2016 return;
2017 }
2018
2019 connection->inputState.setFallbackKey(originalKeyCode, fallback.keyCode);
2020 if (entry->action == AKEY_EVENT_ACTION_UP) {
2021 connection->inputState.removeFallbackKey(originalKeyCode);
2022 }
2023
2024 if (mTracer) {
2025 mTracer->dispatchToTargetHint(*fallbackKeyEntry->traceTracker, inputTarget);
2026 }
2027 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
2028 std::move(fallbackKeyEntry), inputTarget);
2029 }
2030 }
2031
logOutboundKeyDetails(const char * prefix,const KeyEntry & entry)2032 void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
2033 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
2034 << prefix << "eventTime=" << entry.eventTime << ", deviceId=" << entry.deviceId
2035 << ", source=0x" << std::hex << entry.source
2036 << ", displayId=" << entry.displayId.toString() << ", policyFlags=0x"
2037 << entry.policyFlags << ", action=0x" << entry.action << ", flags=0x" << entry.flags
2038 << ", keyCode=0x" << entry.keyCode << ", scanCode=0x" << entry.scanCode
2039 << ", metaState=0x" << entry.metaState << ", repeatCount=" << std::dec
2040 << entry.repeatCount << ", downTime=" << entry.downTime;
2041 }
2042
dispatchSensorLocked(nsecs_t currentTime,const std::shared_ptr<const SensorEntry> & entry,DropReason * dropReason,nsecs_t & nextWakeupTime)2043 void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
2044 const std::shared_ptr<const SensorEntry>& entry,
2045 DropReason* dropReason, nsecs_t& nextWakeupTime) {
2046 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
2047 << "notifySensorEvent eventTime=" << entry->eventTime
2048 << ", hwTimestamp=" << entry->hwTimestamp << ", deviceId=" << entry->deviceId
2049 << ", source=0x" << std::hex << entry->source << std::dec
2050 << ", sensorType=" << ftl::enum_string(entry->sensorType);
2051 auto command = [this, entry]() REQUIRES(mLock) {
2052 scoped_unlock unlock(mLock);
2053
2054 if (entry->accuracyChanged) {
2055 mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
2056 }
2057 mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
2058 entry->hwTimestamp, entry->values);
2059 };
2060 postCommandLocked(std::move(command));
2061 }
2062
flushSensor(int deviceId,InputDeviceSensorType sensorType)2063 bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
2064 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
2065 << "flushSensor deviceId=" << deviceId
2066 << ", sensorType=" << ftl::enum_string(sensorType).c_str();
2067 { // acquire lock
2068 std::scoped_lock _l(mLock);
2069
2070 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
2071 std::shared_ptr<const EventEntry> entry = *it;
2072 if (entry->type == EventEntry::Type::SENSOR) {
2073 it = mInboundQueue.erase(it);
2074 releaseInboundEventLocked(entry);
2075 }
2076 }
2077 }
2078 return true;
2079 }
2080
dispatchMotionLocked(nsecs_t currentTime,std::shared_ptr<const MotionEntry> entry,DropReason * dropReason,nsecs_t & nextWakeupTime)2081 bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
2082 std::shared_ptr<const MotionEntry> entry,
2083 DropReason* dropReason, nsecs_t& nextWakeupTime) {
2084 ATRACE_CALL();
2085 // Preprocessing.
2086 if (!entry->dispatchInProgress) {
2087 entry->dispatchInProgress = true;
2088
2089 logOutboundMotionDetails("dispatchMotion - ", *entry);
2090 }
2091
2092 // Clean up if dropping the event.
2093 if (*dropReason != DropReason::NOT_DROPPED) {
2094 setInjectionResult(*entry,
2095 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
2096 : InputEventInjectionResult::FAILED);
2097 return true;
2098 }
2099
2100 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
2101
2102 // Identify targets.
2103 std::vector<InputTarget> inputTargets;
2104
2105 InputEventInjectionResult injectionResult;
2106 if (isPointerEvent) {
2107 // Pointer event. (eg. touchscreen)
2108
2109 if (mDragState &&
2110 (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2111 // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
2112 pilferPointersLocked(mDragState->dragWindow->getToken());
2113 }
2114
2115 Result<std::vector<InputTarget>, InputEventInjectionResult> result =
2116 mTouchStates
2117 .findTouchedWindowTargets(currentTime, *entry,
2118 mDragState ? mDragState->dragWindow : nullptr,
2119 std::bind_front(&InputDispatcher::
2120 addDragEventLocked,
2121 this),
2122 std::bind_front(&InputDispatcher::
2123 logDispatchStateLocked,
2124 this));
2125
2126 if (result.ok()) {
2127 inputTargets = std::move(*result);
2128 injectionResult = InputEventInjectionResult::SUCCEEDED;
2129 } else {
2130 injectionResult = result.error().code();
2131 }
2132 } else {
2133 // Non touch event. (eg. trackball)
2134 Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
2135 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
2136 if (result.ok()) {
2137 sp<WindowInfoHandle>& focusedWindow = *result;
2138 LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
2139 addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
2140 InputTarget::Flags::FOREGROUND, getDownTime(*entry),
2141 inputTargets);
2142 injectionResult = InputEventInjectionResult::SUCCEEDED;
2143 } else {
2144 injectionResult = result.error().code();
2145 }
2146 }
2147 if (injectionResult == InputEventInjectionResult::PENDING) {
2148 return false;
2149 }
2150
2151 setInjectionResult(*entry, injectionResult);
2152 if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
2153 return true;
2154 }
2155 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
2156 CancelationOptions::Mode mode(
2157 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
2158 : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
2159 CancelationOptions options(mode, "input event injection failed", entry->traceTracker);
2160 options.displayId = entry->displayId;
2161 synthesizeCancelationEventsForMonitorsLocked(options);
2162 return true;
2163 }
2164
2165 // Add monitor channels from event's or focused display.
2166 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
2167
2168 if (mTracer) {
2169 ensureEventTraced(*entry);
2170 for (const auto& target : inputTargets) {
2171 mTracer->dispatchToTargetHint(*entry->traceTracker, target);
2172 }
2173 }
2174
2175 // Dispatch the motion.
2176 dispatchEventLocked(currentTime, entry, inputTargets);
2177 return true;
2178 }
2179
enqueueDragEventLocked(const sp<WindowInfoHandle> & windowHandle,bool isExiting,const int32_t rawX,const int32_t rawY)2180 void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
2181 bool isExiting, const int32_t rawX,
2182 const int32_t rawY) {
2183 const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
2184 std::unique_ptr<DragEntry> dragEntry =
2185 std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
2186 isExiting, xy.x, xy.y);
2187
2188 enqueueInboundEventLocked(std::move(dragEntry));
2189 }
2190
dispatchDragLocked(nsecs_t currentTime,std::shared_ptr<const DragEntry> entry)2191 void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
2192 std::shared_ptr<const DragEntry> entry) {
2193 std::shared_ptr<Connection> connection =
2194 mConnectionManager.getConnection(entry->connectionToken);
2195 if (connection == nullptr) {
2196 return; // Connection has gone away
2197 }
2198 entry->dispatchInProgress = true;
2199 dispatchEventLocked(currentTime, entry, {{connection}});
2200 }
2201
logOutboundMotionDetails(const char * prefix,const MotionEntry & entry)2202 void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
2203 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
2204 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%s, policyFlags=0x%x, "
2205 "action=%s, actionButton=0x%x, flags=0x%x, "
2206 "metaState=0x%x, buttonState=0x%x, downTime=%" PRId64,
2207 prefix, entry.eventTime, entry.deviceId,
2208 inputEventSourceToString(entry.source).c_str(), entry.displayId.toString().c_str(),
2209 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
2210 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.downTime);
2211
2212 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
2213 ALOGD(" Pointer %d: id=%d, toolType=%s, "
2214 "x=%f, y=%f, pressure=%f, size=%f, "
2215 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
2216 i, entry.pointerProperties[i].id,
2217 ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
2218 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2219 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2220 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2221 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2222 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2223 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2224 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2225 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2226 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2227 }
2228 }
2229 }
2230
dispatchEventLocked(nsecs_t currentTime,std::shared_ptr<const EventEntry> eventEntry,const std::vector<InputTarget> & inputTargets)2231 void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
2232 std::shared_ptr<const EventEntry> eventEntry,
2233 const std::vector<InputTarget>& inputTargets) {
2234 ATRACE_CALL();
2235 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "dispatchEventToCurrentInputTargets";
2236
2237 processInteractionsLocked(*eventEntry, inputTargets);
2238
2239 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2240
2241 pokeUserActivityLocked(*eventEntry);
2242
2243 for (const InputTarget& inputTarget : inputTargets) {
2244 std::shared_ptr<Connection> connection = inputTarget.connection;
2245 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
2246 }
2247 }
2248
cancelEventsForAnrLocked(const std::shared_ptr<Connection> & connection)2249 void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
2250 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2251 // If the policy decides to close the app, we will get a channel removal event via
2252 // unregisterInputChannel, and will clean up the connection that way. We are already not
2253 // sending new pointers to the connection when it blocked, but focused events will continue to
2254 // pile up.
2255 ALOGW("Canceling events for %s because it is unresponsive",
2256 connection->getInputChannelName().c_str());
2257 if (connection->status != Connection::Status::NORMAL) {
2258 return;
2259 }
2260 ScopedSyntheticEventTracer traceContext(mTracer);
2261 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
2262 "application not responding", traceContext.getTracker());
2263
2264 sp<WindowInfoHandle> windowHandle;
2265 if (!connection->monitor) {
2266 windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
2267 if (windowHandle == nullptr) {
2268 // The window that is receiving this ANR was removed, so there is no need to generate
2269 // cancellations, because the cancellations would have already been generated when
2270 // the window was removed.
2271 return;
2272 }
2273 }
2274 synthesizeCancelationEventsForConnectionLocked(connection, options, windowHandle);
2275 }
2276
resetNoFocusedWindowTimeoutLocked()2277 void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
2278 LOG_IF(INFO, DEBUG_FOCUS) << "Resetting ANR timeouts.";
2279
2280 // Reset input target wait timeout.
2281 mNoFocusedWindowTimeoutTime = std::nullopt;
2282 mAwaitedFocusedApplication.reset();
2283 }
2284
2285 /**
2286 * Get the display id that the given event should go to. If this event specifies a valid display id,
2287 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2288 * Focused display is the display that the user most recently interacted with.
2289 */
getTargetDisplayId(const EventEntry & entry)2290 ui::LogicalDisplayId InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
2291 ui::LogicalDisplayId displayId{ui::LogicalDisplayId::INVALID};
2292 switch (entry.type) {
2293 case EventEntry::Type::KEY: {
2294 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2295 displayId = keyEntry.displayId;
2296 break;
2297 }
2298 case EventEntry::Type::MOTION: {
2299 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2300 displayId = motionEntry.displayId;
2301 break;
2302 }
2303 case EventEntry::Type::TOUCH_MODE_CHANGED:
2304 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2305 case EventEntry::Type::FOCUS:
2306 case EventEntry::Type::DEVICE_RESET:
2307 case EventEntry::Type::SENSOR:
2308 case EventEntry::Type::DRAG: {
2309 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
2310 return ui::LogicalDisplayId::INVALID;
2311 }
2312 }
2313 return displayId == ui::LogicalDisplayId::INVALID ? mFocusedDisplayId : displayId;
2314 }
2315
shouldWaitToSendKeyLocked(nsecs_t currentTime,const char * focusedWindowName)2316 bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2317 const char* focusedWindowName) {
2318 if (mAnrTracker.empty()) {
2319 // already processed all events that we waited for
2320 mKeyIsWaitingForEventsTimeout = std::nullopt;
2321 return false;
2322 }
2323
2324 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2325 // Start the timer
2326 // Wait to send key because there are unprocessed events that may cause focus to change
2327 mKeyIsWaitingForEventsTimeout = currentTime +
2328 std::chrono::duration_cast<std::chrono::nanoseconds>(
2329 mPolicy.getKeyWaitingForEventsTimeout())
2330 .count();
2331 return true;
2332 }
2333
2334 // We still have pending events, and already started the timer
2335 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2336 return true; // Still waiting
2337 }
2338
2339 // Waited too long, and some connection still hasn't processed all motions
2340 // Just send the key to the focused window
2341 ALOGW("Dispatching key to %s even though there are other unprocessed events",
2342 focusedWindowName);
2343 mKeyIsWaitingForEventsTimeout = std::nullopt;
2344 return false;
2345 }
2346
2347 Result<sp<WindowInfoHandle>, InputEventInjectionResult>
findFocusedWindowTargetLocked(nsecs_t currentTime,const EventEntry & entry,nsecs_t & nextWakeupTime)2348 InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
2349 nsecs_t& nextWakeupTime) {
2350 ui::LogicalDisplayId displayId = getTargetDisplayId(entry);
2351 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
2352 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
2353 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2354
2355 // If there is no currently focused window and no focused application
2356 // then drop the event.
2357 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2358 ALOGI("Dropping %s event because there is no focused window or focused application in "
2359 "display %s.",
2360 ftl::enum_string(entry.type).c_str(), displayId.toString().c_str());
2361 return injectionError(InputEventInjectionResult::FAILED);
2362 }
2363
2364 // Drop key events if requested by input feature
2365 if (focusedWindowHandle != nullptr &&
2366 shouldDropInput(entry, focusedWindowHandle, mWindowInfos)) {
2367 return injectionError(InputEventInjectionResult::FAILED);
2368 }
2369
2370 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2371 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2372 // start interacting with another application via touch (app switch). This code can be removed
2373 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2374 // an app is expected to have a focused window.
2375 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2376 if (!mNoFocusedWindowTimeoutTime.has_value()) {
2377 // We just discovered that there's no focused window. Start the ANR timer
2378 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2379 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2380 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
2381 mAwaitedFocusedApplication = focusedApplicationHandle;
2382 mAwaitedApplicationDisplayId = displayId;
2383 ALOGW("Waiting because no window has focus but %s may eventually add a "
2384 "window when it finishes starting up. Will wait for %" PRId64 "ms",
2385 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
2386 nextWakeupTime = std::min(nextWakeupTime, *mNoFocusedWindowTimeoutTime);
2387 return injectionError(InputEventInjectionResult::PENDING);
2388 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2389 // Already raised ANR. Drop the event
2390 ALOGE("Dropping %s event because there is no focused window",
2391 ftl::enum_string(entry.type).c_str());
2392 return injectionError(InputEventInjectionResult::FAILED);
2393 } else {
2394 // Still waiting for the focused window
2395 return injectionError(InputEventInjectionResult::PENDING);
2396 }
2397 }
2398
2399 // we have a valid, non-null focused window
2400 resetNoFocusedWindowTimeoutLocked();
2401
2402 // Verify targeted injection.
2403 if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2404 ALOGW("Dropping injected event: %s", (*err).c_str());
2405 return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2406 }
2407
2408 if (focusedWindowHandle->getInfo()->inputConfig.test(
2409 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
2410 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
2411 return injectionError(InputEventInjectionResult::PENDING);
2412 }
2413
2414 // If the event is a key event, then we must wait for all previous events to
2415 // complete before delivering it because previous events may have the
2416 // side-effect of transferring focus to a different window and we want to
2417 // ensure that the following keys are sent to the new window.
2418 //
2419 // Suppose the user touches a button in a window then immediately presses "A".
2420 // If the button causes a pop-up window to appear then we want to ensure that
2421 // the "A" key is delivered to the new pop-up window. This is because users
2422 // often anticipate pending UI changes when typing on a keyboard.
2423 // To obtain this behavior, we must serialize key events with respect to all
2424 // prior input events.
2425 if (entry.type == EventEntry::Type::KEY) {
2426 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2427 nextWakeupTime = std::min(nextWakeupTime, *mKeyIsWaitingForEventsTimeout);
2428 return injectionError(InputEventInjectionResult::PENDING);
2429 }
2430 }
2431 // Success!
2432 return focusedWindowHandle;
2433 }
2434
2435 base::Result<std::vector<InputTarget>, os::InputEventInjectionResult>
findTouchedWindowTargets(nsecs_t currentTime,const MotionEntry & entry,const sp<android::gui::WindowInfoHandle> dragWindow,std::function<void (const MotionEntry &)> addDragEvent,std::function<void ()> dump)2436 InputDispatcher::DispatcherTouchState::findTouchedWindowTargets(
2437 nsecs_t currentTime, const MotionEntry& entry,
2438 const sp<android::gui::WindowInfoHandle> dragWindow,
2439 std::function<void(const MotionEntry&)> addDragEvent, std::function<void()> dump) {
2440 ATRACE_CALL();
2441
2442 std::vector<InputTarget> targets;
2443 // For security reasons, we defer updating the touch state until we are sure that
2444 // event injection will be allowed.
2445 const ui::LogicalDisplayId displayId = entry.displayId;
2446 const int32_t action = entry.action;
2447 const int32_t maskedAction = MotionEvent::getActionMasked(action);
2448
2449 // Copy current touch state into tempTouchState.
2450 // This state will be used to update saved touch state at the end of this function.
2451 // If no state for the specified display exists, then our initial state will be empty.
2452 const TouchState* oldState = getTouchStateForMotionEntry(entry);
2453 TouchState tempTouchState;
2454 if (oldState != nullptr) {
2455 tempTouchState = *oldState;
2456 }
2457
2458 const bool isSplit = shouldSplitTouch(entry.source);
2459
2460 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2461 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2462 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2463 // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2464 // touchable windows.
2465 const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
2466 const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2467 (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
2468 const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2469 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2470 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
2471
2472 if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2473 // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2474 tempTouchState.clearHoveringPointers(entry.deviceId);
2475 }
2476
2477 if (isHoverAction) {
2478 if (wasDown) {
2479 // Started hovering, but the device is already down: reject the hover event
2480 LOG(ERROR) << "Got hover event " << entry.getDescription()
2481 << " but the device is already down " << oldState->dump();
2482 return injectionError(InputEventInjectionResult::FAILED);
2483 }
2484 // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2485 // all of the existing hovering pointers and recompute.
2486 tempTouchState.clearHoveringPointers(entry.deviceId);
2487 }
2488
2489 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2490 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2491 const auto [x, y] = resolveTouchedPosition(entry);
2492 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2493 const PointerProperties& pointer = entry.pointerProperties[pointerIndex];
2494 // Outside targets should be added upon first dispatched DOWN event. That means, this should
2495 // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
2496 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
2497 sp<WindowInfoHandle> newTouchedWindowHandle =
2498 mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
2499
2500 if (isDown) {
2501 targets += findOutsideTargets(displayId, newTouchedWindowHandle, pointer.id, dump);
2502 }
2503 LOG_IF(INFO, newTouchedWindowHandle == nullptr)
2504 << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y)
2505 << ") in display " << displayId;
2506
2507 // Verify targeted injection.
2508 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2509 ALOGW("Dropping injected touch event: %s", (*err).c_str());
2510 return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2511 }
2512
2513 if (newTouchedWindowHandle != nullptr &&
2514 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2515 // Check if this should be redirected to another window, in case this window previously
2516 // called 'transferTouch' for this gesture.
2517 const auto it =
2518 std::find_if(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2519 [&](const TouchedWindow& touchedWindow) {
2520 return touchedWindow.forwardingWindowToken ==
2521 newTouchedWindowHandle->getToken() &&
2522 touchedWindow.hasTouchingPointers(entry.deviceId);
2523 });
2524 if (it != tempTouchState.windows.end()) {
2525 LOG(INFO) << "Forwarding pointer from " << newTouchedWindowHandle->getName()
2526 << " to " << it->windowHandle->getName();
2527 newTouchedWindowHandle = it->windowHandle;
2528 }
2529 }
2530
2531 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
2532 findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId, mWindowInfos);
2533 if (newTouchedWindowHandle != nullptr) {
2534 // Process the foreground window first so that it is the first to receive the event.
2535 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
2536 }
2537
2538 if (newTouchedWindows.empty()) {
2539 LOG(INFO) << "Dropping event because there is no touchable window at (" << x << ", "
2540 << y << ") on display " << displayId << ": " << entry;
2541 return injectionError(InputEventInjectionResult::FAILED);
2542 }
2543
2544 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2545 if (!canWindowReceiveMotion(windowHandle, entry)) {
2546 continue;
2547 }
2548
2549 if (isHoverAction) {
2550 // The "windowHandle" is the target of this hovering pointer.
2551 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer, x,
2552 y);
2553 }
2554
2555 // Set target flags.
2556 ftl::Flags<InputTarget::Flags> targetFlags =
2557 getTargetFlags(windowHandle, {x, y}, isSplit);
2558
2559 // Update the temporary touch state.
2560
2561 if (!isHoverAction) {
2562 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2563 maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
2564 Result<void> addResult =
2565 tempTouchState.addOrUpdateWindow(windowHandle,
2566 InputTarget::DispatchMode::AS_IS,
2567 targetFlags, entry.deviceId, {pointer},
2568 isDownOrPointerDown
2569 ? std::make_optional(
2570 entry.eventTime)
2571 : std::nullopt,
2572 /*forwardingWindowToken=*/nullptr);
2573 if (!addResult.ok()) {
2574 LOG(ERROR) << "Error while processing " << entry << " for "
2575 << windowHandle->getName();
2576 dump();
2577 }
2578 // If this is the pointer going down and the touched window has a wallpaper
2579 // then also add the touched wallpaper windows so they are locked in for the
2580 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2581 // SCROLL because the wallpaper engine only supports touch events. We would need to
2582 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2583 // handle these events.
2584 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
2585 windowHandle->getInfo()->inputConfig.test(
2586 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2587 sp<WindowInfoHandle> wallpaper =
2588 mWindowInfos.findWallpaperWindowBelow(windowHandle);
2589 if (wallpaper != nullptr) {
2590 ftl::Flags<InputTarget::Flags> wallpaperFlags =
2591 InputTarget::Flags::WINDOW_IS_OBSCURED |
2592 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
2593 if (isSplit) {
2594 wallpaperFlags |= InputTarget::Flags::SPLIT;
2595 }
2596 tempTouchState.addOrUpdateWindow(wallpaper,
2597 InputTarget::DispatchMode::AS_IS,
2598 wallpaperFlags, entry.deviceId, {pointer},
2599 entry.eventTime,
2600 /*forwardingWindowToken=*/nullptr);
2601 }
2602 }
2603 }
2604 }
2605
2606 // If a window is already pilfering some pointers, give it this new pointer as well and
2607 // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2608 // which is a specific behaviour that we want.
2609 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2610 if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) &&
2611 touchedWindow.hasPilferingPointers(entry.deviceId)) {
2612 // This window is already pilfering some pointers, and this new pointer is also
2613 // going to it. Therefore, take over this pointer and don't give it to anyone
2614 // else.
2615 touchedWindow.addPilferingPointer(entry.deviceId, pointer.id);
2616 }
2617 }
2618
2619 // Restrict all pilfered pointers to the pilfering windows.
2620 tempTouchState.cancelPointersForNonPilferingWindows();
2621 } else {
2622 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2623
2624 // If the pointer is not currently down, then ignore the event.
2625 if (!tempTouchState.isDown(entry.deviceId) &&
2626 maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
2627 LOG_IF(INFO, DEBUG_DROPPED_EVENTS_VERBOSE)
2628 << "Dropping event because the pointer for device " << entry.deviceId
2629 << " is not down or we previously dropped the pointer down event in display "
2630 << displayId << ": " << entry.getDescription();
2631 return injectionError(InputEventInjectionResult::FAILED);
2632 }
2633
2634 // If the pointer is not currently hovering, then ignore the event.
2635 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2636 const int32_t pointerId = entry.pointerProperties[0].id;
2637 if (oldState == nullptr ||
2638 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2639 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2640 "display "
2641 << displayId << ": " << entry.getDescription();
2642 return injectionError(InputEventInjectionResult::FAILED);
2643 }
2644 tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2645 }
2646
2647 addDragEvent(entry);
2648
2649 // Check whether touches should slip outside of the current foreground window.
2650 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
2651 tempTouchState.isSlippery(entry.deviceId)) {
2652 const auto [x, y] = resolveTouchedPosition(entry);
2653 const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
2654 sp<WindowInfoHandle> oldTouchedWindowHandle =
2655 tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
2656 LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
2657 sp<WindowInfoHandle> newTouchedWindowHandle =
2658 mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus);
2659
2660 // Verify targeted injection.
2661 if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2662 ALOGW("Dropping injected event: %s", (*err).c_str());
2663 return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2664 }
2665
2666 // Do not slide events to the window which can not receive motion event
2667 if (newTouchedWindowHandle != nullptr &&
2668 !canWindowReceiveMotion(newTouchedWindowHandle, entry)) {
2669 newTouchedWindowHandle = nullptr;
2670 }
2671
2672 if (newTouchedWindowHandle != nullptr &&
2673 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
2674 ALOGI("Touch is slipping out of window %s into window %s in display %s",
2675 oldTouchedWindowHandle->getName().c_str(),
2676 newTouchedWindowHandle->getName().c_str(), displayId.toString().c_str());
2677
2678 // Make a slippery exit from the old window.
2679 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2680 const PointerProperties& pointer = entry.pointerProperties[0];
2681 pointerIds.set(pointer.id);
2682
2683 const TouchedWindow& touchedWindow =
2684 tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
2685 addPointerWindowTarget(oldTouchedWindowHandle,
2686 InputTarget::DispatchMode::SLIPPERY_EXIT,
2687 ftl::Flags<InputTarget::Flags>(), pointerIds,
2688 touchedWindow.getDownTimeInTarget(entry.deviceId),
2689 /*pointerDisplayId=*/std::nullopt, dump, targets);
2690
2691 // Make a slippery entrance into the new window.
2692
2693 ftl::Flags<InputTarget::Flags> targetFlags =
2694 getTargetFlags(newTouchedWindowHandle, {x, y}, isSplit);
2695
2696 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
2697 InputTarget::DispatchMode::SLIPPERY_ENTER,
2698 targetFlags, entry.deviceId, {pointer},
2699 entry.eventTime,
2700 /*forwardingWindowToken=*/nullptr);
2701
2702 // Check if the wallpaper window should deliver the corresponding event.
2703 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
2704 tempTouchState, entry, targets, dump);
2705 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
2706 oldTouchedWindowHandle);
2707 }
2708 }
2709
2710 // Update the pointerIds for non-splittable when it received pointer down.
2711 if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2712 // If no split, we suppose all touched windows should receive pointer down.
2713 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2714 std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
2715 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2716 // Ignore drag window for it should just track one pointer.
2717 if (dragWindow == touchedWindow.windowHandle) {
2718 continue;
2719 }
2720 if (!touchedWindow.hasTouchingPointers(entry.deviceId)) {
2721 continue;
2722 }
2723 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
2724 }
2725 }
2726 }
2727
2728 // Update dispatching for hover enter and exit.
2729 {
2730 std::vector<TouchedWindow> hoveringWindows =
2731 getHoveringWindowsLocked(oldState, tempTouchState, entry, dump);
2732 // Hardcode to single hovering pointer for now.
2733 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2734 pointerIds.set(entry.pointerProperties[0].id);
2735 for (const TouchedWindow& touchedWindow : hoveringWindows) {
2736 addPointerWindowTarget(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2737 touchedWindow.targetFlags, pointerIds,
2738 touchedWindow.getDownTimeInTarget(entry.deviceId),
2739 /*pointerDisplayId=*/std::nullopt, dump, targets);
2740 }
2741 }
2742
2743 // Ensure that all touched windows are valid for injection.
2744 if (entry.injectionState != nullptr) {
2745 std::string errs;
2746 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
2747 const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2748 if (err) errs += "\n - " + *err;
2749 }
2750 if (!errs.empty()) {
2751 ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
2752 "%s:%s",
2753 entry.injectionState->targetUid->toString().c_str(), errs.c_str());
2754 return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2755 }
2756 }
2757
2758 // Check whether windows listening for outside touches are owned by the same UID. If the owner
2759 // has a different UID, then we will not reveal coordinate information to this window.
2760 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2761 sp<WindowInfoHandle> foregroundWindowHandle =
2762 tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
2763 if (foregroundWindowHandle) {
2764 const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
2765 for (InputTarget& target : targets) {
2766 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
2767 sp<WindowInfoHandle> targetWindow =
2768 mWindowInfos.findWindowHandle(target.connection->getToken());
2769 if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2770 target.flags |= InputTarget::Flags::ZERO_COORDS;
2771 }
2772 }
2773 }
2774 }
2775 }
2776
2777 // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2778 // only want the system UI to handle these gestures.
2779 const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2780 entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2781 if (isTouchpadNavGesture) {
2782 filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2783 }
2784
2785 // Output targets from the touch state.
2786 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
2787 std::vector<PointerProperties> touchingPointers =
2788 touchedWindow.getTouchingPointers(entry.deviceId);
2789 if (touchingPointers.empty()) {
2790 continue;
2791 }
2792 addPointerWindowTarget(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2793 touchedWindow.targetFlags, getPointerIds(touchingPointers),
2794 touchedWindow.getDownTimeInTarget(entry.deviceId),
2795 /*pointerDisplayId=*/displayId, dump, targets);
2796 }
2797
2798 // During targeted injection, only allow owned targets to receive events
2799 std::erase_if(targets, [&](const InputTarget& target) {
2800 LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2801 const auto err = verifyTargetedInjection(target.windowHandle, entry);
2802 if (err) {
2803 LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2804 << ": " << (*err);
2805 return true;
2806 }
2807 return false;
2808 });
2809
2810 if (targets.empty()) {
2811 LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2812 return injectionError(InputEventInjectionResult::FAILED);
2813 }
2814
2815 // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2816 // window that is actually receiving the entire gesture.
2817 if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
2818 return target.dispatchMode == InputTarget::DispatchMode::OUTSIDE;
2819 })) {
2820 LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2821 << entry.getDescription();
2822 return injectionError(InputEventInjectionResult::FAILED);
2823 }
2824
2825 // Now that we have generated all of the input targets for this event, reset the dispatch
2826 // mode for all touched window to AS_IS.
2827 for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2828 touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
2829 }
2830
2831 // Update final pieces of touch state if the injector had permission.
2832 if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2833 // Pointer went up.
2834 tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
2835 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2836 // All pointers up or canceled.
2837 tempTouchState.removeAllPointersForDevice(entry.deviceId);
2838 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2839 // One pointer went up.
2840 const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2841 const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2842 tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
2843 }
2844
2845 // Save changes unless the action was scroll in which case the temporary touch
2846 // state was only valid for this one action.
2847 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2848 if (displayId >= ui::LogicalDisplayId::DEFAULT) {
2849 tempTouchState.clearWindowsWithoutPointers();
2850 saveTouchStateForMotionEntry(entry, std::move(tempTouchState));
2851 } else {
2852 eraseTouchStateForMotionEntry(entry);
2853 }
2854 }
2855
2856 return targets;
2857 }
2858
finishDragAndDrop(ui::LogicalDisplayId displayId,float x,float y)2859 void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x, float y) {
2860 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2861 // have an explicit reason to support it.
2862 constexpr bool isStylus = false;
2863
2864 sp<WindowInfoHandle> dropWindow =
2865 mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus, /*ignoreWindow=*/
2866 mDragState->dragWindow);
2867 if (dropWindow) {
2868 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
2869 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
2870 } else {
2871 ALOGW("No window found when drop.");
2872 sendDropWindowCommandLocked(nullptr, 0, 0);
2873 }
2874 mDragState.reset();
2875 }
2876
addDragEventLocked(const MotionEntry & entry)2877 void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2878 if (!mDragState || mDragState->deviceId != entry.deviceId ||
2879 !mWindowInfos.areDisplaysConnected(mDragState->dragWindow->getInfo()->displayId,
2880 entry.displayId)) {
2881 return;
2882 }
2883
2884 if (!mDragState->isStartDrag) {
2885 mDragState->isStartDrag = true;
2886 mDragState->isStylusButtonDownAtStart =
2887 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2888 }
2889
2890 // Find the pointer index by id.
2891 int32_t pointerIndex = 0;
2892 for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
2893 const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2894 if (pointerProperties.id == mDragState->pointerId) {
2895 break;
2896 }
2897 }
2898
2899 if (uint32_t(pointerIndex) == entry.getPointerCount()) {
2900 LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
2901 }
2902
2903 const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2904 const int32_t x = entry.pointerCoords[pointerIndex].getX();
2905 const int32_t y = entry.pointerCoords[pointerIndex].getY();
2906
2907 switch (maskedAction) {
2908 case AMOTION_EVENT_ACTION_MOVE: {
2909 // Handle the special case : stylus button no longer pressed.
2910 bool isStylusButtonDown =
2911 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2912 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2913 finishDragAndDrop(entry.displayId, x, y);
2914 return;
2915 }
2916
2917 // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2918 // until we have an explicit reason to support it.
2919 constexpr bool isStylus = false;
2920
2921 sp<WindowInfoHandle> hoverWindowHandle =
2922 mWindowInfos.findTouchedWindowAt(entry.displayId, x, y, isStylus,
2923 /*ignoreWindow=*/mDragState->dragWindow);
2924 // enqueue drag exit if needed.
2925 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2926 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2927 if (mDragState->dragHoverWindowHandle != nullptr) {
2928 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
2929 y);
2930 }
2931 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2932 }
2933 // enqueue drag location if needed.
2934 if (hoverWindowHandle != nullptr) {
2935 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
2936 }
2937 break;
2938 }
2939
2940 case AMOTION_EVENT_ACTION_POINTER_UP:
2941 if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
2942 break;
2943 }
2944 // The drag pointer is up.
2945 [[fallthrough]];
2946 case AMOTION_EVENT_ACTION_UP:
2947 finishDragAndDrop(entry.displayId, x, y);
2948 break;
2949 case AMOTION_EVENT_ACTION_CANCEL: {
2950 ALOGD("Receiving cancel when drag and drop.");
2951 sendDropWindowCommandLocked(nullptr, 0, 0);
2952 mDragState.reset();
2953 break;
2954 }
2955 }
2956 }
2957
addWindowTargetLocked(const sp<WindowInfoHandle> & windowHandle,InputTarget::DispatchMode dispatchMode,ftl::Flags<InputTarget::Flags> targetFlags,std::optional<nsecs_t> firstDownTimeInTarget,std::vector<InputTarget> & inputTargets) const2958 void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
2959 InputTarget::DispatchMode dispatchMode,
2960 ftl::Flags<InputTarget::Flags> targetFlags,
2961 std::optional<nsecs_t> firstDownTimeInTarget,
2962 std::vector<InputTarget>& inputTargets) const {
2963 std::vector<InputTarget>::iterator it =
2964 std::find_if(inputTargets.begin(), inputTargets.end(),
2965 [&windowHandle](const InputTarget& inputTarget) {
2966 return inputTarget.connection->getToken() == windowHandle->getToken();
2967 });
2968
2969 const WindowInfo* windowInfo = windowHandle->getInfo();
2970
2971 if (it == inputTargets.end()) {
2972 std::shared_ptr<Connection> connection =
2973 mConnectionManager.getConnection(windowHandle->getToken());
2974 if (connection == nullptr) {
2975 ALOGW("Not creating InputTarget for %s, no input channel",
2976 windowHandle->getName().c_str());
2977 return;
2978 }
2979 inputTargets.push_back(
2980 createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
2981 mWindowInfos.getRawTransform(*windowHandle->getInfo()),
2982 firstDownTimeInTarget));
2983 it = inputTargets.end() - 1;
2984 }
2985
2986 if (it->flags != targetFlags) {
2987 LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
2988 }
2989 if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
2990 LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
2991 << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
2992 }
2993 }
2994
addPointerWindowTarget(const sp<android::gui::WindowInfoHandle> & windowHandle,InputTarget::DispatchMode dispatchMode,ftl::Flags<InputTarget::Flags> targetFlags,std::bitset<MAX_POINTER_ID+1> pointerIds,std::optional<nsecs_t> firstDownTimeInTarget,std::optional<ui::LogicalDisplayId> pointerDisplayId,std::function<void ()> dump,std::vector<InputTarget> & inputTargets)2995 void InputDispatcher::DispatcherTouchState::addPointerWindowTarget(
2996 const sp<android::gui::WindowInfoHandle>& windowHandle,
2997 InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2998 std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
2999 std::optional<ui::LogicalDisplayId> pointerDisplayId, std::function<void()> dump,
3000 std::vector<InputTarget>& inputTargets) {
3001 if (pointerIds.none()) {
3002 for (const auto& target : inputTargets) {
3003 LOG(INFO) << "Target: " << target;
3004 }
3005 LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
3006 return;
3007 }
3008 std::vector<InputTarget>::iterator it =
3009 std::find_if(inputTargets.begin(), inputTargets.end(),
3010 [&windowHandle](const InputTarget& inputTarget) {
3011 return inputTarget.connection->getToken() == windowHandle->getToken();
3012 });
3013
3014 // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
3015 // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
3016 // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
3017 // input targets for hovering pointers and for touching pointers.
3018 // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
3019 // target instead.
3020 if (it != inputTargets.end() && it->dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
3021 // Force the code below to create a new input target
3022 it = inputTargets.end();
3023 }
3024
3025 const WindowInfo& windowInfo = *windowHandle->getInfo();
3026
3027 if (it == inputTargets.end()) {
3028 std::shared_ptr<Connection> connection = mConnectionManager.getConnection(windowInfo.token);
3029 if (connection == nullptr) {
3030 ALOGW("Not creating InputTarget for %s, no input channel", windowInfo.name.c_str());
3031 return;
3032 }
3033 inputTargets.push_back(
3034 createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
3035 mWindowInfos.getRawTransform(*windowHandle->getInfo(),
3036 pointerDisplayId),
3037 firstDownTimeInTarget));
3038 it = inputTargets.end() - 1;
3039 }
3040
3041 if (it->dispatchMode != dispatchMode) {
3042 LOG(ERROR) << __func__ << ": DispatchMode doesn't match! ignoring new mode="
3043 << ftl::enum_string(dispatchMode) << ", it=" << *it;
3044 }
3045 if (it->flags != targetFlags) {
3046 LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
3047 << ", it=" << *it;
3048 }
3049 if (it->globalScaleFactor != windowInfo.globalScaleFactor) {
3050 LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
3051 << ", windowInfo->globalScaleFactor=" << windowInfo.globalScaleFactor;
3052 }
3053
3054 Result<void> result = it->addPointers(pointerIds, windowInfo.transform);
3055 if (!result.ok()) {
3056 dump();
3057 LOG(FATAL) << result.error().message();
3058 }
3059 }
3060
addGlobalMonitoringTargetsLocked(std::vector<InputTarget> & inputTargets,ui::LogicalDisplayId displayId)3061 void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
3062 ui::LogicalDisplayId displayId) {
3063 mConnectionManager
3064 .forEachGlobalMonitorConnection(displayId,
3065 [&](const std::shared_ptr<Connection>& connection) {
3066 if (!connection->responsive) {
3067 ALOGW("Ignoring unrsponsive monitor: %s",
3068 connection->getInputChannelName()
3069 .c_str());
3070 return;
3071 }
3072
3073 InputTarget target{connection};
3074 // target.firstDownTimeInTarget is not set for
3075 // global monitors. It is only required in split
3076 // touch and global monitoring works as intended
3077 // even without setting firstDownTimeInTarget. Since
3078 // global monitors don't have windows, use the
3079 // display transform as the raw transform.
3080 base::ScopedLockAssertion assumeLocked(mLock);
3081 target.rawTransform =
3082 mWindowInfos.getDisplayTransform(displayId);
3083 target.setDefaultPointerTransform(
3084 target.rawTransform);
3085 inputTargets.push_back(target);
3086 });
3087 }
3088
3089 /**
3090 * Indicate whether one window handle should be considered as obscuring
3091 * another window handle. We only check a few preconditions. Actually
3092 * checking the bounds is left to the caller.
3093 */
canBeObscuredBy(const sp<WindowInfoHandle> & windowHandle,const sp<WindowInfoHandle> & otherHandle)3094 static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
3095 const sp<WindowInfoHandle>& otherHandle) {
3096 // Compare by token so cloned layers aren't counted
3097 if (haveSameToken(windowHandle, otherHandle)) {
3098 return false;
3099 }
3100 auto info = windowHandle->getInfo();
3101 auto otherInfo = otherHandle->getInfo();
3102 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
3103 return false;
3104 } else if (otherInfo->alpha == 0 &&
3105 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
3106 // Those act as if they were invisible, so we don't need to flag them.
3107 // We do want to potentially flag touchable windows even if they have 0
3108 // opacity, since they can consume touches and alter the effects of the
3109 // user interaction (eg. apps that rely on
3110 // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
3111 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
3112 return false;
3113 } else if (info->ownerUid == otherInfo->ownerUid) {
3114 // If ownerUid is the same we don't generate occlusion events as there
3115 // is no security boundary within an uid.
3116 return false;
3117 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
3118 return false;
3119 } else if (otherInfo->displayId != info->displayId) {
3120 return false;
3121 }
3122 return true;
3123 }
3124
3125 /**
3126 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
3127 * untrusted, one should check:
3128 *
3129 * 1. If result.hasBlockingOcclusion is true.
3130 * If it's, it means the touch should be blocked due to a window with occlusion mode of
3131 * BLOCK_UNTRUSTED.
3132 *
3133 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
3134 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
3135 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3136 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3137 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
3138 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3139 *
3140 * If neither of those is true, then it means the touch can be allowed.
3141 */
3142 InputDispatcher::DispatcherWindowInfo::TouchOcclusionInfo
computeTouchOcclusionInfo(const sp<WindowInfoHandle> & windowHandle,float x,float y) const3143 InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo(
3144 const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
3145 const WindowInfo* windowInfo = windowHandle->getInfo();
3146 ui::LogicalDisplayId displayId = windowInfo->displayId;
3147 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
3148 TouchOcclusionInfo info;
3149 info.hasBlockingOcclusion = false;
3150 info.obscuringOpacity = 0;
3151 info.obscuringUid = gui::Uid::INVALID;
3152 std::map<gui::Uid, float> opacityByUid;
3153 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
3154 if (windowHandle == otherHandle) {
3155 break; // All future windows are below us. Exit early.
3156 }
3157 const WindowInfo* otherInfo = otherHandle->getInfo();
3158 if (canBeObscuredBy(windowHandle, otherHandle) &&
3159 windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId)) &&
3160 !haveSameApplicationToken(windowInfo, otherInfo)) {
3161 if (DEBUG_TOUCH_OCCLUSION) {
3162 info.debugInfo.push_back(
3163 dumpWindowForTouchOcclusion(*otherInfo, /*isTouchedWindow=*/false));
3164 }
3165 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3166 // we perform the checks below to see if the touch can be propagated or not based on the
3167 // window's touch occlusion mode
3168 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3169 info.hasBlockingOcclusion = true;
3170 info.obscuringUid = otherInfo->ownerUid;
3171 info.obscuringPackage = otherInfo->packageName;
3172 break;
3173 }
3174 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
3175 const auto uid = otherInfo->ownerUid;
3176 float opacity =
3177 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3178 // Given windows A and B:
3179 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3180 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3181 opacityByUid[uid] = opacity;
3182 if (opacity > info.obscuringOpacity) {
3183 info.obscuringOpacity = opacity;
3184 info.obscuringUid = uid;
3185 info.obscuringPackage = otherInfo->packageName;
3186 }
3187 }
3188 }
3189 }
3190 if (DEBUG_TOUCH_OCCLUSION) {
3191 info.debugInfo.push_back(
3192 dumpWindowForTouchOcclusion(*windowInfo, /*isTouchedWindow=*/true));
3193 }
3194 return info;
3195 }
3196
isTouchTrusted(const TouchOcclusionInfo & occlusionInfo) const3197 bool InputDispatcher::DispatcherWindowInfo::isTouchTrusted(
3198 const TouchOcclusionInfo& occlusionInfo) const {
3199 if (occlusionInfo.hasBlockingOcclusion) {
3200 ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3201 occlusionInfo.obscuringUid.toString().c_str());
3202 return false;
3203 }
3204 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
3205 ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
3206 "%.2f, maximum allowed = %.2f)",
3207 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
3208 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3209 return false;
3210 }
3211 return true;
3212 }
3213
isWindowObscuredAtPoint(const sp<WindowInfoHandle> & windowHandle,float x,float y) const3214 bool InputDispatcher::DispatcherWindowInfo::isWindowObscuredAtPoint(
3215 const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
3216 ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
3217 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
3218 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
3219 if (windowHandle == otherHandle) {
3220 break; // All future windows are below us. Exit early.
3221 }
3222 const WindowInfo* otherInfo = otherHandle->getInfo();
3223 if (canBeObscuredBy(windowHandle, otherHandle) &&
3224 windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId))) {
3225 return true;
3226 }
3227 }
3228 return false;
3229 }
3230
isWindowObscured(const sp<WindowInfoHandle> & windowHandle) const3231 bool InputDispatcher::DispatcherWindowInfo::isWindowObscured(
3232 const sp<WindowInfoHandle>& windowHandle) const {
3233 ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
3234 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
3235 const WindowInfo* windowInfo = windowHandle->getInfo();
3236 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
3237 if (windowHandle == otherHandle) {
3238 break; // All future windows are below us. Exit early.
3239 }
3240 const WindowInfo* otherInfo = otherHandle->getInfo();
3241 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->overlaps(windowInfo)) {
3242 return true;
3243 }
3244 }
3245 return false;
3246 }
3247
getApplicationWindowLabel(const InputApplicationHandle * applicationHandle,const sp<WindowInfoHandle> & windowHandle)3248 std::string InputDispatcher::getApplicationWindowLabel(
3249 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
3250 if (applicationHandle != nullptr) {
3251 if (windowHandle != nullptr) {
3252 return applicationHandle->getName() + " - " + windowHandle->getName();
3253 } else {
3254 return applicationHandle->getName();
3255 }
3256 } else if (windowHandle != nullptr) {
3257 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
3258 } else {
3259 return "<unknown application or window>";
3260 }
3261 }
3262
pokeUserActivityLocked(const EventEntry & eventEntry)3263 void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
3264 if (!isUserActivityEvent(eventEntry)) {
3265 // Not poking user activity if the event type does not represent a user activity
3266 return;
3267 }
3268
3269 const int32_t eventType = getUserActivityEventType(eventEntry);
3270 if (input_flags::rate_limit_user_activity_poke_in_dispatcher()) {
3271 // Note that we're directly getting the time diff between the current event and the previous
3272 // event. This is assuming that the first user event always happens at a timestamp that is
3273 // greater than `mMinTimeBetweenUserActivityPokes` (otherwise, the first user event will
3274 // wrongly be dropped). In real life, `mMinTimeBetweenUserActivityPokes` is a much smaller
3275 // value than the potential first user activity event time, so this is ok.
3276 std::chrono::nanoseconds timeSinceLastEvent =
3277 std::chrono::nanoseconds(eventEntry.eventTime - mLastUserActivityTimes[eventType]);
3278 if (timeSinceLastEvent < mMinTimeBetweenUserActivityPokes) {
3279 return;
3280 }
3281 }
3282
3283 ui::LogicalDisplayId displayId = getTargetDisplayId(eventEntry);
3284 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
3285 const WindowInfo* windowDisablingUserActivityInfo = nullptr;
3286 if (focusedWindowHandle != nullptr) {
3287 const WindowInfo* info = focusedWindowHandle->getInfo();
3288 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
3289 windowDisablingUserActivityInfo = info;
3290 }
3291 }
3292
3293 switch (eventEntry.type) {
3294 case EventEntry::Type::MOTION: {
3295 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3296 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3297 return;
3298 }
3299 if (windowDisablingUserActivityInfo != nullptr) {
3300 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3301 << "Not poking user activity: disabled by window '"
3302 << windowDisablingUserActivityInfo->name << "'.";
3303 return;
3304 }
3305 break;
3306 }
3307 case EventEntry::Type::KEY: {
3308 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3309 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
3310 return;
3311 }
3312 // Don't inhibit events that were intercepted or are not passed to
3313 // the apps, like system shortcuts
3314 if (windowDisablingUserActivityInfo != nullptr &&
3315 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP) {
3316 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3317 << "Not poking user activity: disabled by window '"
3318 << windowDisablingUserActivityInfo->name << "'.";
3319 return;
3320 }
3321 break;
3322 }
3323 default: {
3324 LOG_ALWAYS_FATAL("%s events are not user activity",
3325 ftl::enum_string(eventEntry.type).c_str());
3326 break;
3327 }
3328 }
3329
3330 mLastUserActivityTimes[eventType] = eventEntry.eventTime;
3331 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3332 REQUIRES(mLock) {
3333 scoped_unlock unlock(mLock);
3334 mPolicy.pokeUserActivity(eventTime, eventType, displayId);
3335 };
3336 postCommandLocked(std::move(command));
3337 }
3338
prepareDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget & inputTarget)3339 void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
3340 const std::shared_ptr<Connection>& connection,
3341 std::shared_ptr<const EventEntry> eventEntry,
3342 const InputTarget& inputTarget) {
3343 ATRACE_NAME_IF(ATRACE_ENABLED(),
3344 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3345 connection->getInputChannelName().c_str(), eventEntry->id));
3346 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3347 << "channel '" << connection->getInputChannelName()
3348 << "' ~ prepareDispatchCycle - flags=" << inputTarget.flags.string()
3349 << ", globalScaleFactor=" << inputTarget.globalScaleFactor
3350 << ", pointerIds=" << bitsetToString(inputTarget.getPointerIds()) << " "
3351 << inputTarget.getPointerInfoString();
3352
3353 // Skip this event if the connection status is not normal.
3354 // We don't want to enqueue additional outbound events if the connection is broken.
3355 if (connection->status != Connection::Status::NORMAL) {
3356 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "channel '" << connection->getInputChannelName()
3357 << "' ~ Dropping event because the channel status is "
3358 << ftl::enum_string(connection->status);
3359 return;
3360 }
3361
3362 // Split a motion event if needed.
3363 if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
3364 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
3365 "Entry type %s should not have Flags::SPLIT",
3366 ftl::enum_string(eventEntry->type).c_str());
3367
3368 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
3369 if (inputTarget.getPointerIds().count() != originalMotionEntry.getPointerCount()) {
3370 if (!inputTarget.firstDownTimeInTarget.has_value()) {
3371 logDispatchStateLocked();
3372 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3373 "target on connection "
3374 << connection->getInputChannelName() << " for "
3375 << originalMotionEntry.getDescription();
3376 }
3377 std::unique_ptr<MotionEntry> splitMotionEntry =
3378 splitMotionEvent(originalMotionEntry, inputTarget.getPointerIds(),
3379 inputTarget.firstDownTimeInTarget.value());
3380 if (!splitMotionEntry) {
3381 return; // split event was dropped
3382 }
3383 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3384 std::string reason = std::string("reason=pointer cancel on split window");
3385 android_log_event_list(LOGTAG_INPUT_CANCEL)
3386 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3387 }
3388 if (DEBUG_FOCUS) {
3389 ALOGD("channel '%s' ~ Split motion event.",
3390 connection->getInputChannelName().c_str());
3391 logOutboundMotionDetails(" ", *splitMotionEntry);
3392 }
3393 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
3394 std::move(splitMotionEntry),
3395 inputTarget);
3396 return;
3397 }
3398 }
3399
3400 // Not splitting. Enqueue dispatch entries for the event as is.
3401 enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
3402 inputTarget);
3403 }
3404
enqueueDispatchEntryAndStartDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget & inputTarget)3405 void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
3406 nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
3407 std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
3408 ATRACE_NAME_IF(ATRACE_ENABLED(),
3409 StringPrintf("enqueueDispatchEntryAndStartDispatchCycleLocked(inputChannel=%s, "
3410 "id=0x%" PRIx32 ")",
3411 connection->getInputChannelName().c_str(), eventEntry->id));
3412
3413 const bool wasEmpty = connection->outboundQueue.empty();
3414
3415 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
3416
3417 // If the outbound queue was previously empty, start the dispatch cycle going.
3418 if (wasEmpty && !connection->outboundQueue.empty()) {
3419 startDispatchCycleLocked(currentTime, connection);
3420 }
3421 }
3422
enqueueDispatchEntryLocked(const std::shared_ptr<Connection> & connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget & inputTarget)3423 void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
3424 std::shared_ptr<const EventEntry> eventEntry,
3425 const InputTarget& inputTarget) {
3426 const bool isKeyOrMotion = eventEntry->type == EventEntry::Type::KEY ||
3427 eventEntry->type == EventEntry::Type::MOTION;
3428 if (isKeyOrMotion && !inputTarget.windowHandle && !connection->monitor) {
3429 LOG(FATAL) << "All InputTargets for non-monitors must be associated with a window; target: "
3430 << inputTarget << " connection: " << connection->getInputChannelName()
3431 << " entry: " << eventEntry->getDescription();
3432 }
3433 // This is a new event.
3434 // Enqueue a new dispatch entry onto the outbound queue for this connection.
3435 std::unique_ptr<DispatchEntry> dispatchEntry =
3436 createDispatchEntry(mIdGenerator, inputTarget, eventEntry, inputTarget.flags,
3437 mWindowInfosVsyncId, mTracer.get());
3438
3439 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3440 // different EventEntry than what was passed in.
3441 eventEntry = dispatchEntry->eventEntry;
3442 // Apply target flags and update the connection's input state.
3443 switch (eventEntry->type) {
3444 case EventEntry::Type::KEY: {
3445 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3446 if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
3447 LOG(WARNING) << "channel " << connection->getInputChannelName()
3448 << "~ dropping inconsistent event: " << *dispatchEntry;
3449 return; // skip the inconsistent event
3450 }
3451 break;
3452 }
3453
3454 case EventEntry::Type::MOTION: {
3455 std::shared_ptr<const MotionEntry> resolvedMotion =
3456 std::static_pointer_cast<const MotionEntry>(eventEntry);
3457 {
3458 // Determine the resolved motion entry.
3459 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3460 int32_t resolvedAction = motionEntry.action;
3461 int32_t resolvedFlags = motionEntry.flags;
3462
3463 if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
3464 resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3465 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
3466 resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3467 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
3468 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3469 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
3470 resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3471 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
3472 resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3473 }
3474 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3475 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3476 motionEntry.displayId)) {
3477 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3478 << "channel '" << connection->getInputChannelName().c_str()
3479 << "' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
3480 "event";
3481 resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3482 }
3483
3484 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3485 resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3486 }
3487 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3488 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3489 }
3490 if (dispatchEntry->targetFlags.test(
3491 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3492 resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3493 }
3494 if (dispatchEntry->targetFlags.test(InputTarget::Flags::NO_FOCUS_CHANGE)) {
3495 resolvedFlags |= AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
3496 }
3497
3498 dispatchEntry->resolvedFlags = resolvedFlags;
3499 if (resolvedAction != motionEntry.action) {
3500 std::optional<std::vector<PointerProperties>> usingProperties;
3501 std::optional<std::vector<PointerCoords>> usingCoords;
3502 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT ||
3503 resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3504 // This is a HOVER_EXIT or an ACTION_CANCEL event that was synthesized by
3505 // the dispatcher, and therefore the coordinates of this event are currently
3506 // incorrect. These events should use the coordinates of the last dispatched
3507 // ACTION_MOVE or HOVER_MOVE. We need to query InputState to get this data.
3508 const bool hovering = resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT;
3509 std::optional<std::pair<std::vector<PointerProperties>,
3510 std::vector<PointerCoords>>>
3511 pointerInfo =
3512 connection->inputState.getPointersOfLastEvent(motionEntry,
3513 hovering);
3514 if (pointerInfo) {
3515 usingProperties = pointerInfo->first;
3516 usingCoords = pointerInfo->second;
3517 }
3518 }
3519 {
3520 // Generate a new MotionEntry with a new eventId using the resolved action
3521 // and flags, and set it as the resolved entry.
3522 auto newEntry = std::make_shared<
3523 MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
3524 motionEntry.eventTime, motionEntry.deviceId,
3525 motionEntry.source, motionEntry.displayId,
3526 motionEntry.policyFlags, resolvedAction,
3527 motionEntry.actionButton, resolvedFlags,
3528 motionEntry.metaState, motionEntry.buttonState,
3529 motionEntry.classification, motionEntry.edgeFlags,
3530 motionEntry.xPrecision, motionEntry.yPrecision,
3531 motionEntry.xCursorPosition,
3532 motionEntry.yCursorPosition, motionEntry.downTime,
3533 usingProperties.value_or(
3534 motionEntry.pointerProperties),
3535 usingCoords.value_or(motionEntry.pointerCoords));
3536 if (mTracer) {
3537 ensureEventTraced(motionEntry);
3538 newEntry->traceTracker =
3539 mTracer->traceDerivedEvent(*newEntry,
3540 *motionEntry.traceTracker);
3541 }
3542 resolvedMotion = newEntry;
3543 }
3544 if (ATRACE_ENABLED()) {
3545 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3546 ") to MotionEvent(id=0x%" PRIx32 ").",
3547 motionEntry.id, resolvedMotion->id);
3548 ATRACE_NAME(message.c_str());
3549 }
3550
3551 // Set the resolved motion entry in the DispatchEntry.
3552 dispatchEntry->eventEntry = resolvedMotion;
3553 eventEntry = resolvedMotion;
3554 }
3555 }
3556
3557 // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3558 // devices being active at the same time in the same window, so if a new device is
3559 // active, cancel the gesture from the old device.
3560 std::unique_ptr<EventEntry> cancelEvent =
3561 connection->inputState.cancelConflictingInputStream(*resolvedMotion);
3562 if (cancelEvent != nullptr) {
3563 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
3564 << connection->getInputChannelName() << " with event "
3565 << cancelEvent->getDescription();
3566 if (mTracer) {
3567 static_cast<MotionEntry&>(*cancelEvent).traceTracker =
3568 mTracer->traceDerivedEvent(*cancelEvent, *resolvedMotion->traceTracker);
3569 }
3570 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3571 createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent),
3572 ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId,
3573 mTracer.get());
3574
3575 // Send these cancel events to the queue before sending the event from the new
3576 // device.
3577 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
3578 }
3579
3580 if (!connection->inputState.trackMotion(*resolvedMotion,
3581 dispatchEntry->resolvedFlags)) {
3582 LOG(WARNING) << "channel " << connection->getInputChannelName()
3583 << "~ dropping inconsistent event: " << *dispatchEntry;
3584 return; // skip the inconsistent event
3585 }
3586 if ((dispatchEntry->resolvedFlags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3587 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
3588 // Skip reporting pointer down outside focus to the policy.
3589 break;
3590 }
3591
3592 dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
3593 inputTarget.connection->getToken());
3594
3595 break;
3596 }
3597 case EventEntry::Type::FOCUS:
3598 case EventEntry::Type::TOUCH_MODE_CHANGED:
3599 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3600 case EventEntry::Type::DRAG: {
3601 break;
3602 }
3603 case EventEntry::Type::SENSOR: {
3604 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3605 break;
3606 }
3607 case EventEntry::Type::DEVICE_RESET: {
3608 LOG_ALWAYS_FATAL("%s events should not go to apps",
3609 ftl::enum_string(eventEntry->type).c_str());
3610 break;
3611 }
3612 }
3613
3614 // Remember that we are waiting for this dispatch to complete.
3615 if (dispatchEntry->hasForegroundTarget()) {
3616 incrementPendingForegroundDispatches(*eventEntry);
3617 }
3618
3619 // Enqueue the dispatch entry.
3620 connection->outboundQueue.emplace_back(std::move(dispatchEntry));
3621 traceOutboundQueueLength(*connection);
3622 }
3623
3624 /**
3625 * This function is for debugging and metrics collection. It has two roles.
3626 *
3627 * The first role is to log input interaction with windows, which helps determine what the user was
3628 * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3629 * that user started interacting with launcher window, as well as any other window that received
3630 * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3631 * when the set of tokens that received the event changes. It is not logged again as long as the
3632 * user is interacting with the same windows.
3633 *
3634 * The second role is to track input device activity for metrics collection. For each input event,
3635 * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3636 * input_interaction logs, the device interaction is reported even when the set of interaction
3637 * tokens do not change.
3638 *
3639 * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3640 * interaction. This includes up and cancel events for both keys and motions.
3641 */
processInteractionsLocked(const EventEntry & entry,const std::vector<InputTarget> & targets)3642 void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3643 const std::vector<InputTarget>& targets) {
3644 int32_t deviceId;
3645 nsecs_t eventTime;
3646 // Skip ACTION_UP events, and all events other than keys and motions
3647 if (entry.type == EventEntry::Type::KEY) {
3648 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3649 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3650 return;
3651 }
3652 deviceId = keyEntry.deviceId;
3653 eventTime = keyEntry.eventTime;
3654 } else if (entry.type == EventEntry::Type::MOTION) {
3655 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3656 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3657 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3658 MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
3659 return;
3660 }
3661 deviceId = motionEntry.deviceId;
3662 eventTime = motionEntry.eventTime;
3663 } else {
3664 return; // Not a key or a motion
3665 }
3666
3667 std::set<gui::Uid> interactionUids;
3668 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
3669 std::vector<std::shared_ptr<Connection>> newConnections;
3670 for (const InputTarget& target : targets) {
3671 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
3672 continue; // Skip windows that receive ACTION_OUTSIDE
3673 }
3674
3675 sp<IBinder> token = target.connection->getToken();
3676 newConnectionTokens.insert(std::move(token));
3677 newConnections.emplace_back(target.connection);
3678 if (target.windowHandle) {
3679 interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3680 }
3681 }
3682
3683 auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3684 REQUIRES(mLock) {
3685 scoped_unlock unlock(mLock);
3686 mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3687 };
3688 postCommandLocked(std::move(command));
3689
3690 if (newConnectionTokens == mInteractionConnectionTokens) {
3691 return; // no change
3692 }
3693 mInteractionConnectionTokens = newConnectionTokens;
3694
3695 std::string targetList;
3696 for (const std::shared_ptr<Connection>& connection : newConnections) {
3697 targetList += connection->getInputChannelName() + ", ";
3698 }
3699 std::string message = "Interaction with: " + targetList;
3700 if (targetList.empty()) {
3701 message += "<none>";
3702 }
3703 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3704 }
3705
dispatchPointerDownOutsideFocus(uint32_t source,int32_t action,const sp<IBinder> & token)3706 void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
3707 const sp<IBinder>& token) {
3708 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
3709 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3710 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
3711 return;
3712 }
3713
3714 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
3715 if (focusedToken == token) {
3716 // ignore since token is focused
3717 return;
3718 }
3719
3720 auto command = [this, token]() REQUIRES(mLock) {
3721 scoped_unlock unlock(mLock);
3722 mPolicy.onPointerDownOutsideFocus(token);
3723 };
3724 postCommandLocked(std::move(command));
3725 }
3726
publishMotionEvent(Connection & connection,DispatchEntry & dispatchEntry) const3727 status_t InputDispatcher::publishMotionEvent(Connection& connection,
3728 DispatchEntry& dispatchEntry) const {
3729 const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3730 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3731
3732 PointerCoords scaledCoords[MAX_POINTERS];
3733 const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
3734
3735 // TODO(b/316355518): Do not modify coords before dispatch.
3736 // Set the X and Y offset and X and Y scale depending on the input source.
3737 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
3738 !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
3739 float globalScaleFactor = dispatchEntry.globalScaleFactor;
3740 if (globalScaleFactor != 1.0f) {
3741 for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
3742 scaledCoords[i] = motionEntry.pointerCoords[i];
3743 // Don't apply window scale here since we don't want scale to affect raw
3744 // coordinates. The scale will be sent back to the client and applied
3745 // later when requesting relative coordinates.
3746 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
3747 }
3748 usingCoords = scaledCoords;
3749 }
3750 }
3751
3752 std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3753
3754 // Publish the motion event.
3755 return connection.inputPublisher
3756 .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3757 motionEntry.source, motionEntry.displayId, std::move(hmac),
3758 motionEntry.action, motionEntry.actionButton,
3759 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3760 motionEntry.metaState, motionEntry.buttonState,
3761 motionEntry.classification, dispatchEntry.transform,
3762 motionEntry.xPrecision, motionEntry.yPrecision,
3763 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3764 dispatchEntry.rawTransform, motionEntry.downTime,
3765 motionEntry.eventTime, motionEntry.getPointerCount(),
3766 motionEntry.pointerProperties.data(), usingCoords);
3767 }
3768
startDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection)3769 void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
3770 const std::shared_ptr<Connection>& connection) {
3771 ATRACE_NAME_IF(ATRACE_ENABLED(),
3772 StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3773 connection->getInputChannelName().c_str()));
3774 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3775 << "channel '" << connection->getInputChannelName() << "' ~ startDispatchCycle";
3776
3777 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
3778 std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
3779 dispatchEntry->deliveryTime = currentTime;
3780 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
3781 dispatchEntry->timeoutTime = currentTime + timeout.count();
3782
3783 // Publish the event.
3784 status_t status;
3785 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3786 switch (eventEntry.type) {
3787 case EventEntry::Type::KEY: {
3788 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3789 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
3790 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
3791 << "Publishing " << *dispatchEntry << " to "
3792 << connection->getInputChannelName();
3793
3794 // Publish the key event.
3795 status = connection->inputPublisher
3796 .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3797 keyEntry.deviceId, keyEntry.source,
3798 keyEntry.displayId, std::move(hmac),
3799 keyEntry.action, dispatchEntry->resolvedFlags,
3800 keyEntry.keyCode, keyEntry.scanCode,
3801 keyEntry.metaState, keyEntry.repeatCount,
3802 keyEntry.downTime, keyEntry.eventTime);
3803 if (mTracer) {
3804 ensureEventTraced(keyEntry);
3805 mTracer->traceEventDispatch(*dispatchEntry, *keyEntry.traceTracker);
3806 }
3807 break;
3808 }
3809
3810 case EventEntry::Type::MOTION: {
3811 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
3812 << "Publishing " << *dispatchEntry << " to "
3813 << connection->getInputChannelName();
3814 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3815 status = publishMotionEvent(*connection, *dispatchEntry);
3816 if (status == BAD_VALUE) {
3817 logDispatchStateLocked();
3818 LOG(FATAL) << "Publisher failed for " << motionEntry;
3819 }
3820 if (mTracer) {
3821 ensureEventTraced(motionEntry);
3822 mTracer->traceEventDispatch(*dispatchEntry, *motionEntry.traceTracker);
3823 }
3824 break;
3825 }
3826
3827 case EventEntry::Type::FOCUS: {
3828 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
3829 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
3830 focusEntry.id,
3831 focusEntry.hasFocus);
3832 break;
3833 }
3834
3835 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3836 const TouchModeEntry& touchModeEntry =
3837 static_cast<const TouchModeEntry&>(eventEntry);
3838 status = connection->inputPublisher
3839 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3840 touchModeEntry.inTouchMode);
3841
3842 break;
3843 }
3844
3845 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3846 const auto& captureEntry =
3847 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3848 status =
3849 connection->inputPublisher
3850 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3851 captureEntry.pointerCaptureRequest.isEnable());
3852 break;
3853 }
3854
3855 case EventEntry::Type::DRAG: {
3856 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3857 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3858 dragEntry.id, dragEntry.x,
3859 dragEntry.y,
3860 dragEntry.isExiting);
3861 break;
3862 }
3863
3864 case EventEntry::Type::DEVICE_RESET:
3865 case EventEntry::Type::SENSOR: {
3866 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
3867 ftl::enum_string(eventEntry.type).c_str());
3868 return;
3869 }
3870 }
3871
3872 // Check the result.
3873 if (status) {
3874 if (status == WOULD_BLOCK) {
3875 if (connection->waitQueue.empty()) {
3876 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
3877 "This is unexpected because the wait queue is empty, so the pipe "
3878 "should be empty and we shouldn't have any problems writing an "
3879 "event to it, status=%s(%d)",
3880 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3881 status);
3882 abortBrokenDispatchCycleLocked(connection, /*notify=*/true);
3883 } else {
3884 // Pipe is full and we are waiting for the app to finish process some events
3885 // before sending more events to it.
3886 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3887 << "channel '" << connection->getInputChannelName()
3888 << "' ~ Could not publish event because the pipe is full, waiting for "
3889 "the application to catch up";
3890 }
3891 } else {
3892 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
3893 "status=%s(%d)",
3894 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3895 status);
3896 abortBrokenDispatchCycleLocked(connection, /*notify=*/true);
3897 }
3898 return;
3899 }
3900
3901 // Re-enqueue the event on the wait queue.
3902 const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3903 connection->waitQueue.emplace_back(std::move(dispatchEntry));
3904 connection->outboundQueue.erase(connection->outboundQueue.begin());
3905 traceOutboundQueueLength(*connection);
3906 if (connection->responsive) {
3907 mAnrTracker.insert(timeoutTime, connection->getToken());
3908 }
3909 traceWaitQueueLength(*connection);
3910 }
3911 }
3912
sign(const VerifiedInputEvent & event) const3913 std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3914 size_t size;
3915 switch (event.type) {
3916 case VerifiedInputEvent::Type::KEY: {
3917 size = sizeof(VerifiedKeyEvent);
3918 break;
3919 }
3920 case VerifiedInputEvent::Type::MOTION: {
3921 size = sizeof(VerifiedMotionEvent);
3922 break;
3923 }
3924 }
3925 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3926 return mHmacKeyManager.sign(start, size);
3927 }
3928
getSignature(const MotionEntry & motionEntry,const DispatchEntry & dispatchEntry) const3929 const std::array<uint8_t, 32> InputDispatcher::getSignature(
3930 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3931 const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
3932 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
3933 // Only sign events up and down events as the purely move events
3934 // are tied to their up/down counterparts so signing would be redundant.
3935 return INVALID_HMAC;
3936 }
3937
3938 VerifiedMotionEvent verifiedEvent =
3939 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3940 verifiedEvent.actionMasked = actionMasked;
3941 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3942 return sign(verifiedEvent);
3943 }
3944
getSignature(const KeyEntry & keyEntry,const DispatchEntry & dispatchEntry) const3945 const std::array<uint8_t, 32> InputDispatcher::getSignature(
3946 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3947 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3948 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3949 return sign(verifiedEvent);
3950 }
3951
finishDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,uint32_t seq,bool handled,nsecs_t consumeTime)3952 void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
3953 const std::shared_ptr<Connection>& connection,
3954 uint32_t seq, bool handled, nsecs_t consumeTime) {
3955 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE)
3956 << "channel '" << connection->getInputChannelName()
3957 << "' ~ finishDispatchCycle - seq=" << seq << ", handled=" << toString(handled);
3958
3959 if (connection->status != Connection::Status::NORMAL) {
3960 return;
3961 }
3962
3963 // Notify other system components and prepare to start the next dispatch cycle.
3964 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3965 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3966 };
3967 postCommandLocked(std::move(command));
3968 }
3969
abortBrokenDispatchCycleLocked(const std::shared_ptr<Connection> & connection,bool notify)3970 void InputDispatcher::abortBrokenDispatchCycleLocked(const std::shared_ptr<Connection>& connection,
3971 bool notify) {
3972 LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "channel '" << connection->getInputChannelName() << "'~ "
3973 << __func__ << " - notify=" << toString(notify);
3974
3975 // Clear the dispatch queues.
3976 drainDispatchQueue(connection->outboundQueue);
3977 traceOutboundQueueLength(*connection);
3978 drainDispatchQueue(connection->waitQueue);
3979 traceWaitQueueLength(*connection);
3980
3981 // The connection appears to be unrecoverably broken.
3982 // Ignore already broken or zombie connections.
3983 if (connection->status == Connection::Status::NORMAL) {
3984 connection->status = Connection::Status::BROKEN;
3985
3986 if (notify) {
3987 // Notify other system components.
3988 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3989 connection->getInputChannelName().c_str());
3990
3991 auto command = [this, connection]() REQUIRES(mLock) {
3992 scoped_unlock unlock(mLock);
3993 mPolicy.notifyInputChannelBroken(connection->getToken());
3994 };
3995 postCommandLocked(std::move(command));
3996 }
3997 }
3998 }
3999
drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>> & queue)4000 void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
4001 while (!queue.empty()) {
4002 releaseDispatchEntry(std::move(queue.front()));
4003 queue.pop_front();
4004 }
4005 }
4006
releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry)4007 void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
4008 if (dispatchEntry->hasForegroundTarget()) {
4009 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
4010 }
4011 }
4012
handleReceiveCallback(int events,sp<IBinder> connectionToken)4013 int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
4014 std::scoped_lock _l(mLock);
4015 std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken);
4016 if (connection == nullptr) {
4017 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
4018 connectionToken.get(), events);
4019 return 0; // remove the callback
4020 }
4021
4022 bool notify;
4023 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
4024 if (!(events & ALOOPER_EVENT_INPUT)) {
4025 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
4026 "events=0x%x",
4027 connection->getInputChannelName().c_str(), events);
4028 return 1;
4029 }
4030
4031 nsecs_t currentTime = now();
4032 bool gotOne = false;
4033 status_t status = OK;
4034 for (;;) {
4035 Result<InputPublisher::ConsumerResponse> result =
4036 connection->inputPublisher.receiveConsumerResponse();
4037 if (!result.ok()) {
4038 status = result.error().code();
4039 break;
4040 }
4041
4042 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
4043 const InputPublisher::Finished& finish =
4044 std::get<InputPublisher::Finished>(*result);
4045 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
4046 finish.consumeTime);
4047 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
4048 if (shouldReportMetricsForConnection(*connection)) {
4049 const InputPublisher::Timeline& timeline =
4050 std::get<InputPublisher::Timeline>(*result);
4051 mLatencyTracker.trackGraphicsLatency(timeline.inputEventId,
4052 connection->getToken(),
4053 std::move(timeline.graphicsTimeline));
4054 }
4055 }
4056 gotOne = true;
4057 }
4058 if (gotOne) {
4059 runCommandsLockedInterruptable();
4060 if (status == WOULD_BLOCK) {
4061 return 1;
4062 }
4063 }
4064
4065 notify = status != DEAD_OBJECT || !connection->monitor;
4066 if (notify) {
4067 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
4068 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
4069 status);
4070 }
4071 } else {
4072 // Monitor channels are never explicitly unregistered.
4073 // We do it automatically when the remote endpoint is closed so don't warn about them.
4074 const bool stillHaveWindowHandle =
4075 mWindowInfos.findWindowHandle(connection->getToken()) != nullptr;
4076 notify = !connection->monitor && stillHaveWindowHandle;
4077 if (notify) {
4078 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
4079 connection->getInputChannelName().c_str(), events);
4080 }
4081 }
4082
4083 // Remove the channel.
4084 removeInputChannelLocked(connection, notify);
4085 return 0; // remove the callback
4086 }
4087
synthesizeCancelationEventsForAllConnectionsLocked(const CancelationOptions & options)4088 void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
4089 const CancelationOptions& options) {
4090 // Cancel windows (i.e. non-monitors).
4091 // A channel must have at least one window to receive any input. If a window was removed, the
4092 // event streams directed to the window will already have been canceled during window removal.
4093 // So there is no need to generate cancellations for connections without any windows.
4094 const auto [cancelPointers, cancelNonPointers] = expandCancellationMode(options.mode);
4095 // Generate cancellations for touched windows first. This is to avoid generating cancellations
4096 // through a non-touched window if there are more than one window for an input channel.
4097 if (cancelPointers) {
4098 if (options.displayId.has_value()) {
4099 mTouchStates.forAllTouchedWindowsOnDisplay(
4100 options.displayId.value(), [&](const sp<gui::WindowInfoHandle>& windowHandle) {
4101 base::ScopedLockAssertion assumeLocked(mLock);
4102 synthesizeCancelationEventsForWindowLocked(windowHandle, options);
4103 });
4104 } else {
4105 mTouchStates.forAllTouchedWindows([&](const sp<gui::WindowInfoHandle>& windowHandle) {
4106 base::ScopedLockAssertion assumeLocked(mLock);
4107 synthesizeCancelationEventsForWindowLocked(windowHandle, options);
4108 });
4109 }
4110 }
4111 // Follow up by generating cancellations for all windows, because we don't explicitly track
4112 // the windows that have an ongoing focus event stream.
4113 if (cancelNonPointers) {
4114 mWindowInfos.forEachWindowHandle(
4115 [&](const sp<android::gui::WindowInfoHandle>& windowHandle) {
4116 base::ScopedLockAssertion assumeLocked(mLock);
4117 synthesizeCancelationEventsForWindowLocked(windowHandle, options);
4118 });
4119 }
4120
4121 // Cancel monitors.
4122 synthesizeCancelationEventsForMonitorsLocked(options);
4123 }
4124
synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions & options)4125 void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
4126 const CancelationOptions& options) {
4127 mConnectionManager.forEachGlobalMonitorConnection(
4128 [&](const std::shared_ptr<Connection>& connection) {
4129 base::ScopedLockAssertion assumeLocked(mLock);
4130 synthesizeCancelationEventsForConnectionLocked(connection, options,
4131 /*window=*/nullptr);
4132 });
4133 }
4134
synthesizeCancelationEventsForWindowLocked(const sp<WindowInfoHandle> & windowHandle,const CancelationOptions & options,const std::shared_ptr<Connection> & connection)4135 void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4136 const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options,
4137 const std::shared_ptr<Connection>& connection) {
4138 if (windowHandle == nullptr) {
4139 LOG(FATAL) << __func__ << ": Window handle must not be null";
4140 }
4141 if (connection) {
4142 // The connection can be optionally provided to avoid multiple lookups.
4143 if (windowHandle->getToken() != connection->getToken()) {
4144 LOG(FATAL) << __func__
4145 << ": Wrong connection provided for window: " << windowHandle->getName();
4146 }
4147 }
4148
4149 std::shared_ptr<Connection> resolvedConnection =
4150 connection ? connection : mConnectionManager.getConnection(windowHandle->getToken());
4151 if (!resolvedConnection) {
4152 LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName();
4153 return;
4154 }
4155 synthesizeCancelationEventsForConnectionLocked(resolvedConnection, options, windowHandle);
4156 }
4157
synthesizeCancelationEventsForConnectionLocked(const std::shared_ptr<Connection> & connection,const CancelationOptions & options,const sp<WindowInfoHandle> & window)4158 void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
4159 const std::shared_ptr<Connection>& connection, const CancelationOptions& options,
4160 const sp<WindowInfoHandle>& window) {
4161 if (!connection->monitor && window == nullptr) {
4162 LOG(FATAL) << __func__
4163 << ": Cannot send event to non-monitor channel without a window - channel: "
4164 << connection->getInputChannelName();
4165 }
4166 if (connection->status != Connection::Status::NORMAL) {
4167 return;
4168 }
4169
4170 nsecs_t currentTime = now();
4171
4172 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
4173 connection->inputState.synthesizeCancelationEvents(currentTime, options);
4174
4175 if (cancelationEvents.empty()) {
4176 return;
4177 }
4178
4179 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
4180 << "channel '" << connection->getInputChannelName() << "' ~ Synthesized "
4181 << cancelationEvents.size()
4182 << " cancelation events to bring channel back in sync with reality: " << options.reason
4183 << ", mode=" << ftl::enum_string(options.mode) << ".";
4184
4185 std::string reason = std::string("reason=").append(options.reason);
4186 android_log_event_list(LOGTAG_INPUT_CANCEL)
4187 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
4188
4189 const bool wasEmpty = connection->outboundQueue.empty();
4190 // The target to use if we don't find a window associated with the channel.
4191 const InputTarget fallbackTarget{connection};
4192 const auto& token = connection->getToken();
4193
4194 for (size_t i = 0; i < cancelationEvents.size(); i++) {
4195 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
4196 std::vector<InputTarget> targets{};
4197
4198 switch (cancelationEventEntry->type) {
4199 case EventEntry::Type::KEY: {
4200 if (mTracer) {
4201 static_cast<KeyEntry&>(*cancelationEventEntry).traceTracker =
4202 mTracer->traceDerivedEvent(*cancelationEventEntry,
4203 *options.traceTracker);
4204 }
4205 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
4206 if (window) {
4207 addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4208 /*targetFlags=*/{}, keyEntry.downTime, targets);
4209 } else {
4210 targets.emplace_back(fallbackTarget);
4211 }
4212 logOutboundKeyDetails("cancel - ", keyEntry);
4213 break;
4214 }
4215 case EventEntry::Type::MOTION: {
4216 if (mTracer) {
4217 static_cast<MotionEntry&>(*cancelationEventEntry).traceTracker =
4218 mTracer->traceDerivedEvent(*cancelationEventEntry,
4219 *options.traceTracker);
4220 }
4221 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
4222 if (window) {
4223 std::bitset<MAX_POINTER_ID + 1> pointerIds;
4224 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
4225 pointerIndex++) {
4226 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4227 }
4228 if (mDragState && mDragState->dragWindow->getToken() == token &&
4229 pointerIds.test(mDragState->pointerId)) {
4230 LOG(INFO) << __func__
4231 << ": Canceling drag and drop because the pointers for the drag "
4232 "window are being canceled.";
4233 sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4234 mDragState.reset();
4235 }
4236 mTouchStates
4237 .addPointerWindowTarget(window, InputTarget::DispatchMode::AS_IS,
4238 ftl::Flags<InputTarget::Flags>(), pointerIds,
4239 motionEntry.downTime,
4240 /*pointerDisplayId=*/std::nullopt,
4241 std::bind_front(&InputDispatcher::
4242 logDispatchStateLocked,
4243 this),
4244 targets);
4245 } else {
4246 targets.emplace_back(fallbackTarget);
4247 // Since we don't have a window, use the display transform as the raw transform.
4248 const ui::Transform displayTransform =
4249 mWindowInfos.getDisplayTransform(motionEntry.displayId);
4250 targets.back().rawTransform = displayTransform;
4251 targets.back().setDefaultPointerTransform(displayTransform);
4252 }
4253 logOutboundMotionDetails("cancel - ", motionEntry);
4254 break;
4255 }
4256 case EventEntry::Type::FOCUS:
4257 case EventEntry::Type::TOUCH_MODE_CHANGED:
4258 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4259 case EventEntry::Type::DRAG: {
4260 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
4261 ftl::enum_string(cancelationEventEntry->type).c_str());
4262 break;
4263 }
4264 case EventEntry::Type::DEVICE_RESET:
4265 case EventEntry::Type::SENSOR: {
4266 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
4267 ftl::enum_string(cancelationEventEntry->type).c_str());
4268 break;
4269 }
4270 }
4271
4272 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
4273 if (mTracer) {
4274 mTracer->dispatchToTargetHint(*options.traceTracker, targets[0]);
4275 }
4276 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]);
4277 }
4278
4279 // If the outbound queue was previously empty, start the dispatch cycle going.
4280 if (wasEmpty && !connection->outboundQueue.empty()) {
4281 startDispatchCycleLocked(currentTime, connection);
4282 }
4283 }
4284
synthesizePointerDownEventsForConnectionLocked(const nsecs_t downTime,const std::shared_ptr<Connection> & connection,ftl::Flags<InputTarget::Flags> targetFlags,const std::unique_ptr<trace::EventTrackerInterface> & traceTracker)4285 void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
4286 const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
4287 ftl::Flags<InputTarget::Flags> targetFlags,
4288 const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) {
4289 if (connection->status != Connection::Status::NORMAL) {
4290 return;
4291 }
4292
4293 std::vector<std::unique_ptr<EventEntry>> downEvents =
4294 connection->inputState.synthesizePointerDownEvents(downTime);
4295
4296 if (downEvents.empty()) {
4297 return;
4298 }
4299
4300 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
4301 << "channel '" << connection->getInputChannelName() << "' ~ Synthesized "
4302 << downEvents.size() << " down events to ensure consistent event stream.";
4303
4304 const auto [windowHandle, displayId] =
4305 mTouchStates.findExistingTouchedWindowHandleAndDisplay(connection->getToken());
4306
4307 const bool wasEmpty = connection->outboundQueue.empty();
4308 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
4309 std::vector<InputTarget> targets{};
4310 switch (downEventEntry->type) {
4311 case EventEntry::Type::MOTION: {
4312 if (mTracer) {
4313 static_cast<MotionEntry&>(*downEventEntry).traceTracker =
4314 mTracer->traceDerivedEvent(*downEventEntry, *traceTracker);
4315 }
4316 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4317 if (windowHandle != nullptr) {
4318 std::bitset<MAX_POINTER_ID + 1> pointerIds;
4319 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
4320 pointerIndex++) {
4321 pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4322 }
4323 mTouchStates
4324 .addPointerWindowTarget(windowHandle, InputTarget::DispatchMode::AS_IS,
4325 targetFlags, pointerIds, motionEntry.downTime,
4326 /*pointerDisplayId=*/std::nullopt,
4327 std::bind_front(&InputDispatcher::
4328 logDispatchStateLocked,
4329 this),
4330 targets);
4331 } else {
4332 targets.emplace_back(connection, targetFlags);
4333 // Since we don't have a window, use the display transform as the raw transform.
4334 const ui::Transform displayTransform =
4335 mWindowInfos.getDisplayTransform(motionEntry.displayId);
4336 targets.back().rawTransform = displayTransform;
4337 targets.back().setDefaultPointerTransform(displayTransform);
4338 }
4339 logOutboundMotionDetails("down - ", motionEntry);
4340 break;
4341 }
4342
4343 case EventEntry::Type::KEY:
4344 case EventEntry::Type::FOCUS:
4345 case EventEntry::Type::TOUCH_MODE_CHANGED:
4346 case EventEntry::Type::DEVICE_RESET:
4347 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4348 case EventEntry::Type::SENSOR:
4349 case EventEntry::Type::DRAG: {
4350 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
4351 ftl::enum_string(downEventEntry->type).c_str());
4352 break;
4353 }
4354 }
4355
4356 if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
4357 if (mTracer) {
4358 mTracer->dispatchToTargetHint(*traceTracker, targets[0]);
4359 }
4360 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]);
4361 }
4362
4363 // If the outbound queue was previously empty, start the dispatch cycle going.
4364 if (wasEmpty && !connection->outboundQueue.empty()) {
4365 startDispatchCycleLocked(downTime, connection);
4366 }
4367 }
4368
splitMotionEvent(const MotionEntry & originalMotionEntry,std::bitset<MAX_POINTER_ID+1> pointerIds,nsecs_t splitDownTime)4369 std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
4370 const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4371 nsecs_t splitDownTime) {
4372 const auto& [action, pointerProperties, pointerCoords] =
4373 MotionEvent::split(originalMotionEntry.action, originalMotionEntry.flags,
4374 /*historySize=*/0, originalMotionEntry.pointerProperties,
4375 originalMotionEntry.pointerCoords, pointerIds);
4376 if (pointerIds.count() != pointerCoords.size()) {
4377 // TODO(b/329107108): Determine why some IDs in pointerIds were not in originalMotionEntry.
4378 // This is bad. We are missing some of the pointers that we expected to deliver.
4379 // Most likely this indicates that we received an ACTION_MOVE events that has
4380 // different pointer ids than we expected based on the previous ACTION_DOWN
4381 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4382 // in this way.
4383 ALOGW("Dropping split motion event because the pointer count is %zu but "
4384 "we expected there to be %zu pointers. This probably means we received "
4385 "a broken sequence of pointer ids from the input device: %s",
4386 pointerCoords.size(), pointerIds.count(),
4387 originalMotionEntry.getDescription().c_str());
4388 return nullptr;
4389 }
4390
4391 // TODO(b/327503168): Move this check inside MotionEvent::split once all callers handle it
4392 // correctly.
4393 if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4394 logDispatchStateLocked();
4395 LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4396 "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4397 originalMotionEntry.getDescription().c_str(), splitDownTime);
4398 }
4399
4400 int32_t newId = mIdGenerator.nextId();
4401 ATRACE_NAME_IF(ATRACE_ENABLED(),
4402 StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4403 ").",
4404 originalMotionEntry.id, newId));
4405 std::unique_ptr<MotionEntry> splitMotionEntry =
4406 std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4407 originalMotionEntry.eventTime,
4408 originalMotionEntry.deviceId, originalMotionEntry.source,
4409 originalMotionEntry.displayId,
4410 originalMotionEntry.policyFlags, action,
4411 originalMotionEntry.actionButton,
4412 originalMotionEntry.flags, originalMotionEntry.metaState,
4413 originalMotionEntry.buttonState,
4414 originalMotionEntry.classification,
4415 originalMotionEntry.edgeFlags,
4416 originalMotionEntry.xPrecision,
4417 originalMotionEntry.yPrecision,
4418 originalMotionEntry.xCursorPosition,
4419 originalMotionEntry.yCursorPosition, splitDownTime,
4420 pointerProperties, pointerCoords);
4421 if (mTracer) {
4422 splitMotionEntry->traceTracker =
4423 mTracer->traceDerivedEvent(*splitMotionEntry, *originalMotionEntry.traceTracker);
4424 }
4425
4426 return splitMotionEntry;
4427 }
4428
notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs & args)4429 void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4430 std::scoped_lock _l(mLock);
4431 // Reset key repeating in case a keyboard device was added or removed or something.
4432 resetKeyRepeatLocked();
4433 mInputDevices = args.inputDeviceInfos;
4434 }
4435
notifyKey(const NotifyKeyArgs & args)4436 void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
4437 LOG_IF(INFO, debugInboundEventDetails())
4438 << "notifyKey - id=" << args.id << ", eventTime=" << args.eventTime
4439 << ", deviceId=" << args.deviceId
4440 << ", source=" << inputEventSourceToString(args.source)
4441 << ", displayId=" << args.displayId.toString() << ", policyFlags=0x" << std::hex
4442 << args.policyFlags << ", action=" << KeyEvent::actionToString(args.action)
4443 << ", flags=0x" << args.flags << ", keyCode=" << KeyEvent::getLabel(args.keyCode)
4444 << ", scanCode=0x" << args.scanCode << ", metaState=0x" << args.metaState
4445 << ", downTime=" << std::dec << args.downTime;
4446 Result<void> keyCheck = validateKeyEvent(args.action);
4447 if (!keyCheck.ok()) {
4448 LOG(ERROR) << "invalid key event: " << keyCheck.error();
4449 return;
4450 }
4451
4452 uint32_t policyFlags = args.policyFlags;
4453 int32_t flags = args.flags;
4454 int32_t metaState = args.metaState;
4455 // InputDispatcher tracks and generates key repeats on behalf of
4456 // whatever notifies it, so repeatCount should always be set to 0
4457 constexpr int32_t repeatCount = 0;
4458 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4459 policyFlags |= POLICY_FLAG_VIRTUAL;
4460 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4461 }
4462 if (policyFlags & POLICY_FLAG_FUNCTION) {
4463 metaState |= AMETA_FUNCTION_ON;
4464 }
4465
4466 policyFlags |= POLICY_FLAG_TRUSTED;
4467
4468 int32_t keyCode = args.keyCode;
4469 KeyEvent event;
4470 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4471 flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4472 args.eventTime);
4473
4474 android::base::Timer t;
4475 mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
4476 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4477 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4478 std::to_string(t.duration().count()).c_str());
4479 }
4480
4481 bool needWake = false;
4482 { // acquire lock
4483 mLock.lock();
4484
4485 if (input_flags::keyboard_repeat_keys() && !mConfig.keyRepeatEnabled) {
4486 policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
4487 }
4488
4489 if (shouldSendKeyToInputFilterLocked(args)) {
4490 mLock.unlock();
4491
4492 policyFlags |= POLICY_FLAG_FILTERED;
4493 if (!mPolicy.filterInputEvent(event, policyFlags)) {
4494 return; // event was consumed by the filter
4495 }
4496
4497 mLock.lock();
4498 }
4499
4500 std::unique_ptr<KeyEntry> newEntry =
4501 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4502 args.deviceId, args.source, args.displayId, policyFlags,
4503 args.action, flags, keyCode, args.scanCode, metaState,
4504 repeatCount, args.downTime);
4505 if (mTracer) {
4506 newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
4507 }
4508
4509 if (mPerDeviceInputLatencyMetricsFlag) {
4510 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4511 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
4512 !mInputFilterEnabled) {
4513 mLatencyTracker.trackListener(args);
4514 }
4515 }
4516
4517 needWake = enqueueInboundEventLocked(std::move(newEntry));
4518 mLock.unlock();
4519 } // release lock
4520
4521 if (needWake) {
4522 mLooper->wake();
4523 }
4524 }
4525
shouldSendKeyToInputFilterLocked(const NotifyKeyArgs & args)4526 bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
4527 return mInputFilterEnabled;
4528 }
4529
notifyMotion(const NotifyMotionArgs & args)4530 void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
4531 if (debugInboundEventDetails()) {
4532 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
4533 "displayId=%s, policyFlags=0x%x, "
4534 "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
4535 "xCursorPosition=%f, yCursorPosition=%f, downTime=%" PRId64,
4536 args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4537 args.displayId.toString().c_str(), args.policyFlags,
4538 MotionEvent::actionToString(args.action).c_str(), args.actionButton, args.flags,
4539 args.metaState, args.buttonState, args.xCursorPosition, args.yCursorPosition,
4540 args.downTime);
4541 for (uint32_t i = 0; i < args.getPointerCount(); i++) {
4542 ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4543 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
4544 i, args.pointerProperties[i].id,
4545 ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4546 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4547 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4548 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4549 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4550 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4551 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4552 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4553 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4554 args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4555 }
4556 }
4557
4558 Result<void> motionCheck =
4559 validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4560 args.pointerProperties.data());
4561 if (!motionCheck.ok()) {
4562 LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
4563 return;
4564 }
4565
4566 if (DEBUG_VERIFY_EVENTS) {
4567 auto [it, _] =
4568 mVerifiersByDisplay.try_emplace(args.displayId,
4569 StringPrintf("display %s",
4570 args.displayId.toString().c_str()));
4571 Result<void> result =
4572 it->second.processMovement(args.deviceId, args.source, args.action,
4573 args.actionButton, args.getPointerCount(),
4574 args.pointerProperties.data(), args.pointerCoords.data(),
4575 args.flags, args.buttonState);
4576 if (!result.ok()) {
4577 LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4578 }
4579 }
4580
4581 uint32_t policyFlags = args.policyFlags;
4582 policyFlags |= POLICY_FLAG_TRUSTED;
4583
4584 android::base::Timer t;
4585 mPolicy.interceptMotionBeforeQueueing(args.displayId, args.source, args.action, args.eventTime,
4586 policyFlags);
4587 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4588 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4589 std::to_string(t.duration().count()).c_str());
4590 }
4591
4592 bool needWake = false;
4593 { // acquire lock
4594 mLock.lock();
4595 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4596 // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4597 // complete the processing of the current stroke.
4598 if (mTouchStates.hasTouchingOrHoveringPointers(args.displayId, args.deviceId)) {
4599 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4600 }
4601 }
4602
4603 if (shouldSendMotionToInputFilterLocked(args)) {
4604 ui::Transform displayTransform = mWindowInfos.getDisplayTransform(args.displayId);
4605
4606 mLock.unlock();
4607
4608 MotionEvent event;
4609 event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4610 args.action, args.actionButton, args.flags, args.edgeFlags,
4611 args.metaState, args.buttonState, args.classification,
4612 displayTransform, args.xPrecision, args.yPrecision,
4613 args.xCursorPosition, args.yCursorPosition, displayTransform,
4614 args.downTime, args.eventTime, args.getPointerCount(),
4615 args.pointerProperties.data(), args.pointerCoords.data());
4616
4617 policyFlags |= POLICY_FLAG_FILTERED;
4618 if (!mPolicy.filterInputEvent(event, policyFlags)) {
4619 return; // event was consumed by the filter
4620 }
4621
4622 mLock.lock();
4623 }
4624
4625 // Just enqueue a new motion event.
4626 std::unique_ptr<MotionEntry> newEntry =
4627 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4628 args.deviceId, args.source, args.displayId,
4629 policyFlags, args.action, args.actionButton,
4630 args.flags, args.metaState, args.buttonState,
4631 args.classification, args.edgeFlags, args.xPrecision,
4632 args.yPrecision, args.xCursorPosition,
4633 args.yCursorPosition, args.downTime,
4634 args.pointerProperties, args.pointerCoords);
4635 if (mTracer) {
4636 newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
4637 }
4638
4639 if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4640 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
4641 !mInputFilterEnabled) {
4642 mLatencyTracker.trackListener(args);
4643 }
4644
4645 needWake = enqueueInboundEventLocked(std::move(newEntry));
4646 mLock.unlock();
4647 } // release lock
4648
4649 if (needWake) {
4650 mLooper->wake();
4651 }
4652 }
4653
notifySensor(const NotifySensorArgs & args)4654 void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
4655 LOG_IF(INFO, debugInboundEventDetails())
4656 << "notifySensor - id=" << args.id << " eventTime=" << args.eventTime
4657 << ", deviceId=" << args.deviceId << ", source=0x" << std::hex << args.source
4658 << std::dec << ", sensorType=" << ftl::enum_string(args.sensorType);
4659
4660 bool needWake = false;
4661 { // acquire lock
4662 mLock.lock();
4663
4664 // Just enqueue a new sensor event.
4665 std::unique_ptr<SensorEntry> newEntry =
4666 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4667 /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4668 args.accuracy, args.accuracyChanged, args.values);
4669
4670 needWake = enqueueInboundEventLocked(std::move(newEntry));
4671 mLock.unlock();
4672 } // release lock
4673
4674 if (needWake) {
4675 mLooper->wake();
4676 }
4677 }
4678
notifyVibratorState(const NotifyVibratorStateArgs & args)4679 void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
4680 LOG_IF(INFO, debugInboundEventDetails())
4681 << "notifyVibratorState - eventTime=" << args.eventTime << ", device=" << args.deviceId
4682 << ", isOn=" << args.isOn;
4683 mPolicy.notifyVibratorState(args.deviceId, args.isOn);
4684 }
4685
shouldSendMotionToInputFilterLocked(const NotifyMotionArgs & args)4686 bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
4687 return mInputFilterEnabled;
4688 }
4689
notifySwitch(const NotifySwitchArgs & args)4690 void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
4691 LOG_IF(INFO, debugInboundEventDetails())
4692 << "notifySwitch - eventTime=" << args.eventTime << ", policyFlags=0x" << std::hex
4693 << args.policyFlags << ", switchValues=0x" << std::setfill('0') << std::setw(8)
4694 << args.switchValues << ", switchMask=0x" << std::setw(8) << args.switchMask;
4695
4696 uint32_t policyFlags = args.policyFlags;
4697 policyFlags |= POLICY_FLAG_TRUSTED;
4698 mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
4699 }
4700
notifyDeviceReset(const NotifyDeviceResetArgs & args)4701 void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
4702 // TODO(b/308677868) Remove device reset from the InputListener interface
4703 LOG_IF(INFO, debugInboundEventDetails())
4704 << "notifyDeviceReset - eventTime=" << args.eventTime << ", deviceId=" << args.deviceId;
4705
4706 bool needWake = false;
4707 { // acquire lock
4708 std::scoped_lock _l(mLock);
4709
4710 std::unique_ptr<DeviceResetEntry> newEntry =
4711 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
4712 needWake = enqueueInboundEventLocked(std::move(newEntry));
4713
4714 for (auto& [_, verifier] : mVerifiersByDisplay) {
4715 verifier.resetDevice(args.deviceId);
4716 }
4717 } // release lock
4718
4719 if (needWake) {
4720 mLooper->wake();
4721 }
4722 }
4723
notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs & args)4724 void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
4725 LOG_IF(INFO, debugInboundEventDetails())
4726 << "notifyPointerCaptureChanged - eventTime=%" << args.eventTime
4727 << ", enabled=" << toString(args.request.isEnable());
4728
4729 bool needWake = false;
4730 { // acquire lock
4731 std::scoped_lock _l(mLock);
4732 auto entry =
4733 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
4734 needWake = enqueueInboundEventLocked(std::move(entry));
4735 } // release lock
4736
4737 if (needWake) {
4738 mLooper->wake();
4739 }
4740 }
4741
shouldRejectInjectedMotionLocked(const MotionEvent & motionEvent,DeviceId deviceId,ui::LogicalDisplayId displayId,std::optional<gui::Uid> targetUid,int32_t flags)4742 bool InputDispatcher::shouldRejectInjectedMotionLocked(const MotionEvent& motionEvent,
4743 DeviceId deviceId,
4744 ui::LogicalDisplayId displayId,
4745 std::optional<gui::Uid> targetUid,
4746 int32_t flags) {
4747 // Don't verify targeted injection, since it will only affect the caller's
4748 // window, and the windows are typically destroyed at the end of the test.
4749 if (targetUid.has_value()) {
4750 return false;
4751 }
4752
4753 // Verify all other injected streams, whether the injection is coming from apps or from
4754 // input filter. Print an error if the stream becomes inconsistent with this event.
4755 // An inconsistent injected event sent could cause a crash in the later stages of
4756 // dispatching pipeline.
4757 auto [it, _] = mInputFilterVerifiersByDisplay.try_emplace(displayId,
4758 std::string("Injection on ") +
4759 displayId.toString());
4760 InputVerifier& verifier = it->second;
4761
4762 Result<void> result =
4763 verifier.processMovement(deviceId, motionEvent.getSource(), motionEvent.getAction(),
4764 motionEvent.getActionButton(), motionEvent.getPointerCount(),
4765 motionEvent.getPointerProperties(),
4766 motionEvent.getSamplePointerCoords(), flags,
4767 motionEvent.getButtonState());
4768 if (!result.ok()) {
4769 logDispatchStateLocked();
4770 LOG(ERROR) << "Inconsistent event: " << motionEvent << ", reason: " << result.error();
4771 return true;
4772 }
4773 return false;
4774 }
4775
injectInputEvent(const InputEvent * event,std::optional<gui::Uid> targetUid,InputEventInjectionSync syncMode,std::chrono::milliseconds timeout,uint32_t policyFlags)4776 InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
4777 std::optional<gui::Uid> targetUid,
4778 InputEventInjectionSync syncMode,
4779 std::chrono::milliseconds timeout,
4780 uint32_t policyFlags) {
4781 Result<void> eventValidation = validateInputEvent(*event);
4782 if (!eventValidation.ok()) {
4783 LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4784 return InputEventInjectionResult::FAILED;
4785 }
4786
4787 LOG_IF(INFO, debugInboundEventDetails())
4788 << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4789 << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4790 << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec << ", event=" << *event;
4791 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
4792
4793 policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
4794
4795 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
4796 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4797 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4798 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4799 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4800 // from events that originate from actual hardware.
4801 DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
4802 if (policyFlags & POLICY_FLAG_FILTERED) {
4803 resolvedDeviceId = event->getDeviceId();
4804 }
4805
4806 const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4807 auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4808
4809 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
4810 switch (event->getType()) {
4811 case InputEventType::KEY: {
4812 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4813 const int32_t action = incomingKey.getAction();
4814 int32_t flags = incomingKey.getFlags();
4815 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4816 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4817 }
4818 int32_t keyCode = incomingKey.getKeyCode();
4819 int32_t metaState = incomingKey.getMetaState();
4820 KeyEvent keyEvent;
4821 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
4822 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4823 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4824 incomingKey.getDownTime(), incomingKey.getEventTime());
4825
4826 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4827 policyFlags |= POLICY_FLAG_VIRTUAL;
4828 }
4829
4830 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4831 android::base::Timer t;
4832 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
4833 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4834 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4835 std::to_string(t.duration().count()).c_str());
4836 }
4837 }
4838
4839 mLock.lock();
4840 std::unique_ptr<KeyEntry> injectedEntry =
4841 std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4842 incomingKey.getEventTime(), resolvedDeviceId,
4843 incomingKey.getSource(), incomingKey.getDisplayId(),
4844 policyFlags, action, flags, keyCode,
4845 incomingKey.getScanCode(), metaState,
4846 incomingKey.getRepeatCount(),
4847 incomingKey.getDownTime());
4848 if (mTracer) {
4849 injectedEntry->traceTracker = mTracer->traceInboundEvent(*injectedEntry);
4850 }
4851 injectedEntries.push(std::move(injectedEntry));
4852 break;
4853 }
4854
4855 case InputEventType::MOTION: {
4856 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4857 const bool isPointerEvent =
4858 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4859 // If a pointer event has no displayId specified, inject it to the default display.
4860 const ui::LogicalDisplayId displayId =
4861 isPointerEvent && (event->getDisplayId() == ui::LogicalDisplayId::INVALID)
4862 ? ui::LogicalDisplayId::DEFAULT
4863 : event->getDisplayId();
4864 int32_t flags = motionEvent.getFlags();
4865
4866 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4867 nsecs_t eventTime = motionEvent.getEventTime();
4868 android::base::Timer t;
4869 mPolicy.interceptMotionBeforeQueueing(displayId, motionEvent.getSource(),
4870 motionEvent.getAction(), eventTime,
4871 /*byref*/ policyFlags);
4872 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4873 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4874 std::to_string(t.duration().count()).c_str());
4875 }
4876 }
4877
4878 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4879 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4880 }
4881
4882 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL) {
4883 flags |= AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL;
4884 }
4885
4886 mLock.lock();
4887
4888 if (shouldRejectInjectedMotionLocked(motionEvent, resolvedDeviceId, displayId,
4889 targetUid, flags)) {
4890 mLock.unlock();
4891 return InputEventInjectionResult::FAILED;
4892 }
4893
4894 if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4895 // Set the flag anyway if we already have an ongoing motion gesture. That
4896 // would allow us to complete the processing of the current stroke.
4897 if (mTouchStates.hasTouchingOrHoveringPointers(displayId, resolvedDeviceId)) {
4898 policyFlags |= POLICY_FLAG_PASS_TO_USER;
4899 }
4900 }
4901
4902 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4903 const size_t pointerCount = motionEvent.getPointerCount();
4904 const std::vector<PointerProperties>
4905 pointerProperties(motionEvent.getPointerProperties(),
4906 motionEvent.getPointerProperties() + pointerCount);
4907
4908 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
4909 std::unique_ptr<MotionEntry> injectedEntry =
4910 std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4911 *sampleEventTimes, resolvedDeviceId,
4912 motionEvent.getSource(), displayId, policyFlags,
4913 motionEvent.getAction(),
4914 motionEvent.getActionButton(), flags,
4915 motionEvent.getMetaState(),
4916 motionEvent.getButtonState(),
4917 motionEvent.getClassification(),
4918 motionEvent.getEdgeFlags(),
4919 motionEvent.getXPrecision(),
4920 motionEvent.getYPrecision(),
4921 motionEvent.getRawXCursorPosition(),
4922 motionEvent.getRawYCursorPosition(),
4923 motionEvent.getDownTime(), pointerProperties,
4924 std::vector<PointerCoords>(samplePointerCoords,
4925 samplePointerCoords +
4926 pointerCount));
4927 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
4928 if (mTracer) {
4929 injectedEntry->traceTracker = mTracer->traceInboundEvent(*injectedEntry);
4930 }
4931 injectedEntries.push(std::move(injectedEntry));
4932 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
4933 sampleEventTimes += 1;
4934 samplePointerCoords += motionEvent.getPointerCount();
4935 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
4936 MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4937 resolvedDeviceId, motionEvent.getSource(), displayId,
4938 policyFlags, motionEvent.getAction(),
4939 motionEvent.getActionButton(), flags,
4940 motionEvent.getMetaState(), motionEvent.getButtonState(),
4941 motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4942 motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4943 motionEvent.getRawXCursorPosition(),
4944 motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4945 pointerProperties,
4946 std::vector<PointerCoords>(samplePointerCoords,
4947 samplePointerCoords +
4948 pointerCount));
4949 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4950 motionEvent.getTransform());
4951 if (mTracer) {
4952 nextInjectedEntry->traceTracker =
4953 mTracer->traceInboundEvent(*nextInjectedEntry);
4954 }
4955 injectedEntries.push(std::move(nextInjectedEntry));
4956 }
4957 break;
4958 }
4959
4960 default:
4961 LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
4962 return InputEventInjectionResult::FAILED;
4963 }
4964
4965 bool needWake = false;
4966 while (!injectedEntries.empty()) {
4967 LOG_IF(INFO, DEBUG_INJECTION) << "Injecting " << injectedEntries.front()->getDescription();
4968 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
4969 injectedEntries.pop();
4970 }
4971
4972 mLock.unlock();
4973
4974 if (needWake) {
4975 mLooper->wake();
4976 }
4977
4978 InputEventInjectionResult injectionResult;
4979 { // acquire lock
4980 std::unique_lock _l(mLock);
4981
4982 if (syncMode == InputEventInjectionSync::NONE) {
4983 injectionResult = InputEventInjectionResult::SUCCEEDED;
4984 } else {
4985 for (;;) {
4986 injectionResult = injectionState->injectionResult;
4987 if (injectionResult != InputEventInjectionResult::PENDING) {
4988 break;
4989 }
4990
4991 nsecs_t remainingTimeout = endTime - now();
4992 if (remainingTimeout <= 0) {
4993 LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Timed out waiting for "
4994 "injection result to become available.";
4995 injectionResult = InputEventInjectionResult::TIMED_OUT;
4996 break;
4997 }
4998
4999 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
5000 }
5001
5002 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
5003 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
5004 while (injectionState->pendingForegroundDispatches != 0) {
5005 LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Waiting for "
5006 << injectionState->pendingForegroundDispatches
5007 << " pending foreground dispatches.";
5008 nsecs_t remainingTimeout = endTime - now();
5009 if (remainingTimeout <= 0) {
5010 LOG_IF(INFO, DEBUG_INJECTION)
5011 << "injectInputEvent - Timed out waiting for pending foreground "
5012 "dispatches to finish.";
5013 injectionResult = InputEventInjectionResult::TIMED_OUT;
5014 break;
5015 }
5016
5017 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
5018 }
5019 }
5020 }
5021 } // release lock
5022
5023 LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Finished with result "
5024 << ftl::enum_string(injectionResult);
5025
5026 return injectionResult;
5027 }
5028
verifyInputEvent(const InputEvent & event)5029 std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
5030 std::array<uint8_t, 32> calculatedHmac;
5031 std::unique_ptr<VerifiedInputEvent> result;
5032 switch (event.getType()) {
5033 case InputEventType::KEY: {
5034 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
5035 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
5036 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
5037 calculatedHmac = sign(verifiedKeyEvent);
5038 break;
5039 }
5040 case InputEventType::MOTION: {
5041 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
5042 VerifiedMotionEvent verifiedMotionEvent =
5043 verifiedMotionEventFromMotionEvent(motionEvent);
5044 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
5045 calculatedHmac = sign(verifiedMotionEvent);
5046 break;
5047 }
5048 default: {
5049 LOG(ERROR) << "Cannot verify events of type " << ftl::enum_string(event.getType());
5050 return nullptr;
5051 }
5052 }
5053 if (calculatedHmac == INVALID_HMAC) {
5054 return nullptr;
5055 }
5056 if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
5057 return nullptr;
5058 }
5059 return result;
5060 }
5061
setInjectionResult(const EventEntry & entry,InputEventInjectionResult injectionResult)5062 void InputDispatcher::setInjectionResult(const EventEntry& entry,
5063 InputEventInjectionResult injectionResult) {
5064 if (!entry.injectionState) {
5065 // Not an injected event.
5066 return;
5067 }
5068
5069 InjectionState& injectionState = *entry.injectionState;
5070 LOG_IF(INFO, DEBUG_INJECTION) << "Setting input event injection result to "
5071 << ftl::enum_string(injectionResult);
5072
5073 if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
5074 // Log the outcome since the injector did not wait for the injection result.
5075 switch (injectionResult) {
5076 case InputEventInjectionResult::SUCCEEDED:
5077 ALOGV("Asynchronous input event injection succeeded.");
5078 break;
5079 case InputEventInjectionResult::TARGET_MISMATCH:
5080 ALOGV("Asynchronous input event injection target mismatch.");
5081 break;
5082 case InputEventInjectionResult::FAILED:
5083 ALOGW("Asynchronous input event injection failed.");
5084 break;
5085 case InputEventInjectionResult::TIMED_OUT:
5086 ALOGW("Asynchronous input event injection timed out.");
5087 break;
5088 case InputEventInjectionResult::PENDING:
5089 ALOGE("Setting result to 'PENDING' for asynchronous injection");
5090 break;
5091 }
5092 }
5093
5094 injectionState.injectionResult = injectionResult;
5095 mInjectionResultAvailable.notify_all();
5096 }
5097
transformMotionEntryForInjectionLocked(MotionEntry & entry,const ui::Transform & injectedTransform) const5098 void InputDispatcher::transformMotionEntryForInjectionLocked(
5099 MotionEntry& entry, const ui::Transform& injectedTransform) const {
5100 // Input injection works in the logical display coordinate space, but the input pipeline works
5101 // display space, so we need to transform the injected events accordingly.
5102 const ui::Transform displayTransform = mWindowInfos.getDisplayTransform(entry.displayId);
5103 const auto& transformToDisplay = displayTransform.inverse() * injectedTransform;
5104
5105 if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
5106 entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
5107 const vec2 cursor =
5108 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
5109 {entry.xCursorPosition, entry.yCursorPosition});
5110 entry.xCursorPosition = cursor.x;
5111 entry.yCursorPosition = cursor.y;
5112 }
5113 for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
5114 entry.pointerCoords[i] =
5115 MotionEvent::calculateTransformedCoords(entry.source, entry.flags,
5116 transformToDisplay, entry.pointerCoords[i]);
5117 }
5118 }
5119
incrementPendingForegroundDispatches(const EventEntry & entry)5120 void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
5121 if (entry.injectionState) {
5122 entry.injectionState->pendingForegroundDispatches += 1;
5123 }
5124 }
5125
decrementPendingForegroundDispatches(const EventEntry & entry)5126 void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
5127 if (entry.injectionState) {
5128 entry.injectionState->pendingForegroundDispatches -= 1;
5129
5130 if (entry.injectionState->pendingForegroundDispatches == 0) {
5131 mInjectionSyncFinished.notify_all();
5132 }
5133 }
5134 }
5135
findWindowHandle(const sp<IBinder> & windowHandleToken,std::optional<ui::LogicalDisplayId> displayId) const5136 sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandle(
5137 const sp<IBinder>& windowHandleToken, std::optional<ui::LogicalDisplayId> displayId) const {
5138 if (windowHandleToken == nullptr) {
5139 return nullptr;
5140 }
5141
5142 if (!displayId) {
5143 // Look through all displays.
5144 for (const auto& [_, windowHandles] : mWindowHandlesByDisplay) {
5145 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
5146 if (windowHandle->getToken() == windowHandleToken) {
5147 return windowHandle;
5148 }
5149 }
5150 }
5151 return nullptr;
5152 }
5153
5154 // Only look through the requested display.
5155 return findWindowHandleOnDisplay(windowHandleToken, *displayId);
5156 }
5157
findWindowHandleOnConnectedDisplays(const sp<IBinder> & windowHandleToken,ui::LogicalDisplayId displayId) const5158 sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandleOnConnectedDisplays(
5159 const sp<IBinder>& windowHandleToken, ui::LogicalDisplayId displayId) const {
5160 if (windowHandleToken == nullptr) {
5161 return nullptr;
5162 }
5163
5164 sp<WindowInfoHandle> windowHandle;
5165 for (ui::LogicalDisplayId connectedDisplayId : getConnectedDisplays(displayId)) {
5166 windowHandle = findWindowHandleOnDisplay(windowHandleToken, connectedDisplayId);
5167 if (windowHandle != nullptr) {
5168 return windowHandle;
5169 }
5170 }
5171 return nullptr;
5172 }
5173
isWindowPresent(const sp<WindowInfoHandle> & windowHandle) const5174 bool InputDispatcher::DispatcherWindowInfo::isWindowPresent(
5175 const sp<WindowInfoHandle>& windowHandle) const {
5176 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5177 for (const sp<WindowInfoHandle>& handle : windowHandles) {
5178 if (handle->getId() == windowHandle->getId() &&
5179 handle->getToken() == windowHandle->getToken()) {
5180 if (windowHandle->getInfo()->displayId != displayId) {
5181 ALOGE("Found window %s in display %s"
5182 ", but it should belong to display %s",
5183 windowHandle->getName().c_str(), displayId.toString().c_str(),
5184 windowHandle->getInfo()->displayId.toString().c_str());
5185 }
5186 return true;
5187 }
5188 }
5189 }
5190 return false;
5191 }
5192
getFocusedWindowHandleLocked(ui::LogicalDisplayId displayId) const5193 sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(
5194 ui::LogicalDisplayId displayId) const {
5195 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
5196 return mWindowInfos.findWindowHandle(focusedToken, displayId);
5197 }
5198
setWindowHandlesForDisplay(ui::LogicalDisplayId displayId,std::vector<sp<WindowInfoHandle>> && windowHandles)5199 void InputDispatcher::DispatcherWindowInfo::setWindowHandlesForDisplay(
5200 ui::LogicalDisplayId displayId, std::vector<sp<WindowInfoHandle>>&& windowHandles) {
5201 // Insert or replace
5202 mWindowHandlesByDisplay[displayId] = std::move(windowHandles);
5203 }
5204
setDisplayInfos(const std::vector<android::gui::DisplayInfo> & displayInfos)5205 void InputDispatcher::DispatcherWindowInfo::setDisplayInfos(
5206 const std::vector<android::gui::DisplayInfo>& displayInfos) {
5207 mDisplayInfos.clear();
5208 for (const auto& displayInfo : displayInfos) {
5209 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
5210 }
5211 }
5212
removeDisplay(ui::LogicalDisplayId displayId)5213 void InputDispatcher::DispatcherWindowInfo::removeDisplay(ui::LogicalDisplayId displayId) {
5214 mWindowHandlesByDisplay.erase(displayId);
5215 }
5216
5217 const std::vector<sp<android::gui::WindowInfoHandle>>&
getWindowHandlesForDisplay(ui::LogicalDisplayId displayId) const5218 InputDispatcher::DispatcherWindowInfo::getWindowHandlesForDisplay(
5219 ui::LogicalDisplayId displayId) const {
5220 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
5221 const auto it = mWindowHandlesByDisplay.find(displayId);
5222 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
5223 }
5224
forEachWindowHandle(std::function<void (const sp<android::gui::WindowInfoHandle> &)> f) const5225 void InputDispatcher::DispatcherWindowInfo::forEachWindowHandle(
5226 std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const {
5227 for (const auto& [_, windowHandles] : mWindowHandlesByDisplay) {
5228 for (const auto& windowHandle : windowHandles) {
5229 f(windowHandle);
5230 }
5231 }
5232 }
5233
forEachDisplayId(std::function<void (ui::LogicalDisplayId)> f) const5234 void InputDispatcher::DispatcherWindowInfo::forEachDisplayId(
5235 std::function<void(ui::LogicalDisplayId)> f) const {
5236 for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
5237 f(displayId);
5238 }
5239 }
5240
getDisplayTransform(ui::LogicalDisplayId displayId) const5241 ui::Transform InputDispatcher::DispatcherWindowInfo::getDisplayTransform(
5242 ui::LogicalDisplayId displayId) const {
5243 auto displayInfoIt = mDisplayInfos.find(displayId);
5244 return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
5245 : kIdentityTransform;
5246 }
5247
getRawTransform(const android::gui::WindowInfo & windowInfo,std::optional<ui::LogicalDisplayId> pointerDisplayId) const5248 ui::Transform InputDispatcher::DispatcherWindowInfo::getRawTransform(
5249 const android::gui::WindowInfo& windowInfo,
5250 std::optional<ui::LogicalDisplayId> pointerDisplayId) const {
5251 // TODO(b/383092013): Handle TOPOLOGY_AWARE window flag.
5252 // For now, we assume all windows are topology-aware and can handle cross-display streams.
5253 if (com::android::input::flags::connected_displays_cursor() && pointerDisplayId.has_value() &&
5254 *pointerDisplayId != windowInfo.displayId) {
5255 // Sending pointer to a different display than the window. This is a
5256 // cross-display drag gesture, so always use the new display's transform.
5257 return getDisplayTransform(*pointerDisplayId);
5258 }
5259 // If the window has a cloneLayerStackTransform, always use it as the transform for the "getRaw"
5260 // APIs. If not, fall back to using the DisplayInfo transform of the window's display
5261 bool useClonedScreenCoordinates = (input_flags::use_cloned_screen_coordinates_as_raw() &&
5262 windowInfo.cloneLayerStackTransform);
5263 if (useClonedScreenCoordinates) {
5264 return *windowInfo.cloneLayerStackTransform;
5265 }
5266 return getDisplayTransform(windowInfo.displayId);
5267 }
5268
getPrimaryDisplayId(ui::LogicalDisplayId displayId) const5269 ui::LogicalDisplayId InputDispatcher::DispatcherWindowInfo::getPrimaryDisplayId(
5270 ui::LogicalDisplayId displayId) const {
5271 if (mTopology.graph.contains(displayId)) {
5272 return mTopology.primaryDisplayId;
5273 }
5274 return displayId;
5275 }
5276
areDisplaysConnected(ui::LogicalDisplayId display1,ui::LogicalDisplayId display2) const5277 bool InputDispatcher::DispatcherWindowInfo::areDisplaysConnected(
5278 ui::LogicalDisplayId display1, ui::LogicalDisplayId display2) const {
5279 return display1 == display2 ||
5280 (mTopology.graph.contains(display1) && mTopology.graph.contains(display2));
5281 }
5282
dumpDisplayAndWindowInfo() const5283 std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const {
5284 std::string dump;
5285 if (!mWindowHandlesByDisplay.empty()) {
5286 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5287 dump += StringPrintf("Display: %s\n", displayId.toString().c_str());
5288 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5289 const auto& displayInfo = it->second;
5290 dump += StringPrintf(INDENT "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5291 displayInfo.logicalHeight);
5292 displayInfo.transform.dump(dump, "transform", INDENT3);
5293 } else {
5294 dump += INDENT "No DisplayInfo found!\n";
5295 }
5296
5297 if (!windowHandles.empty()) {
5298 dump += INDENT "Windows:\n";
5299 for (size_t i = 0; i < windowHandles.size(); i++) {
5300 dump += StringPrintf(INDENT2 "%zu: %s", i,
5301 streamableToString(*windowHandles[i]).c_str());
5302 }
5303 } else {
5304 dump += INDENT "Windows: <none>\n";
5305 }
5306 }
5307 } else {
5308 dump += "Displays: <none>\n";
5309 }
5310 dump += StringPrintf("mMaximumObscuringOpacityForTouch: %f\n",
5311 mMaximumObscuringOpacityForTouch);
5312 dump += "DisplayTopologyGraph:\n";
5313 dump += addLinePrefix(mTopology.dump(), INDENT);
5314 dump += "\n";
5315 return dump;
5316 }
5317
getConnectedDisplays(ui::LogicalDisplayId displayId) const5318 std::vector<ui::LogicalDisplayId> InputDispatcher::DispatcherWindowInfo::getConnectedDisplays(
5319 ui::LogicalDisplayId displayId) const {
5320 if (!mTopology.graph.contains(displayId)) {
5321 return {displayId};
5322 }
5323
5324 std::vector<ui::LogicalDisplayId> connectedDisplays;
5325 for (auto it : mTopology.graph) {
5326 connectedDisplays.push_back(it.first);
5327 }
5328 return connectedDisplays;
5329 }
5330
findWindowHandleOnDisplay(const sp<IBinder> & windowHandleToken,ui::LogicalDisplayId displayId) const5331 sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandleOnDisplay(
5332 const sp<IBinder>& windowHandleToken, ui::LogicalDisplayId displayId) const {
5333 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesForDisplay(displayId)) {
5334 if (windowHandle->getToken() == windowHandleToken) {
5335 return windowHandle;
5336 }
5337 }
5338 return nullptr;
5339 }
5340
canWindowReceiveMotion(const sp<android::gui::WindowInfoHandle> & window,const android::inputdispatcher::MotionEntry & motionEntry) const5341 bool InputDispatcher::DispatcherTouchState::canWindowReceiveMotion(
5342 const sp<android::gui::WindowInfoHandle>& window,
5343 const android::inputdispatcher::MotionEntry& motionEntry) const {
5344 const WindowInfo& info = *window->getInfo();
5345
5346 // Skip spy window targets that are not valid for targeted injection.
5347 if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
5348 return false;
5349 }
5350
5351 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5352 ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5353 return false;
5354 }
5355
5356 if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5357 ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5358 window->getName().c_str());
5359 return false;
5360 }
5361
5362 std::shared_ptr<Connection> connection = mConnectionManager.getConnection(window->getToken());
5363 if (connection == nullptr) {
5364 ALOGW("Not sending touch to %s because there's no corresponding connection",
5365 window->getName().c_str());
5366 return false;
5367 }
5368
5369 if (!connection->responsive) {
5370 ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
5371 return false;
5372 }
5373
5374 // Drop events that can't be trusted due to occlusion
5375 const auto [x, y] = resolveTouchedPosition(motionEntry);
5376 DispatcherWindowInfo::TouchOcclusionInfo occlusionInfo =
5377 mWindowInfos.computeTouchOcclusionInfo(window, x, y);
5378 if (!mWindowInfos.isTouchTrusted(occlusionInfo)) {
5379 if (DEBUG_TOUCH_OCCLUSION) {
5380 ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
5381 for (const auto& log : occlusionInfo.debugInfo) {
5382 ALOGD("%s", log.c_str());
5383 }
5384 }
5385 ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5386 occlusionInfo.obscuringUid.toString().c_str());
5387 return false;
5388 }
5389
5390 // Drop touch events if requested by input feature
5391 if (shouldDropInput(motionEntry, window, mWindowInfos)) {
5392 return false;
5393 }
5394
5395 // Ignore touches if stylus is down anywhere on screen
5396 if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
5397 isStylusActiveInDisplay(info.displayId)) {
5398 LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
5399 return false;
5400 }
5401
5402 return true;
5403 }
5404
updateWindowHandlesForDisplayLocked(const std::vector<sp<WindowInfoHandle>> & windowInfoHandles,ui::LogicalDisplayId displayId)5405 void InputDispatcher::updateWindowHandlesForDisplayLocked(
5406 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles,
5407 ui::LogicalDisplayId displayId) {
5408 if (windowInfoHandles.empty()) {
5409 // Remove all handles on a display if there are no windows left.
5410 mWindowInfos.removeDisplay(displayId);
5411 return;
5412 }
5413
5414 // Since we compare the pointer of input window handles across window updates, we need
5415 // to make sure the handle object for the same window stays unchanged across updates.
5416 const std::vector<sp<WindowInfoHandle>>& oldHandles =
5417 mWindowInfos.getWindowHandlesForDisplay(displayId);
5418 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5419 for (const sp<WindowInfoHandle>& handle : oldHandles) {
5420 oldHandlesById[handle->getId()] = handle;
5421 }
5422
5423 std::vector<sp<WindowInfoHandle>> newHandles;
5424 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
5425 const WindowInfo* info = handle->getInfo();
5426 if (mConnectionManager.getConnection(handle->getToken()) == nullptr) {
5427 const bool noInputChannel =
5428 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
5429 const bool canReceiveInput =
5430 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5431 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
5432 if (canReceiveInput && !noInputChannel) {
5433 ALOGV("Window handle %s has no registered input channel",
5434 handle->getName().c_str());
5435 continue;
5436 }
5437 }
5438
5439 if (info->displayId != displayId) {
5440 ALOGE("Window %s updated by wrong display %s, should belong to display %s",
5441 handle->getName().c_str(), displayId.toString().c_str(),
5442 info->displayId.toString().c_str());
5443 continue;
5444 }
5445
5446 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5447 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
5448 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
5449 oldHandle->updateFrom(handle);
5450 newHandles.push_back(oldHandle);
5451 } else {
5452 newHandles.push_back(handle);
5453 }
5454 }
5455
5456 mWindowInfos.setWindowHandlesForDisplay(displayId, std::move(newHandles));
5457 }
5458
5459 /**
5460 * Called from InputManagerService, update window handle list by displayId that can receive input.
5461 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5462 * If set an empty list, remove all handles from the specific display.
5463 * For focused handle, check if need to change and send a cancel event to previous one.
5464 * For removed handle, check if need to send a cancel event if already in touch.
5465 */
setInputWindowsLocked(const std::vector<sp<WindowInfoHandle>> & windowInfoHandles,ui::LogicalDisplayId displayId)5466 void InputDispatcher::setInputWindowsLocked(
5467 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles,
5468 ui::LogicalDisplayId displayId) {
5469 if (DEBUG_FOCUS) {
5470 std::string windowList;
5471 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
5472 windowList += iwh->getName() + " ";
5473 }
5474 LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList;
5475 }
5476 ScopedSyntheticEventTracer traceContext(mTracer);
5477
5478 // Check preconditions for new input windows
5479 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
5480 const WindowInfo& info = *window->getInfo();
5481
5482 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
5483 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
5484 if (noInputWindow && window->getToken() != nullptr) {
5485 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5486 window->getName().c_str());
5487 window->releaseChannel();
5488 }
5489
5490 // Ensure all spy windows are trusted overlays
5491 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5492 !info.inputConfig.test(
5493 WindowInfo::InputConfig::TRUSTED_OVERLAY),
5494 "%s has feature SPY, but is not a trusted overlay.",
5495 window->getName().c_str());
5496
5497 // Ensure all stylus interceptors are trusted overlays
5498 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5499 !info.inputConfig.test(
5500 WindowInfo::InputConfig::TRUSTED_OVERLAY),
5501 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5502 window->getName().c_str());
5503 }
5504
5505 // Copy old handles for release if they are no longer present.
5506 const std::vector<sp<WindowInfoHandle>> oldWindowHandles =
5507 mWindowInfos.getWindowHandlesForDisplay(displayId);
5508 const sp<WindowInfoHandle> removedFocusedWindowHandle = getFocusedWindowHandleLocked(displayId);
5509
5510 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
5511
5512 const std::vector<sp<WindowInfoHandle>>& windowHandles =
5513 mWindowInfos.getWindowHandlesForDisplay(displayId);
5514
5515 std::optional<FocusResolver::FocusChanges> changes =
5516 mFocusResolver.setInputWindows(displayId, windowHandles);
5517 if (changes) {
5518 onFocusChangedLocked(*changes, traceContext.getTracker(), removedFocusedWindowHandle);
5519 }
5520
5521 CancelationOptions pointerCancellationOptions(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5522 "touched window was removed",
5523 traceContext.getTracker());
5524 CancelationOptions hoverCancellationOptions(CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
5525 "WindowInfo changed", traceContext.getTracker());
5526 const std::list<DispatcherTouchState::CancellationArgs> cancellations =
5527 mTouchStates.updateFromWindowInfo(displayId);
5528 for (const auto& cancellationArgs : cancellations) {
5529 switch (cancellationArgs.mode) {
5530 case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
5531 pointerCancellationOptions.deviceId = cancellationArgs.deviceId;
5532 synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle,
5533 pointerCancellationOptions);
5534 break;
5535 case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
5536 hoverCancellationOptions.deviceId = cancellationArgs.deviceId;
5537 synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle,
5538 hoverCancellationOptions);
5539 break;
5540 default:
5541 LOG_ALWAYS_FATAL("Unexpected cancellation Mode");
5542 }
5543 }
5544
5545 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
5546 // could just clear the state here.
5547 if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
5548 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
5549 windowHandles.end()) {
5550 ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5551 sendDropWindowCommandLocked(nullptr, 0, 0);
5552 mDragState.reset();
5553 }
5554
5555 // Release information for windows that are no longer present.
5556 // This ensures that unused input channels are released promptly.
5557 // Otherwise, they might stick around until the window handle is destroyed
5558 // which might not happen until the next GC.
5559 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
5560 if (!mWindowInfos.isWindowPresent(oldWindowHandle)) {
5561 LOG_IF(INFO, DEBUG_FOCUS) << "Window went away: " << oldWindowHandle->getName();
5562 oldWindowHandle->releaseChannel();
5563 }
5564 }
5565 }
5566
5567 std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
updateFromWindowInfo(ui::LogicalDisplayId displayId)5568 InputDispatcher::DispatcherTouchState::updateFromWindowInfo(ui::LogicalDisplayId displayId) {
5569 std::list<CancellationArgs> cancellations;
5570 forTouchAndCursorStatesOnDisplay(displayId, [&](TouchState& state) {
5571 cancellations.splice(cancellations.end(),
5572 eraseRemovedWindowsFromWindowInfo(state, displayId));
5573 cancellations.splice(cancellations.end(),
5574 updateHoveringStateFromWindowInfo(state, displayId));
5575 return false;
5576 });
5577 return cancellations;
5578 }
5579
5580 std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
eraseRemovedWindowsFromWindowInfo(TouchState & state,ui::LogicalDisplayId displayId)5581 InputDispatcher::DispatcherTouchState::eraseRemovedWindowsFromWindowInfo(
5582 TouchState& state, ui::LogicalDisplayId displayId) {
5583 std::list<CancellationArgs> cancellations;
5584 for (auto it = state.windows.begin(); it != state.windows.end();) {
5585 TouchedWindow& touchedWindow = *it;
5586 if (mWindowInfos.isWindowPresent(touchedWindow.windowHandle)) {
5587 it++;
5588 continue;
5589 }
5590 LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5591 << " in display %" << displayId;
5592 cancellations.emplace_back(touchedWindow.windowHandle,
5593 CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
5594 // Since we are about to drop the touch, cancel the events for the wallpaper as well.
5595 if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
5596 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5597 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
5598 for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds()) {
5599 if (const auto& ww = state.getWallpaperWindow(deviceId); ww != nullptr) {
5600 cancellations.emplace_back(ww, CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5601 deviceId);
5602 }
5603 }
5604 }
5605 it = state.windows.erase(it);
5606 }
5607 return cancellations;
5608 }
5609
5610 std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
updateHoveringStateFromWindowInfo(TouchState & state,ui::LogicalDisplayId displayId)5611 InputDispatcher::DispatcherTouchState::updateHoveringStateFromWindowInfo(
5612 TouchState& state, ui::LogicalDisplayId displayId) {
5613 std::list<CancellationArgs> cancellations;
5614 // Check if the hovering should stop because the window is no longer eligible to receive it
5615 // (for example, if the touchable region changed)
5616 ui::Transform displayTransform = mWindowInfos.getDisplayTransform(displayId);
5617 for (TouchedWindow& touchedWindow : state.windows) {
5618 std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf(
5619 [&](const PointerProperties& properties, float x, float y) {
5620 const bool isStylus = properties.toolType == ToolType::STYLUS;
5621 const bool stillAcceptsTouch =
5622 windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(), displayId,
5623 x, y, isStylus, displayTransform);
5624 return !stillAcceptsTouch;
5625 });
5626
5627 for (DeviceId deviceId : erasedDevices) {
5628 cancellations.emplace_back(touchedWindow.windowHandle,
5629 CancelationOptions::Mode::CANCEL_HOVER_EVENTS, deviceId);
5630 }
5631 }
5632 return cancellations;
5633 }
5634
setFocusedApplication(ui::LogicalDisplayId displayId,const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)5635 void InputDispatcher::setFocusedApplication(
5636 ui::LogicalDisplayId displayId,
5637 const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5638 LOG_IF(INFO, DEBUG_FOCUS) << "setFocusedApplication displayId=" << displayId.toString() << " "
5639 << (inputApplicationHandle ? inputApplicationHandle->getName()
5640 : "<nullptr>");
5641 { // acquire lock
5642 std::scoped_lock _l(mLock);
5643 setFocusedApplicationLocked(displayId, inputApplicationHandle);
5644 } // release lock
5645
5646 // Wake up poll loop since it may need to make new input dispatching choices.
5647 mLooper->wake();
5648 }
5649
setFocusedApplicationLocked(ui::LogicalDisplayId displayId,const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)5650 void InputDispatcher::setFocusedApplicationLocked(
5651 ui::LogicalDisplayId displayId,
5652 const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5653 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5654 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5655
5656 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5657 return; // This application is already focused. No need to wake up or change anything.
5658 }
5659
5660 // Set the new application handle.
5661 if (inputApplicationHandle != nullptr) {
5662 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5663 } else {
5664 mFocusedApplicationHandlesByDisplay.erase(displayId);
5665 }
5666
5667 // No matter what the old focused application was, stop waiting on it because it is
5668 // no longer focused.
5669 resetNoFocusedWindowTimeoutLocked();
5670 }
5671
setMinTimeBetweenUserActivityPokes(std::chrono::milliseconds interval)5672 void InputDispatcher::setMinTimeBetweenUserActivityPokes(std::chrono::milliseconds interval) {
5673 if (interval.count() < 0) {
5674 LOG_ALWAYS_FATAL("Minimum time between user activity pokes should be >= 0");
5675 }
5676 std::scoped_lock _l(mLock);
5677 mMinTimeBetweenUserActivityPokes = interval;
5678 }
5679
5680 /**
5681 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5682 * the display not specified.
5683 *
5684 * We track any unreleased events for each window. If a window loses the ability to receive the
5685 * released event, we will send a cancel event to it. So when the focused display is changed, we
5686 * cancel all the unreleased display-unspecified events for the focused window on the old focused
5687 * display. The display-specified events won't be affected.
5688 */
setFocusedDisplay(ui::LogicalDisplayId displayId)5689 void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) {
5690 LOG_IF(INFO, DEBUG_FOCUS) << "setFocusedDisplay displayId=" << displayId.toString();
5691 { // acquire lock
5692 std::scoped_lock _l(mLock);
5693 ScopedSyntheticEventTracer traceContext(mTracer);
5694
5695 if (mFocusedDisplayId != displayId) {
5696 sp<IBinder> oldFocusedWindowToken =
5697 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5698 if (oldFocusedWindowToken != nullptr) {
5699 const auto windowHandle =
5700 mWindowInfos.findWindowHandle(oldFocusedWindowToken, mFocusedDisplayId);
5701 if (windowHandle == nullptr) {
5702 LOG(FATAL) << __func__ << ": Previously focused token did not have a window";
5703 }
5704 CancelationOptions
5705 options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
5706 "The display which contains this window no longer has focus.",
5707 traceContext.getTracker());
5708 options.displayId = ui::LogicalDisplayId::INVALID;
5709 synthesizeCancelationEventsForWindowLocked(windowHandle, options);
5710 }
5711 mFocusedDisplayId = displayId;
5712 // Enqueue a command to run outside the lock to tell the policy that the focused display
5713 // changed.
5714 auto command = [this]() REQUIRES(mLock) {
5715 scoped_unlock unlock(mLock);
5716 mPolicy.notifyFocusedDisplayChanged(mFocusedDisplayId);
5717 };
5718 postCommandLocked(std::move(command));
5719
5720 // Only a window on the focused display can have Pointer Capture, so disable the active
5721 // Pointer Capture session if there is one, since the focused display changed.
5722 disablePointerCaptureForcedLocked();
5723
5724 // Find new focused window and validate
5725 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
5726 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
5727
5728 if (newFocusedWindowToken == nullptr) {
5729 ALOGW("Focused display #%s does not have a focused window.",
5730 displayId.toString().c_str());
5731 if (mFocusResolver.hasFocusedWindowTokens()) {
5732 ALOGE("But another display has a focused window\n%s",
5733 mFocusResolver.dumpFocusedWindows().c_str());
5734 }
5735 }
5736 }
5737 } // release lock
5738
5739 // Wake up poll loop since it may need to make new input dispatching choices.
5740 mLooper->wake();
5741 }
5742
setInputDispatchMode(bool enabled,bool frozen)5743 void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
5744 LOG_IF(INFO, DEBUG_FOCUS) << "setInputDispatchMode: enabled=" << enabled
5745 << ", frozen=" << frozen;
5746
5747 bool changed;
5748 { // acquire lock
5749 std::scoped_lock _l(mLock);
5750
5751 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5752 if (mDispatchFrozen && !frozen) {
5753 resetNoFocusedWindowTimeoutLocked();
5754 }
5755
5756 if (mDispatchEnabled && !enabled) {
5757 resetAndDropEverythingLocked("dispatcher is being disabled");
5758 }
5759
5760 mDispatchEnabled = enabled;
5761 mDispatchFrozen = frozen;
5762 changed = true;
5763 } else {
5764 changed = false;
5765 }
5766 } // release lock
5767
5768 if (changed) {
5769 // Wake up poll loop since it may need to make new input dispatching choices.
5770 mLooper->wake();
5771 }
5772 }
5773
setInputFilterEnabled(bool enabled)5774 void InputDispatcher::setInputFilterEnabled(bool enabled) {
5775 LOG_IF(INFO, DEBUG_FOCUS) << "setInputFilterEnabled: enabled=" << enabled;
5776
5777 { // acquire lock
5778 std::scoped_lock _l(mLock);
5779
5780 if (mInputFilterEnabled == enabled) {
5781 return;
5782 }
5783
5784 mInputFilterEnabled = enabled;
5785 resetAndDropEverythingLocked("input filter is being enabled or disabled");
5786 } // release lock
5787
5788 // Wake up poll loop since there might be work to do to drop everything.
5789 mLooper->wake();
5790 }
5791
setInTouchMode(bool inTouchMode,gui::Pid pid,gui::Uid uid,bool hasPermission,ui::LogicalDisplayId displayId)5792 bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
5793 bool hasPermission, ui::LogicalDisplayId displayId) {
5794 bool needWake = false;
5795 {
5796 std::scoped_lock lock(mLock);
5797 LOG_IF(INFO, DEBUG_TOUCH_MODE)
5798 << "Request to change touch mode to " << toString(inTouchMode)
5799 << " (calling pid=" << pid.toString() << ", uid=" << uid.toString()
5800 << ", hasPermission=" << toString(hasPermission)
5801 << ", target displayId=" << displayId.toString()
5802 << ", mTouchModePerDisplay[displayId]="
5803 << (mTouchModePerDisplay.count(displayId) == 0
5804 ? "not set"
5805 : std::to_string(mTouchModePerDisplay[displayId]))
5806 << ")";
5807
5808 auto touchModeIt = mTouchModePerDisplay.find(displayId);
5809 if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
5810 return false;
5811 }
5812 if (!hasPermission) {
5813 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5814 !recentWindowsAreOwnedByLocked(pid, uid)) {
5815 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
5816 "window nor none of the previously interacted window",
5817 pid.toString().c_str(), uid.toString().c_str());
5818 return false;
5819 }
5820 }
5821 mTouchModePerDisplay[displayId] = inTouchMode;
5822 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5823 displayId);
5824 needWake = enqueueInboundEventLocked(std::move(entry));
5825 } // release lock
5826
5827 if (needWake) {
5828 mLooper->wake();
5829 }
5830 return true;
5831 }
5832
focusedWindowIsOwnedByLocked(gui::Pid pid,gui::Uid uid)5833 bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
5834 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5835 if (focusedToken == nullptr) {
5836 return false;
5837 }
5838 sp<WindowInfoHandle> windowHandle = mWindowInfos.findWindowHandle(focusedToken);
5839 return isWindowOwnedBy(windowHandle, pid, uid);
5840 }
5841
recentWindowsAreOwnedByLocked(gui::Pid pid,gui::Uid uid)5842 bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
5843 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5844 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5845 const sp<WindowInfoHandle> windowHandle =
5846 mWindowInfos.findWindowHandle(connectionToken);
5847 return isWindowOwnedBy(windowHandle, pid, uid);
5848 }) != mInteractionConnectionTokens.end();
5849 }
5850
setMaximumObscuringOpacityForTouch(float opacity)5851 void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5852 std::scoped_lock lock(mLock);
5853 mWindowInfos.setMaximumObscuringOpacityForTouch(opacity);
5854 }
5855
transferTouchGesture(const sp<IBinder> & fromToken,const sp<IBinder> & toToken,bool isDragDrop,bool transferEntireGesture)5856 bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5857 bool isDragDrop, bool transferEntireGesture) {
5858 if (fromToken == toToken) {
5859 LOG_IF(INFO, DEBUG_FOCUS) << "Trivial transfer to same window.";
5860 return true;
5861 }
5862
5863 { // acquire lock
5864 std::scoped_lock _l(mLock);
5865
5866 ScopedSyntheticEventTracer traceContext(mTracer);
5867 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5868 "transferring touch from this window to another window",
5869 traceContext.getTracker());
5870
5871 auto result = mTouchStates.transferTouchGesture(fromToken, toToken, transferEntireGesture);
5872 if (!result.has_value()) {
5873 return false;
5874 }
5875
5876 const auto& [toWindowHandle, deviceId, pointers, cancellations, pointerDowns] =
5877 result.value();
5878
5879 for (const auto& cancellationArgs : cancellations) {
5880 LOG_ALWAYS_FATAL_IF(cancellationArgs.mode !=
5881 CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
5882 LOG_ALWAYS_FATAL_IF(cancellationArgs.deviceId.has_value());
5883 synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, options);
5884 }
5885
5886 for (const auto& pointerDownArgs : pointerDowns) {
5887 synthesizePointerDownEventsForConnectionLocked(pointerDownArgs.downTimeInTarget,
5888 pointerDownArgs.connection,
5889 pointerDownArgs.targetFlags,
5890 traceContext.getTracker());
5891 }
5892
5893 // Store the dragging window.
5894 if (isDragDrop) {
5895 if (pointers.size() != 1) {
5896 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5897 " pointer on the window.");
5898 return false;
5899 }
5900 // Track the pointer id for drag window and generate the drag state.
5901 const size_t id = pointers.begin()->id;
5902 mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id);
5903 }
5904 } // release lock
5905
5906 // Wake up poll loop since it may need to make new input dispatching choices.
5907 mLooper->wake();
5908 return true;
5909 }
5910
5911 std::optional<std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<PointerProperties>,
5912 std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>,
5913 std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>>
transferTouchGesture(const sp<android::IBinder> & fromToken,const sp<android::IBinder> & toToken,bool transferEntireGesture)5914 InputDispatcher::DispatcherTouchState::transferTouchGesture(const sp<android::IBinder>& fromToken,
5915 const sp<android::IBinder>& toToken,
5916 bool transferEntireGesture) {
5917 // Find the target touch state and touched window by fromToken.
5918 auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(fromToken);
5919 if (!touchStateWindowAndDisplay.has_value()) {
5920 ALOGD("Touch transfer failed because from window is not being touched.");
5921 return std::nullopt;
5922 }
5923
5924 auto [state, touchedWindow, displayId] = touchStateWindowAndDisplay.value();
5925 std::set<DeviceId> deviceIds = touchedWindow.getTouchingDeviceIds();
5926 if (deviceIds.size() != 1) {
5927 LOG(INFO) << "Can't transfer touch. Currently touching devices: "
5928 << dumpContainer(deviceIds) << " for window: " << touchedWindow.dump();
5929 return std::nullopt;
5930 }
5931 const DeviceId deviceId = *deviceIds.begin();
5932
5933 const sp<WindowInfoHandle> fromWindowHandle = touchedWindow.windowHandle;
5934 // TouchState displayId may not be same as window displayId, we need to lookup for toToken on
5935 // all connected displays.
5936 const sp<WindowInfoHandle> toWindowHandle =
5937 mWindowInfos.findWindowHandleOnConnectedDisplays(toToken, displayId);
5938 if (!toWindowHandle) {
5939 ALOGW("Cannot transfer touch because the transfer target window was not found.");
5940 return std::nullopt;
5941 }
5942
5943 LOG_IF(INFO, DEBUG_FOCUS) << __func__ << ": fromWindowHandle=" << fromWindowHandle->getName()
5944 << ", toWindowHandle=" << toWindowHandle->getName();
5945
5946 // Erase old window.
5947 ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow.targetFlags;
5948 std::vector<PointerProperties> pointers = touchedWindow.getTouchingPointers(deviceId);
5949 state.removeWindowByToken(fromToken);
5950
5951 // Add new window.
5952 nsecs_t downTimeInTarget = now();
5953 ftl::Flags<InputTarget::Flags> newTargetFlags = oldTargetFlags & (InputTarget::Flags::SPLIT);
5954 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
5955 newTargetFlags |= InputTarget::Flags::FOREGROUND;
5956 }
5957 // Transferring touch focus using this API should not effect the focused window.
5958 newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE;
5959 sp<IBinder> forwardingWindowToken;
5960 if (transferEntireGesture && com::android::input::flags::allow_transfer_of_entire_gesture()) {
5961 forwardingWindowToken = fromToken;
5962 }
5963 state.addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
5964 deviceId, pointers, downTimeInTarget, forwardingWindowToken);
5965
5966 // Synthesize cancel for old window and down for new window.
5967 std::shared_ptr<Connection> fromConnection = mConnectionManager.getConnection(fromToken);
5968 std::shared_ptr<Connection> toConnection = mConnectionManager.getConnection(toToken);
5969 std::list<CancellationArgs> cancellations;
5970 std::list<PointerDownArgs> pointerDowns;
5971 if (fromConnection != nullptr && toConnection != nullptr) {
5972 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
5973 cancellations.emplace_back(fromWindowHandle,
5974 CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
5975
5976 // Check if the wallpaper window should deliver the corresponding event.
5977 auto [wallpaperCancellations, wallpaperPointerDowns] =
5978 transferWallpaperTouch(fromWindowHandle, toWindowHandle, state, deviceId, pointers,
5979 oldTargetFlags, newTargetFlags);
5980
5981 cancellations.splice(cancellations.end(), wallpaperCancellations);
5982 pointerDowns.splice(pointerDowns.end(), wallpaperPointerDowns);
5983
5984 // Because new window may have a wallpaper window, it will merge input state from it
5985 // parent window, after this the firstNewPointerIdx in input state will be reset, then
5986 // it will cause new move event be thought inconsistent, so we should synthesize the
5987 // down event after it reset.
5988 pointerDowns.emplace_back(downTimeInTarget, toConnection, newTargetFlags);
5989 }
5990
5991 return std::make_tuple(toWindowHandle, deviceId, pointers, cancellations, pointerDowns);
5992 }
5993
5994 /**
5995 * Get the touched foreground window on the given display.
5996 * Return null if there are no windows touched on that display, or if more than one foreground
5997 * window is being touched.
5998 */
findTouchedForegroundWindow(ui::LogicalDisplayId displayId) const5999 sp<WindowInfoHandle> InputDispatcher::DispatcherTouchState::findTouchedForegroundWindow(
6000 ui::LogicalDisplayId displayId) const {
6001 sp<WindowInfoHandle> touchedForegroundWindow;
6002 forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) {
6003 // If multiple foreground windows are touched, return nullptr
6004 for (const TouchedWindow& window : state.windows) {
6005 if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
6006 if (touchedForegroundWindow != nullptr) {
6007 ALOGI("Two or more foreground windows: %s and %s",
6008 touchedForegroundWindow->getName().c_str(),
6009 window.windowHandle->getName().c_str());
6010 touchedForegroundWindow = nullptr;
6011 return true;
6012 }
6013 touchedForegroundWindow = window.windowHandle;
6014 }
6015 }
6016 return false;
6017 });
6018 ALOGI_IF(touchedForegroundWindow == nullptr,
6019 "No touch state or no touched foreground window on display %d", displayId.val());
6020 return touchedForegroundWindow;
6021 }
6022
6023 // Binder call
transferTouchOnDisplay(const sp<IBinder> & destChannelToken,ui::LogicalDisplayId displayId)6024 bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken,
6025 ui::LogicalDisplayId displayId) {
6026 sp<IBinder> fromToken;
6027 { // acquire lock
6028 std::scoped_lock _l(mLock);
6029 sp<WindowInfoHandle> toWindowHandle =
6030 mWindowInfos.findWindowHandle(destChannelToken, displayId);
6031 if (toWindowHandle == nullptr) {
6032 ALOGW("Could not find window associated with token=%p on display %s",
6033 destChannelToken.get(), displayId.toString().c_str());
6034 return false;
6035 }
6036
6037 sp<WindowInfoHandle> from = mTouchStates.findTouchedForegroundWindow(displayId);
6038 if (from == nullptr) {
6039 ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
6040 return false;
6041 }
6042
6043 fromToken = from->getToken();
6044 } // release lock
6045
6046 return transferTouchGesture(fromToken, destChannelToken, /*isDragDrop=*/false,
6047 /*transferEntireGesture=*/false);
6048 }
6049
resetAndDropEverythingLocked(const char * reason)6050 void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
6051 LOG_IF(INFO, DEBUG_FOCUS) << "Resetting and dropping all events (" << reason << ").";
6052
6053 ScopedSyntheticEventTracer traceContext(mTracer);
6054 CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason,
6055 traceContext.getTracker());
6056 synthesizeCancelationEventsForAllConnectionsLocked(options);
6057
6058 resetKeyRepeatLocked();
6059 releasePendingEventLocked();
6060 drainInboundQueueLocked();
6061 resetNoFocusedWindowTimeoutLocked();
6062
6063 mAnrTracker.clear();
6064 mTouchStates.clear();
6065 }
6066
logDispatchStateLocked() const6067 void InputDispatcher::logDispatchStateLocked() const {
6068 std::string dump;
6069 dumpDispatchStateLocked(dump);
6070
6071 std::istringstream stream(dump);
6072 std::string line;
6073
6074 while (std::getline(stream, line, '\n')) {
6075 ALOGI("%s", line.c_str());
6076 }
6077 }
6078
dumpPointerCaptureStateLocked() const6079 std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
6080 std::string dump;
6081
6082 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
6083 toString(mCurrentPointerCaptureRequest.isEnable()));
6084
6085 std::string windowName = "None";
6086 if (mWindowTokenWithPointerCapture) {
6087 const sp<WindowInfoHandle> captureWindowHandle =
6088 mWindowInfos.findWindowHandle(mWindowTokenWithPointerCapture);
6089 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
6090 : "token has capture without window";
6091 }
6092 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
6093
6094 return dump;
6095 }
6096
dumpDispatchStateLocked(std::string & dump) const6097 void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
6098 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
6099 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
6100 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
6101 dump += StringPrintf(INDENT "FocusedDisplayId: %s\n", mFocusedDisplayId.toString().c_str());
6102
6103 if (!mFocusedApplicationHandlesByDisplay.empty()) {
6104 dump += StringPrintf(INDENT "FocusedApplications:\n");
6105 for (auto& it : mFocusedApplicationHandlesByDisplay) {
6106 const ui::LogicalDisplayId displayId = it.first;
6107 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
6108 const std::chrono::duration timeout =
6109 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
6110 dump += StringPrintf(INDENT2 "displayId=%s, name='%s', dispatchingTimeout=%" PRId64
6111 "ms\n",
6112 displayId.toString().c_str(), applicationHandle->getName().c_str(),
6113 millis(timeout));
6114 }
6115 } else {
6116 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
6117 }
6118
6119 dump += mFocusResolver.dump();
6120 dump += dumpPointerCaptureStateLocked();
6121
6122 dump += addLinePrefix(mTouchStates.dump(), INDENT);
6123
6124 if (mDragState) {
6125 dump += StringPrintf(INDENT "DragState:\n");
6126 mDragState->dump(dump, INDENT2);
6127 }
6128
6129 dump += addLinePrefix(mWindowInfos.dumpDisplayAndWindowInfo(), INDENT);
6130
6131 const nsecs_t currentTime = now();
6132
6133 dump += addLinePrefix(mConnectionManager.dump(currentTime), INDENT);
6134
6135 // Dump recently dispatched or dropped events from oldest to newest.
6136 if (!mRecentQueue.empty()) {
6137 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
6138 for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
6139 dump += INDENT2;
6140 dump += entry->getDescription();
6141 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
6142 }
6143 } else {
6144 dump += INDENT "RecentQueue: <empty>\n";
6145 }
6146
6147 // Dump event currently being dispatched.
6148 if (mPendingEvent) {
6149 dump += INDENT "PendingEvent:\n";
6150 dump += INDENT2;
6151 dump += mPendingEvent->getDescription();
6152 dump += StringPrintf(", age=%" PRId64 "ms\n",
6153 ns2ms(currentTime - mPendingEvent->eventTime));
6154 } else {
6155 dump += INDENT "PendingEvent: <none>\n";
6156 }
6157
6158 // Dump inbound events from oldest to newest.
6159 if (!mInboundQueue.empty()) {
6160 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
6161 for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
6162 dump += INDENT2;
6163 dump += entry->getDescription();
6164 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
6165 }
6166 } else {
6167 dump += INDENT "InboundQueue: <empty>\n";
6168 }
6169
6170 if (!mCommandQueue.empty()) {
6171 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
6172 } else {
6173 dump += INDENT "CommandQueue: <empty>\n";
6174 }
6175
6176 if (!mTouchModePerDisplay.empty()) {
6177 dump += INDENT "TouchModePerDisplay:\n";
6178 for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
6179 dump += StringPrintf(INDENT2 "Display: %s TouchMode: %s\n",
6180 displayId.toString().c_str(), std::to_string(touchMode).c_str());
6181 }
6182 } else {
6183 dump += INDENT "TouchModePerDisplay: <none>\n";
6184 }
6185
6186 dump += INDENT "Configuration:\n";
6187 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
6188 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
6189 ns2ms(mConfig.keyRepeatTimeout));
6190 dump += mLatencyTracker.dump(INDENT2);
6191 dump += mInputEventTimelineProcessor->dump(INDENT2);
6192 dump += INDENT "InputTracer: ";
6193 dump += mTracer == nullptr ? "Disabled" : "Enabled";
6194 }
6195
6196 class LooperEventCallback : public LooperCallback {
6197 public:
LooperEventCallback(std::function<int (int events)> callback)6198 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
handleEvent(int,int events,void *)6199 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
6200
6201 private:
6202 std::function<int(int events)> mCallback;
6203 };
6204
createInputChannel(const std::string & name)6205 Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
6206 LOG_IF(INFO, DEBUG_CHANNEL_CREATION) << "channel '" << name << "' ~ createInputChannel";
6207
6208 std::unique_ptr<InputChannel> serverChannel;
6209 std::unique_ptr<InputChannel> clientChannel;
6210 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
6211
6212 if (result) {
6213 return base::Error(result) << "Failed to open input channel pair with name " << name;
6214 }
6215
6216 { // acquire lock
6217 std::scoped_lock _l(mLock);
6218 const sp<IBinder>& token = serverChannel->getConnectionToken();
6219 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
6220 this, std::placeholders::_1, token);
6221
6222 mConnectionManager.createConnection(std::move(serverChannel), mIdGenerator, callback);
6223 } // release lock
6224
6225 // Wake the looper because some connections have changed.
6226 mLooper->wake();
6227 return clientChannel;
6228 }
6229
createInputMonitor(ui::LogicalDisplayId displayId,const std::string & name,gui::Pid pid)6230 Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
6231 ui::LogicalDisplayId displayId, const std::string& name, gui::Pid pid) {
6232 std::unique_ptr<InputChannel> serverChannel;
6233 std::unique_ptr<InputChannel> clientChannel;
6234 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
6235 if (result) {
6236 return base::Error(result) << "Failed to open input channel pair with name " << name;
6237 }
6238
6239 { // acquire lock
6240 std::scoped_lock _l(mLock);
6241
6242 if (displayId < ui::LogicalDisplayId::DEFAULT) {
6243 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
6244 << " without a specified display.";
6245 }
6246
6247 const sp<IBinder>& token = serverChannel->getConnectionToken();
6248 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
6249 this, std::placeholders::_1, token);
6250
6251 mConnectionManager.createGlobalInputMonitor(displayId, std::move(serverChannel),
6252 mIdGenerator, pid, callback);
6253 }
6254
6255 // Wake the looper because some connections have changed.
6256 mLooper->wake();
6257 return clientChannel;
6258 }
6259
removeInputChannel(const sp<IBinder> & connectionToken)6260 status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
6261 { // acquire lock
6262 std::scoped_lock _l(mLock);
6263 std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken);
6264 if (connection == nullptr) {
6265 // Connection can be removed via socket hang up or an explicit call to
6266 // 'removeInputChannel'
6267 return BAD_VALUE;
6268 }
6269
6270 status_t status = removeInputChannelLocked(connection, /*notify=*/false);
6271 if (status) {
6272 return status;
6273 }
6274 } // release lock
6275
6276 // Wake the poll loop because removing the connection may have changed the current
6277 // synchronization state.
6278 mLooper->wake();
6279 return OK;
6280 }
6281
removeInputChannelLocked(const std::shared_ptr<Connection> & connection,bool notify)6282 status_t InputDispatcher::removeInputChannelLocked(const std::shared_ptr<Connection>& connection,
6283 bool notify) {
6284 LOG_ALWAYS_FATAL_IF(connection == nullptr);
6285 abortBrokenDispatchCycleLocked(connection, notify);
6286
6287 mAnrTracker.eraseToken(connection->getToken());
6288 mConnectionManager.removeConnection(connection);
6289
6290 return OK;
6291 }
6292
removeMonitorChannel(const sp<IBinder> & connectionToken)6293 void InputDispatcher::ConnectionManager::removeMonitorChannel(const sp<IBinder>& connectionToken) {
6294 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
6295 auto& [displayId, monitors] = *it;
6296 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
6297 return monitor.connection->getToken() == connectionToken;
6298 });
6299
6300 if (monitors.empty()) {
6301 it = mGlobalMonitorsByDisplay.erase(it);
6302 } else {
6303 ++it;
6304 }
6305 }
6306 }
6307
pilferPointers(const sp<IBinder> & token)6308 status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
6309 std::scoped_lock _l(mLock);
6310 return pilferPointersLocked(token);
6311 }
6312
pilferPointersLocked(const sp<IBinder> & token)6313 status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
6314 const std::shared_ptr<Connection> requestingConnection =
6315 mConnectionManager.getConnection(token);
6316 if (!requestingConnection) {
6317 LOG(WARNING)
6318 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
6319 return BAD_VALUE;
6320 }
6321
6322 const auto result = mTouchStates.pilferPointers(token, *requestingConnection);
6323 if (!result.ok()) {
6324 return result.error().code();
6325 }
6326
6327 ScopedSyntheticEventTracer traceContext(mTracer);
6328 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6329 "input channel stole pointer stream", traceContext.getTracker());
6330 const auto cancellations = *result;
6331 for (const auto& cancellationArgs : cancellations) {
6332 LOG_ALWAYS_FATAL_IF(cancellationArgs.mode !=
6333 CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
6334 options.displayId = cancellationArgs.displayId;
6335 options.deviceId = cancellationArgs.deviceId;
6336 options.pointerIds = cancellationArgs.pointerIds;
6337 synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, options);
6338 }
6339 return OK;
6340 }
6341
6342 base::Result<std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>, status_t>
pilferPointers(const sp<IBinder> & token,const Connection & requestingConnection)6343 InputDispatcher::DispatcherTouchState::pilferPointers(const sp<IBinder>& token,
6344 const Connection& requestingConnection) {
6345 auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(token);
6346 if (!touchStateWindowAndDisplay.has_value()) {
6347 LOG(WARNING)
6348 << "Attempted to pilfer points from a channel without any on-going pointer streams."
6349 " Ignoring.";
6350 return Error(BAD_VALUE);
6351 }
6352
6353 auto [state, window, displayId] = touchStateWindowAndDisplay.value();
6354
6355 std::set<int32_t> deviceIds = window.getTouchingDeviceIds();
6356 if (deviceIds.empty()) {
6357 LOG(WARNING) << "Can't pilfer: no touching devices in window: " << window.dump();
6358 return Error(BAD_VALUE);
6359 }
6360
6361 std::list<CancellationArgs> cancellations;
6362 for (const DeviceId deviceId : deviceIds) {
6363 // Send cancel events to all the input channels we're stealing from.
6364 std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
6365 std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
6366 std::string canceledWindows;
6367 for (const TouchedWindow& w : state.windows) {
6368 if (w.windowHandle->getToken() != token) {
6369 cancellations.emplace_back(w.windowHandle,
6370 CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6371 deviceId, displayId, pointerIds);
6372 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6373 canceledWindows += w.windowHandle->getName();
6374 }
6375 }
6376 canceledWindows += canceledWindows.empty() ? "[]" : "]";
6377 LOG(INFO) << "Channel " << requestingConnection.getInputChannelName()
6378 << " is stealing input gesture for device " << deviceId << " from "
6379 << canceledWindows;
6380
6381 // Prevent the gesture from being sent to any other windows.
6382 // This only blocks relevant pointers to be sent to other windows
6383 window.addPilferingPointers(deviceId, pointerIds);
6384
6385 state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
6386 }
6387 return cancellations;
6388 }
6389
requestPointerCapture(const sp<IBinder> & windowToken,bool enabled)6390 void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6391 { // acquire lock
6392 std::scoped_lock _l(mLock);
6393 if (DEBUG_FOCUS) {
6394 const sp<WindowInfoHandle> windowHandle = mWindowInfos.findWindowHandle(windowToken);
6395 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6396 windowHandle != nullptr ? windowHandle->getName().c_str()
6397 : "token without window");
6398 }
6399
6400 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
6401 if (focusedToken != windowToken) {
6402 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6403 enabled ? "enable" : "disable");
6404 return;
6405 }
6406
6407 if (enabled == mCurrentPointerCaptureRequest.isEnable()) {
6408 ALOGW("Ignoring request to %s Pointer Capture: "
6409 "window has %s requested pointer capture.",
6410 enabled ? "enable" : "disable", enabled ? "already" : "not");
6411 return;
6412 }
6413
6414 if (enabled) {
6415 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6416 mIneligibleDisplaysForPointerCapture.end(),
6417 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6418 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6419 return;
6420 }
6421 }
6422
6423 setPointerCaptureLocked(enabled ? windowToken : nullptr);
6424 } // release lock
6425
6426 // Wake the thread to process command entries.
6427 mLooper->wake();
6428 }
6429
setDisplayEligibilityForPointerCapture(ui::LogicalDisplayId displayId,bool isEligible)6430 void InputDispatcher::setDisplayEligibilityForPointerCapture(ui::LogicalDisplayId displayId,
6431 bool isEligible) {
6432 { // acquire lock
6433 std::scoped_lock _l(mLock);
6434 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6435 if (!isEligible) {
6436 mIneligibleDisplaysForPointerCapture.push_back(displayId);
6437 }
6438 } // release lock
6439 }
6440
findMonitorPidByToken(const sp<IBinder> & token) const6441 std::optional<gui::Pid> InputDispatcher::ConnectionManager::findMonitorPidByToken(
6442 const sp<IBinder>& token) const {
6443 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
6444 for (const Monitor& monitor : monitors) {
6445 if (monitor.connection->getToken() == token) {
6446 return monitor.pid;
6447 }
6448 }
6449 }
6450 return std::nullopt;
6451 }
6452
getConnection(const sp<IBinder> & inputConnectionToken) const6453 std::shared_ptr<Connection> InputDispatcher::ConnectionManager::getConnection(
6454 const sp<IBinder>& inputConnectionToken) const {
6455 if (inputConnectionToken == nullptr) {
6456 return nullptr;
6457 }
6458
6459 for (const auto& [token, connection] : mConnectionsByToken) {
6460 if (token == inputConnectionToken) {
6461 return connection;
6462 }
6463 }
6464
6465 return nullptr;
6466 }
6467
doDispatchCycleFinishedCommand(nsecs_t finishTime,const std::shared_ptr<Connection> & connection,uint32_t seq,bool handled,nsecs_t consumeTime)6468 void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
6469 const std::shared_ptr<Connection>& connection,
6470 uint32_t seq, bool handled,
6471 nsecs_t consumeTime) {
6472 // Handle post-event policy actions.
6473 std::unique_ptr<const KeyEntry> fallbackKeyEntry;
6474
6475 { // Start critical section
6476 auto dispatchEntryIt =
6477 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6478 [seq](auto& e) { return e->seq == seq; });
6479 if (dispatchEntryIt == connection->waitQueue.end()) {
6480 return;
6481 }
6482
6483 DispatchEntry& dispatchEntry = **dispatchEntryIt;
6484
6485 const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6486 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6487 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getInputChannelName().c_str(),
6488 ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6489 }
6490 if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6491 mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id, connection->getToken(),
6492 dispatchEntry.deliveryTime, consumeTime, finishTime);
6493 }
6494
6495 if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
6496 fallbackKeyEntry =
6497 afterKeyEventLockedInterruptable(connection, &dispatchEntry, handled);
6498 }
6499 } // End critical section: The -LockedInterruptable methods may have released the lock.
6500
6501 // Dequeue the event and start the next cycle.
6502 // Because the lock might have been released, it is possible that the
6503 // contents of the wait queue to have been drained, so we need to double-check
6504 // a few things.
6505 auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6506 [seq](auto& e) { return e->seq == seq; });
6507 if (entryIt != connection->waitQueue.end()) {
6508 std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6509 connection->waitQueue.erase(entryIt);
6510
6511 const sp<IBinder>& connectionToken = connection->getToken();
6512 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6513 if (!connection->responsive) {
6514 connection->responsive = isConnectionResponsive(*connection);
6515 if (connection->responsive) {
6516 // The connection was unresponsive, and now it's responsive.
6517 processConnectionResponsiveLocked(*connection);
6518 }
6519 }
6520 traceWaitQueueLength(*connection);
6521 if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6522 const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
6523 // Only dispatch fallbacks if there is a window for the connection.
6524 if (windowHandle != nullptr) {
6525 nsecs_t downTime = fallbackKeyEntry->downTime;
6526 enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry),
6527 createInputTarget(connection, windowHandle,
6528 InputTarget::DispatchMode::AS_IS,
6529 dispatchEntry->targetFlags,
6530 mWindowInfos.getRawTransform(
6531 *windowHandle->getInfo()),
6532 downTime));
6533 }
6534 }
6535 releaseDispatchEntry(std::move(dispatchEntry));
6536 }
6537
6538 // Start the next dispatch cycle for this connection.
6539 startDispatchCycleLocked(now(), connection);
6540 }
6541
sendFocusChangedCommandLocked(const sp<IBinder> & oldToken,const sp<IBinder> & newToken)6542 void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6543 const sp<IBinder>& newToken) {
6544 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6545 scoped_unlock unlock(mLock);
6546 mPolicy.notifyFocusChanged(oldToken, newToken);
6547 };
6548 postCommandLocked(std::move(command));
6549 }
6550
sendDropWindowCommandLocked(const sp<IBinder> & token,float x,float y)6551 void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6552 auto command = [this, token, x, y]() REQUIRES(mLock) {
6553 scoped_unlock unlock(mLock);
6554 mPolicy.notifyDropWindow(token, x, y);
6555 };
6556 postCommandLocked(std::move(command));
6557 }
6558
onAnrLocked(const std::shared_ptr<Connection> & connection)6559 void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
6560 if (connection == nullptr) {
6561 LOG_ALWAYS_FATAL("Caller must check for nullness");
6562 }
6563 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6564 // is already healthy again. Don't raise ANR in this situation
6565 if (connection->waitQueue.empty()) {
6566 ALOGI("Not raising ANR because the connection %s has recovered",
6567 connection->getInputChannelName().c_str());
6568 return;
6569 }
6570 /**
6571 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6572 * may not be the one that caused the timeout to occur. One possibility is that window timeout
6573 * has changed. This could cause newer entries to time out before the already dispatched
6574 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6575 * processes the events linearly. So providing information about the oldest entry seems to be
6576 * most useful.
6577 */
6578 DispatchEntry& oldestEntry = *connection->waitQueue.front();
6579 const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
6580 std::string reason =
6581 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
6582 connection->getInputChannelName().c_str(),
6583 ns2ms(currentWait),
6584 oldestEntry.eventEntry->getDescription().c_str());
6585 sp<IBinder> connectionToken = connection->getToken();
6586 updateLastAnrStateLocked(mWindowInfos.findWindowHandle(connectionToken), reason);
6587
6588 processConnectionUnresponsiveLocked(*connection, std::move(reason));
6589
6590 // Stop waking up for events on this connection, it is already unresponsive
6591 cancelEventsForAnrLocked(connection);
6592 }
6593
onAnrLocked(std::shared_ptr<InputApplicationHandle> application)6594 void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6595 std::string reason =
6596 StringPrintf("%s does not have a focused window", application->getName().c_str());
6597 updateLastAnrStateLocked(*application, reason);
6598
6599 auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
6600 scoped_unlock unlock(mLock);
6601 mPolicy.notifyNoFocusedWindowAnr(app);
6602 };
6603 postCommandLocked(std::move(command));
6604 }
6605
updateLastAnrStateLocked(const sp<WindowInfoHandle> & window,const std::string & reason)6606 void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
6607 const std::string& reason) {
6608 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6609 updateLastAnrStateLocked(windowLabel, reason);
6610 }
6611
updateLastAnrStateLocked(const InputApplicationHandle & application,const std::string & reason)6612 void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6613 const std::string& reason) {
6614 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
6615 updateLastAnrStateLocked(windowLabel, reason);
6616 }
6617
updateLastAnrStateLocked(const std::string & windowLabel,const std::string & reason)6618 void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6619 const std::string& reason) {
6620 // Capture a record of the InputDispatcher state at the time of the ANR.
6621 time_t t = time(nullptr);
6622 struct tm tm;
6623 localtime_r(&t, &tm);
6624 char timestr[64];
6625 strftime(timestr, sizeof(timestr), "%F %T", &tm);
6626 mLastAnrState.clear();
6627 mLastAnrState += INDENT "ANR:\n";
6628 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
6629 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6630 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
6631 dumpDispatchStateLocked(mLastAnrState);
6632 }
6633
doInterceptKeyBeforeDispatchingCommand(const sp<IBinder> & focusedWindowToken,const KeyEntry & entry)6634 void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
6635 const KeyEntry& entry) {
6636 const KeyEvent event = createKeyEvent(entry);
6637 std::variant<nsecs_t, KeyEntry::InterceptKeyResult> interceptResult;
6638 nsecs_t delay = 0;
6639 { // release lock
6640 scoped_unlock unlock(mLock);
6641 android::base::Timer t;
6642 interceptResult =
6643 mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
6644 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6645 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6646 std::to_string(t.duration().count()).c_str());
6647 }
6648 } // acquire lock
6649
6650 if (std::holds_alternative<KeyEntry::InterceptKeyResult>(interceptResult)) {
6651 entry.interceptKeyResult = std::get<KeyEntry::InterceptKeyResult>(interceptResult);
6652 return;
6653 }
6654
6655 if (std::holds_alternative<nsecs_t>(interceptResult)) {
6656 entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
6657 entry.interceptKeyWakeupTime = now() + std::get<nsecs_t>(interceptResult);
6658 }
6659 }
6660
sendWindowUnresponsiveCommandLocked(const sp<IBinder> & token,std::optional<gui::Pid> pid,std::string reason)6661 void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
6662 std::optional<gui::Pid> pid,
6663 std::string reason) {
6664 auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
6665 scoped_unlock unlock(mLock);
6666 mPolicy.notifyWindowUnresponsive(token, pid, r);
6667 };
6668 postCommandLocked(std::move(command));
6669 }
6670
sendWindowResponsiveCommandLocked(const sp<IBinder> & token,std::optional<gui::Pid> pid)6671 void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
6672 std::optional<gui::Pid> pid) {
6673 auto command = [this, token, pid]() REQUIRES(mLock) {
6674 scoped_unlock unlock(mLock);
6675 mPolicy.notifyWindowResponsive(token, pid);
6676 };
6677 postCommandLocked(std::move(command));
6678 }
6679
6680 /**
6681 * Tell the policy that a connection has become unresponsive so that it can start ANR.
6682 * Check whether the connection of interest is a monitor or a window, and add the corresponding
6683 * command entry to the command queue.
6684 */
processConnectionUnresponsiveLocked(const Connection & connection,std::string reason)6685 void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6686 std::string reason) {
6687 const sp<IBinder>& connectionToken = connection.getToken();
6688 std::optional<gui::Pid> pid;
6689 if (connection.monitor) {
6690 ALOGW("Monitor %s is unresponsive: %s", connection.getInputChannelName().c_str(),
6691 reason.c_str());
6692 pid = mConnectionManager.findMonitorPidByToken(connectionToken);
6693 } else {
6694 // The connection is a window
6695 ALOGW("Window %s is unresponsive: %s", connection.getInputChannelName().c_str(),
6696 reason.c_str());
6697 const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken);
6698 if (handle != nullptr) {
6699 pid = handle->getInfo()->ownerPid;
6700 }
6701 }
6702 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
6703 }
6704
6705 /**
6706 * Tell the policy that a connection has become responsive so that it can stop ANR.
6707 */
processConnectionResponsiveLocked(const Connection & connection)6708 void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6709 const sp<IBinder>& connectionToken = connection.getToken();
6710 std::optional<gui::Pid> pid;
6711 if (connection.monitor) {
6712 pid = mConnectionManager.findMonitorPidByToken(connectionToken);
6713 } else {
6714 // The connection is a window
6715 const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken);
6716 if (handle != nullptr) {
6717 pid = handle->getInfo()->ownerPid;
6718 }
6719 }
6720 sendWindowResponsiveCommandLocked(connectionToken, pid);
6721 }
6722
afterKeyEventLockedInterruptable(const std::shared_ptr<Connection> & connection,DispatchEntry * dispatchEntry,bool handled)6723 std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
6724 const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) {
6725 // The dispatchEntry is currently valid, but it might point to a deleted object after we release
6726 // the lock. For simplicity, make copies of the data of interest here and assume that
6727 // 'dispatchEntry' is not valid after this section.
6728 // Hold a strong reference to the EventEntry to ensure it's valid for the duration of this
6729 // function, even if the DispatchEntry gets destroyed and releases its share of the ownership.
6730 std::shared_ptr<const EventEntry> eventEntry = dispatchEntry->eventEntry;
6731 const bool hasForegroundTarget = dispatchEntry->hasForegroundTarget();
6732 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(eventEntry));
6733 // To prevent misuse, ensure dispatchEntry is no longer valid.
6734 dispatchEntry = nullptr;
6735 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
6736 if (!handled) {
6737 // Report the key as unhandled, since the fallback was not handled.
6738 mReporter->reportUnhandledKey(keyEntry.id);
6739 }
6740 return {};
6741 }
6742
6743 // Get the fallback key state.
6744 // Clear it out after dispatching the UP.
6745 int32_t originalKeyCode = keyEntry.keyCode;
6746 std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
6747 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
6748 connection->inputState.removeFallbackKey(originalKeyCode);
6749 }
6750
6751 if (handled || !hasForegroundTarget) {
6752 // If the application handles the original key for which we previously
6753 // generated a fallback or if the window is not a foreground window,
6754 // then cancel the associated fallback key, if any.
6755 if (fallbackKeyCode) {
6756 // Dispatch the unhandled key to the policy with the cancel flag.
6757 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
6758 << "Unhandled key event: Asking policy to cancel fallback action. keyCode="
6759 << keyEntry.keyCode << ", action=" << keyEntry.action
6760 << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex
6761 << keyEntry.policyFlags;
6762 KeyEvent event = createKeyEvent(keyEntry);
6763 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
6764
6765 mLock.unlock();
6766
6767 if (const auto unhandledKeyFallback =
6768 mPolicy.dispatchUnhandledKey(connection->getToken(), event,
6769 keyEntry.policyFlags);
6770 unhandledKeyFallback) {
6771 event = *unhandledKeyFallback;
6772 }
6773
6774 mLock.lock();
6775
6776 // Cancel the fallback key, but only if we still have a window for the channel.
6777 // It could have been removed during the policy call.
6778 if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
6779 const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
6780 if (windowHandle != nullptr) {
6781 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
6782 "application handled the original non-fallback key "
6783 "or is no longer a foreground target, "
6784 "canceling previously dispatched fallback key",
6785 keyEntry.traceTracker);
6786 options.keyCode = *fallbackKeyCode;
6787 synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection);
6788 }
6789 }
6790 connection->inputState.removeFallbackKey(originalKeyCode);
6791 }
6792 } else {
6793 // If the application did not handle a non-fallback key, first check
6794 // that we are in a good state to perform unhandled key event processing
6795 // Then ask the policy what to do with it.
6796 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
6797 if (!fallbackKeyCode && !initialDown) {
6798 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
6799 << "Unhandled key event: Skipping unhandled key event processing since this is "
6800 "not an initial down. keyCode="
6801 << originalKeyCode << ", action=" << keyEntry.action
6802 << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex
6803 << keyEntry.policyFlags;
6804 return {};
6805 }
6806
6807 // Dispatch the unhandled key to the policy.
6808 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
6809 << "Unhandled key event: Asking policy to perform fallback action. keyCode="
6810 << keyEntry.keyCode << ", action=" << keyEntry.action
6811 << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex
6812 << keyEntry.policyFlags;
6813 ;
6814 KeyEvent event = createKeyEvent(keyEntry);
6815
6816 mLock.unlock();
6817
6818 bool fallback = false;
6819 if (auto fb = mPolicy.dispatchUnhandledKey(connection->getToken(), event,
6820 keyEntry.policyFlags);
6821 fb) {
6822 fallback = true;
6823 event = *fb;
6824 }
6825
6826 mLock.lock();
6827
6828 if (connection->status != Connection::Status::NORMAL) {
6829 connection->inputState.removeFallbackKey(originalKeyCode);
6830 return {};
6831 }
6832
6833 // Latch the fallback keycode for this key on an initial down.
6834 // The fallback keycode cannot change at any other point in the lifecycle.
6835 if (initialDown) {
6836 if (fallback) {
6837 fallbackKeyCode = event.getKeyCode();
6838 } else {
6839 fallbackKeyCode = AKEYCODE_UNKNOWN;
6840 }
6841 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
6842 }
6843
6844 LOG_IF(FATAL, !fallbackKeyCode)
6845 << "fallbackKeyCode is not initialized. initialDown = " << initialDown;
6846
6847 // Cancel the fallback key if the policy decides not to send it anymore.
6848 // We will continue to dispatch the key to the policy but we will no
6849 // longer dispatch a fallback key to the application.
6850 if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6851 (!fallback || *fallbackKeyCode != event.getKeyCode())) {
6852 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6853 if (fallback) {
6854 ALOGD("Unhandled key event: Policy requested to send key %d"
6855 "as a fallback for %d, but on the DOWN it had requested "
6856 "to send %d instead. Fallback canceled.",
6857 event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
6858 } else {
6859 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6860 "but on the DOWN it had requested to send %d. "
6861 "Fallback canceled.",
6862 originalKeyCode, *fallbackKeyCode);
6863 }
6864 }
6865
6866 const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken());
6867 if (windowHandle != nullptr) {
6868 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
6869 "canceling fallback, policy no longer desires it",
6870 keyEntry.traceTracker);
6871 options.keyCode = *fallbackKeyCode;
6872 synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection);
6873 }
6874
6875 fallback = false;
6876 *fallbackKeyCode = AKEYCODE_UNKNOWN;
6877 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
6878 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
6879 }
6880 }
6881
6882 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6883 {
6884 std::string msg;
6885 const std::map<int32_t, int32_t>& fallbackKeys =
6886 connection->inputState.getFallbackKeys();
6887 for (const auto& [key, value] : fallbackKeys) {
6888 msg += StringPrintf(", %d->%d", key, value);
6889 }
6890 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6891 fallbackKeys.size(), msg.c_str());
6892 }
6893 }
6894
6895 if (fallback) {
6896 // Return the fallback key that we want dispatched to the channel.
6897 std::unique_ptr<KeyEntry> newEntry =
6898 std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6899 event.getEventTime(), event.getDeviceId(),
6900 event.getSource(), event.getDisplayId(),
6901 keyEntry.policyFlags, keyEntry.action,
6902 event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6903 *fallbackKeyCode, event.getScanCode(),
6904 event.getMetaState(), event.getRepeatCount(),
6905 event.getDownTime());
6906 if (mTracer) {
6907 newEntry->traceTracker =
6908 mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker);
6909 }
6910 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
6911 << "Unhandled key event: Dispatching fallback key. originalKeyCode="
6912 << originalKeyCode << ", fallbackKeyCode=" << *fallbackKeyCode
6913 << ", fallbackMetaState=0x" << std::hex << keyEntry.metaState;
6914 return newEntry;
6915 } else {
6916 LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) << "Unhandled key event: No fallback key.";
6917
6918 // Report the key as unhandled, since there is no fallback key.
6919 mReporter->reportUnhandledKey(keyEntry.id);
6920 }
6921 }
6922 return {};
6923 }
6924
traceInboundQueueLengthLocked()6925 void InputDispatcher::traceInboundQueueLengthLocked() {
6926 if (ATRACE_ENABLED()) {
6927 ATRACE_INT("iq", mInboundQueue.size());
6928 }
6929 }
6930
traceOutboundQueueLength(const Connection & connection)6931 void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
6932 if (ATRACE_ENABLED()) {
6933 char counterName[40];
6934 snprintf(counterName, sizeof(counterName), "oq:%s",
6935 connection.getInputChannelName().c_str());
6936 ATRACE_INT(counterName, connection.outboundQueue.size());
6937 }
6938 }
6939
traceWaitQueueLength(const Connection & connection)6940 void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
6941 if (ATRACE_ENABLED()) {
6942 char counterName[40];
6943 snprintf(counterName, sizeof(counterName), "wq:%s",
6944 connection.getInputChannelName().c_str());
6945 ATRACE_INT(counterName, connection.waitQueue.size());
6946 }
6947 }
6948
dump(std::string & dump) const6949 void InputDispatcher::dump(std::string& dump) const {
6950 std::scoped_lock _l(mLock);
6951
6952 dump += "Input Dispatcher State:\n";
6953 dumpDispatchStateLocked(dump);
6954
6955 if (!mLastAnrState.empty()) {
6956 dump += "\nInput Dispatcher State at time of last ANR:\n";
6957 dump += mLastAnrState;
6958 }
6959 }
6960
monitor()6961 void InputDispatcher::monitor() {
6962 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
6963 std::unique_lock _l(mLock);
6964 mLooper->wake();
6965 mDispatcherIsAlive.wait(_l);
6966 }
6967
6968 /**
6969 * Wake up the dispatcher and wait until it processes all events and commands.
6970 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6971 * this method can be safely called from any thread, as long as you've ensured that
6972 * the work you are interested in completing has already been queued.
6973 */
waitForIdle() const6974 bool InputDispatcher::waitForIdle() const {
6975 /**
6976 * Timeout should represent the longest possible time that a device might spend processing
6977 * events and commands.
6978 */
6979 constexpr std::chrono::duration TIMEOUT = 100ms;
6980 std::unique_lock lock(mLock);
6981 mLooper->wake();
6982 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6983 return result == std::cv_status::no_timeout;
6984 }
6985
6986 /**
6987 * Sets focus to the window identified by the token. This must be called
6988 * after updating any input window handles.
6989 *
6990 * Params:
6991 * request.token - input channel token used to identify the window that should gain focus.
6992 * request.focusedToken - the token that the caller expects currently to be focused. If the
6993 * specified token does not match the currently focused window, this request will be dropped.
6994 * If the specified focused token matches the currently focused window, the call will succeed.
6995 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6996 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6997 * when requesting the focus change. This determines which request gets
6998 * precedence if there is a focus change request from another source such as pointer down.
6999 */
setFocusedWindow(const FocusRequest & request)7000 void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
7001 { // acquire lock
7002 std::scoped_lock _l(mLock);
7003 std::optional<FocusResolver::FocusChanges> changes =
7004 mFocusResolver.setFocusedWindow(request,
7005 mWindowInfos.getWindowHandlesForDisplay(
7006 ui::LogicalDisplayId{request.displayId}));
7007 ScopedSyntheticEventTracer traceContext(mTracer);
7008 if (changes) {
7009 onFocusChangedLocked(*changes, traceContext.getTracker());
7010 }
7011 } // release lock
7012 // Wake up poll loop since it may need to make new input dispatching choices.
7013 mLooper->wake();
7014 }
7015
onFocusChangedLocked(const FocusResolver::FocusChanges & changes,const std::unique_ptr<trace::EventTrackerInterface> & traceTracker,const sp<WindowInfoHandle> removedFocusedWindowHandle)7016 void InputDispatcher::onFocusChangedLocked(
7017 const FocusResolver::FocusChanges& changes,
7018 const std::unique_ptr<trace::EventTrackerInterface>& traceTracker,
7019 const sp<WindowInfoHandle> removedFocusedWindowHandle) {
7020 if (changes.oldFocus) {
7021 const auto resolvedWindow = removedFocusedWindowHandle != nullptr
7022 ? removedFocusedWindowHandle
7023 : mWindowInfos.findWindowHandle(changes.oldFocus, changes.displayId);
7024 if (resolvedWindow == nullptr) {
7025 LOG(FATAL) << __func__ << ": Previously focused token did not have a window";
7026 }
7027 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
7028 "focus left window", traceTracker);
7029 synthesizeCancelationEventsForWindowLocked(resolvedWindow, options);
7030 enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
7031 }
7032 if (changes.newFocus) {
7033 resetNoFocusedWindowTimeoutLocked();
7034 enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
7035 }
7036
7037 if (mFocusedDisplayId == changes.displayId) {
7038 // If a window has pointer capture, then it must have focus and must be on the top-focused
7039 // display. We need to ensure that this contract is upheld when pointer capture is being
7040 // disabled due to a loss of window focus. If the window loses focus before it loses pointer
7041 // capture, then the window can be in a state where it has pointer capture but not focus,
7042 // violating the contract. Therefore we must dispatch the pointer capture event before the
7043 // focus event. Since focus events are added to the front of the queue (above), we add the
7044 // pointer capture event to the front of the queue after the focus events are added. This
7045 // ensures the pointer capture event ends up at the front.
7046 disablePointerCaptureForcedLocked();
7047
7048 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
7049 }
7050 }
7051
disablePointerCaptureForcedLocked()7052 void InputDispatcher::disablePointerCaptureForcedLocked() {
7053 if (!mCurrentPointerCaptureRequest.isEnable() && !mWindowTokenWithPointerCapture) {
7054 return;
7055 }
7056
7057 LOG_IF(INFO, DEBUG_FOCUS) << "Disabling Pointer Capture because the window lost focus.";
7058
7059 if (mCurrentPointerCaptureRequest.isEnable()) {
7060 setPointerCaptureLocked(nullptr);
7061 }
7062
7063 if (!mWindowTokenWithPointerCapture) {
7064 // No need to send capture changes because no window has capture.
7065 return;
7066 }
7067
7068 if (mPendingEvent != nullptr) {
7069 // Move the pending event to the front of the queue. This will give the chance
7070 // for the pending event to be dropped if it is a captured event.
7071 mInboundQueue.push_front(mPendingEvent);
7072 mPendingEvent = nullptr;
7073 }
7074
7075 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
7076 mCurrentPointerCaptureRequest);
7077 mInboundQueue.push_front(std::move(entry));
7078 }
7079
setPointerCaptureLocked(const sp<IBinder> & windowToken)7080 void InputDispatcher::setPointerCaptureLocked(const sp<IBinder>& windowToken) {
7081 mCurrentPointerCaptureRequest.window = windowToken;
7082 mCurrentPointerCaptureRequest.seq++;
7083 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
7084 scoped_unlock unlock(mLock);
7085 mPolicy.setPointerCapture(request);
7086 };
7087 postCommandLocked(std::move(command));
7088 }
7089
displayRemoved(ui::LogicalDisplayId displayId)7090 void InputDispatcher::displayRemoved(ui::LogicalDisplayId displayId) {
7091 { // acquire lock
7092 std::scoped_lock _l(mLock);
7093 // Set an empty list to remove all handles from the specific display.
7094 setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
7095 setFocusedApplicationLocked(displayId, nullptr);
7096 // Call focus resolver to clean up stale requests. This must be called after input windows
7097 // have been removed for the removed display.
7098 mFocusResolver.displayRemoved(displayId);
7099 // Reset pointer capture eligibility, regardless of previous state.
7100 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
7101 // Remove the associated touch mode state.
7102 mTouchModePerDisplay.erase(displayId);
7103 mVerifiersByDisplay.erase(displayId);
7104 mInputFilterVerifiersByDisplay.erase(displayId);
7105 } // release lock
7106
7107 // Wake up poll loop since it may need to make new input dispatching choices.
7108 mLooper->wake();
7109 }
7110
onWindowInfosChanged(const gui::WindowInfosUpdate & update)7111 void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
7112 if (auto result = validateWindowInfosUpdate(update); !result.ok()) {
7113 {
7114 // acquire lock
7115 std::scoped_lock _l(mLock);
7116 logDispatchStateLocked();
7117 }
7118 LOG_ALWAYS_FATAL("Incorrect WindowInfosUpdate provided: %s",
7119 result.error().message().c_str());
7120 };
7121 // The listener sends the windows as a flattened array. Separate the windows by display for
7122 // more convenient parsing.
7123 std::unordered_map<ui::LogicalDisplayId, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
7124 for (const auto& info : update.windowInfos) {
7125 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
7126 handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
7127 }
7128
7129 { // acquire lock
7130 std::scoped_lock _l(mLock);
7131
7132 // Ensure that we have an entry created for all existing displays so that if a displayId has
7133 // no windows, we can tell that the windows were removed from the display.
7134 mWindowInfos.forEachDisplayId(
7135 [&](ui::LogicalDisplayId displayId) { handlesPerDisplay[displayId]; });
7136
7137 mWindowInfos.setDisplayInfos(update.displayInfos);
7138
7139 for (const auto& [displayId, handles] : handlesPerDisplay) {
7140 setInputWindowsLocked(handles, displayId);
7141 }
7142
7143 mWindowInfosVsyncId = update.vsyncId;
7144 }
7145 // Wake up poll loop since it may need to make new input dispatching choices.
7146 mLooper->wake();
7147 }
7148
shouldDropInput(const EventEntry & entry,const sp<WindowInfoHandle> & windowHandle,const DispatcherWindowInfo & windowInfos)7149 bool InputDispatcher::shouldDropInput(const EventEntry& entry,
7150 const sp<WindowInfoHandle>& windowHandle,
7151 const DispatcherWindowInfo& windowInfos) {
7152 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
7153 (windowHandle->getInfo()->inputConfig.test(
7154 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
7155 windowInfos.isWindowObscured(windowHandle))) {
7156 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
7157 "display %s.",
7158 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
7159 windowHandle->getInfo()->inputConfig.string().c_str(),
7160 windowHandle->getInfo()->displayId.toString().c_str());
7161 return true;
7162 }
7163 return false;
7164 }
7165
onWindowInfosChanged(const gui::WindowInfosUpdate & update)7166 void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
7167 const gui::WindowInfosUpdate& update) {
7168 mDispatcher.onWindowInfosChanged(update);
7169 }
7170
cancelCurrentTouch()7171 void InputDispatcher::cancelCurrentTouch() {
7172 {
7173 std::scoped_lock _l(mLock);
7174 ScopedSyntheticEventTracer traceContext(mTracer);
7175 ALOGD("Canceling all ongoing pointer gestures on all displays.");
7176 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
7177 "cancel current touch", traceContext.getTracker());
7178 synthesizeCancelationEventsForAllConnectionsLocked(options);
7179
7180 mTouchStates.clear();
7181 }
7182 // Wake up poll loop since there might be work to do.
7183 mLooper->wake();
7184 }
7185
setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout)7186 void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
7187 std::scoped_lock _l(mLock);
7188 mMonitorDispatchingTimeout = timeout;
7189 }
7190
slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,const sp<WindowInfoHandle> & oldWindowHandle,const sp<WindowInfoHandle> & newWindowHandle,TouchState & state,const MotionEntry & entry,std::vector<InputTarget> & targets,std::function<void ()> dump)7191 void InputDispatcher::DispatcherTouchState::slipWallpaperTouch(
7192 ftl::Flags<InputTarget::Flags> targetFlags, const sp<WindowInfoHandle>& oldWindowHandle,
7193 const sp<WindowInfoHandle>& newWindowHandle, TouchState& state, const MotionEntry& entry,
7194 std::vector<InputTarget>& targets, std::function<void()> dump) {
7195 LOG_IF(FATAL, entry.getPointerCount() != 1) << "Entry not eligible for slip: " << entry;
7196 const DeviceId deviceId = entry.deviceId;
7197 const PointerProperties& pointerProperties = entry.pointerProperties[0];
7198 std::vector<PointerProperties> pointers{pointerProperties};
7199 const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
7200 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7201 const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
7202 newWindowHandle->getInfo()->inputConfig.test(
7203 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7204 const sp<WindowInfoHandle> oldWallpaper =
7205 oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
7206 const sp<WindowInfoHandle> newWallpaper =
7207 newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(newWindowHandle) : nullptr;
7208 if (oldWallpaper == newWallpaper) {
7209 return;
7210 }
7211
7212 if (oldWallpaper != nullptr) {
7213 const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
7214 addPointerWindowTarget(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
7215 oldTouchedWindow.targetFlags, getPointerIds(pointers),
7216 oldTouchedWindow.getDownTimeInTarget(deviceId),
7217 /*pointerDisplayId=*/std::nullopt, dump, targets);
7218 state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
7219 }
7220
7221 if (newWallpaper != nullptr) {
7222 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
7223 InputTarget::Flags::WINDOW_IS_OBSCURED |
7224 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
7225 deviceId, pointers, entry.eventTime,
7226 /*forwardingWindowToken=*/nullptr);
7227 }
7228 }
7229
7230 std::pair<std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>,
7231 std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>
transferWallpaperTouch(const sp<gui::WindowInfoHandle> fromWindowHandle,const sp<gui::WindowInfoHandle> toWindowHandle,TouchState & state,android::DeviceId deviceId,const std::vector<PointerProperties> & pointers,ftl::Flags<InputTarget::Flags> oldTargetFlags,ftl::Flags<InputTarget::Flags> newTargetFlags)7232 InputDispatcher::DispatcherTouchState::transferWallpaperTouch(
7233 const sp<gui::WindowInfoHandle> fromWindowHandle,
7234 const sp<gui::WindowInfoHandle> toWindowHandle, TouchState& state,
7235 android::DeviceId deviceId, const std::vector<PointerProperties>& pointers,
7236 ftl::Flags<InputTarget::Flags> oldTargetFlags,
7237 ftl::Flags<InputTarget::Flags> newTargetFlags) {
7238 const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
7239 fromWindowHandle->getInfo()->inputConfig.test(
7240 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7241 const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
7242 toWindowHandle->getInfo()->inputConfig.test(
7243 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7244
7245 const sp<WindowInfoHandle> oldWallpaper =
7246 oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
7247 const sp<WindowInfoHandle> newWallpaper =
7248 newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(toWindowHandle) : nullptr;
7249 if (oldWallpaper == newWallpaper) {
7250 return {};
7251 }
7252
7253 std::list<CancellationArgs> cancellations;
7254 std::list<PointerDownArgs> pointerDowns;
7255 if (oldWallpaper != nullptr) {
7256 state.removeWindowByToken(oldWallpaper->getToken());
7257 cancellations.emplace_back(oldWallpaper, CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
7258 }
7259
7260 if (newWallpaper != nullptr) {
7261 nsecs_t downTimeInTarget = now();
7262 ftl::Flags<InputTarget::Flags> wallpaperFlags = newTargetFlags;
7263 wallpaperFlags |= oldTargetFlags & InputTarget::Flags::SPLIT;
7264 wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
7265 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
7266 state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
7267 deviceId, pointers, downTimeInTarget,
7268 /*forwardingWindowToken=*/nullptr);
7269 std::shared_ptr<Connection> wallpaperConnection =
7270 mConnectionManager.getConnection(newWallpaper->getToken());
7271 if (wallpaperConnection != nullptr) {
7272 std::shared_ptr<Connection> toConnection =
7273 mConnectionManager.getConnection(toWindowHandle->getToken());
7274 toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
7275 pointerDowns.emplace_back(downTimeInTarget, wallpaperConnection, wallpaperFlags);
7276 }
7277 pointerDowns.emplace_back(downTimeInTarget, wallpaperConnection, wallpaperFlags);
7278 }
7279 return {cancellations, pointerDowns};
7280 }
7281
findWallpaperWindowBelow(const sp<WindowInfoHandle> & windowHandle) const7282 sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWallpaperWindowBelow(
7283 const sp<WindowInfoHandle>& windowHandle) const {
7284 const std::vector<sp<WindowInfoHandle>>& windowHandles =
7285 getWindowHandlesForDisplay(windowHandle->getInfo()->displayId);
7286 bool foundWindow = false;
7287 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
7288 if (!foundWindow && otherHandle != windowHandle) {
7289 continue;
7290 }
7291 if (windowHandle == otherHandle) {
7292 foundWindow = true;
7293 continue;
7294 }
7295
7296 if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
7297 return otherHandle;
7298 }
7299 }
7300 return nullptr;
7301 }
7302
setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,std::chrono::nanoseconds delay,bool keyRepeatEnabled)7303 void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
7304 std::chrono::nanoseconds delay,
7305 bool keyRepeatEnabled) {
7306 std::scoped_lock _l(mLock);
7307
7308 mConfig.keyRepeatTimeout = timeout.count();
7309 mConfig.keyRepeatDelay = delay.count();
7310 mConfig.keyRepeatEnabled = keyRepeatEnabled;
7311 }
7312
isPointerInWindow(const sp<android::IBinder> & token,ui::LogicalDisplayId displayId,DeviceId deviceId,int32_t pointerId)7313 bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token,
7314 ui::LogicalDisplayId displayId, DeviceId deviceId,
7315 int32_t pointerId) {
7316 std::scoped_lock _l(mLock);
7317 return mTouchStates.isPointerInWindow(token, displayId, deviceId, pointerId);
7318 }
7319
setInputMethodConnectionIsActive(bool isActive)7320 void InputDispatcher::setInputMethodConnectionIsActive(bool isActive) {
7321 std::scoped_lock _l(mLock);
7322 if (mTracer) {
7323 mTracer->setInputMethodConnectionIsActive(isActive);
7324 }
7325 }
7326
setDisplayTopology(const android::DisplayTopologyGraph & displayTopologyGraph)7327 void InputDispatcher::setDisplayTopology(
7328 const android::DisplayTopologyGraph& displayTopologyGraph) {
7329 std::scoped_lock _l(mLock);
7330 mWindowInfos.setDisplayTopology(displayTopologyGraph);
7331 }
7332
ConnectionManager(const sp<android::Looper> & looper)7333 InputDispatcher::ConnectionManager::ConnectionManager(const sp<android::Looper>& looper)
7334 : mLooper(looper) {}
7335
7336 // This destructor is required to ensure cleanup of each input connection, so that the fd is
7337 // removed from the looper.
~ConnectionManager()7338 InputDispatcher::ConnectionManager::~ConnectionManager() {
7339 while (!mConnectionsByToken.empty()) {
7340 std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
7341 removeConnection(connection);
7342 }
7343 }
7344
forEachGlobalMonitorConnection(std::function<void (const std::shared_ptr<Connection> &)> f) const7345 void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
7346 std::function<void(const std::shared_ptr<Connection>&)> f) const {
7347 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
7348 for (const Monitor& monitor : monitors) {
7349 f(monitor.connection);
7350 }
7351 }
7352 }
7353
forEachGlobalMonitorConnection(ui::LogicalDisplayId displayId,std::function<void (const std::shared_ptr<Connection> &)> f) const7354 void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
7355 ui::LogicalDisplayId displayId,
7356 std::function<void(const std::shared_ptr<Connection>&)> f) const {
7357 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
7358 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
7359
7360 for (const Monitor& monitor : monitorsIt->second) {
7361 f(monitor.connection);
7362 }
7363 }
7364
createGlobalInputMonitor(ui::LogicalDisplayId displayId,std::unique_ptr<InputChannel> && inputChannel,const android::IdGenerator & idGenerator,gui::Pid pid,std::function<int (int)> callback)7365 void InputDispatcher::ConnectionManager::createGlobalInputMonitor(
7366 ui::LogicalDisplayId displayId, std::unique_ptr<InputChannel>&& inputChannel,
7367 const android::IdGenerator& idGenerator, gui::Pid pid, std::function<int(int)> callback) {
7368 const int fd = inputChannel->getFd();
7369 std::shared_ptr<Connection> connection =
7370 std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/true, idGenerator);
7371 sp<IBinder> token = connection->getToken();
7372 auto [_, inserted] = mConnectionsByToken.emplace(token, connection);
7373 if (!inserted) {
7374 ALOGE("Created a new connection, but the token %p is already known", token.get());
7375 }
7376 mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
7377
7378 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), nullptr);
7379 }
7380
createConnection(std::unique_ptr<InputChannel> && inputChannel,const android::IdGenerator & idGenerator,std::function<int (int)> callback)7381 void InputDispatcher::ConnectionManager::createConnection(
7382 std::unique_ptr<InputChannel>&& inputChannel, const android::IdGenerator& idGenerator,
7383 std::function<int(int)> callback) {
7384 const int fd = inputChannel->getFd();
7385 std::shared_ptr<Connection> connection =
7386 std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/false, idGenerator);
7387 sp<IBinder> token = connection->getToken();
7388 auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection);
7389 if (!inserted) {
7390 ALOGE("Created a new connection, but the token %p is already known", token.get());
7391 }
7392
7393 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), nullptr);
7394 }
7395
removeConnection(const std::shared_ptr<Connection> & connection)7396 status_t InputDispatcher::ConnectionManager::removeConnection(
7397 const std::shared_ptr<Connection>& connection) {
7398 mConnectionsByToken.erase(connection->getToken());
7399
7400 if (connection->monitor) {
7401 removeMonitorChannel(connection->getToken());
7402 }
7403
7404 mLooper->removeFd(connection->inputPublisher.getChannel().getFd());
7405
7406 connection->status = Connection::Status::ZOMBIE;
7407 return OK;
7408 }
7409
dump(nsecs_t currentTime) const7410 std::string InputDispatcher::ConnectionManager::dump(nsecs_t currentTime) const {
7411 std::string dump;
7412 if (!mGlobalMonitorsByDisplay.empty()) {
7413 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
7414 dump += StringPrintf("Global monitors on display %s:\n", displayId.toString().c_str());
7415 const size_t numMonitors = monitors.size();
7416 for (size_t i = 0; i < numMonitors; i++) {
7417 const Monitor& monitor = monitors[i];
7418 const std::shared_ptr<Connection>& connection = monitor.connection;
7419 dump += StringPrintf(INDENT "%zu: '%s', ", i,
7420 connection->getInputChannelName().c_str());
7421 dump += "\n";
7422 }
7423 }
7424 } else {
7425 dump += "Global Monitors: <none>\n";
7426 }
7427
7428 if (!mConnectionsByToken.empty()) {
7429 dump += "Connections:\n";
7430 for (const auto& [token, connection] : mConnectionsByToken) {
7431 dump += StringPrintf(INDENT "%i: channelName='%s', "
7432 "status=%s, monitor=%s, responsive=%s\n",
7433 connection->inputPublisher.getChannel().getFd(),
7434 connection->getInputChannelName().c_str(),
7435 ftl::enum_string(connection->status).c_str(),
7436 toString(connection->monitor), toString(connection->responsive));
7437
7438 if (!connection->outboundQueue.empty()) {
7439 dump += StringPrintf(INDENT2 "OutboundQueue: length=%zu\n",
7440 connection->outboundQueue.size());
7441 dump += dumpQueue(connection->outboundQueue, currentTime);
7442 }
7443
7444 if (!connection->waitQueue.empty()) {
7445 dump += StringPrintf(INDENT2 "WaitQueue: length=%zu\n",
7446 connection->waitQueue.size());
7447 dump += dumpQueue(connection->waitQueue, currentTime);
7448 }
7449 std::string inputStateDump = streamableToString(connection->inputState);
7450 if (!inputStateDump.empty()) {
7451 dump += INDENT2 "InputState: ";
7452 dump += inputStateDump + "\n";
7453 }
7454 }
7455 } else {
7456 dump += "Connections: <none>\n";
7457 }
7458 return dump;
7459 }
7460
setMaximumObscuringOpacityForTouch(float opacity)7461 void InputDispatcher::DispatcherWindowInfo::setMaximumObscuringOpacityForTouch(float opacity) {
7462 if (opacity < 0 || opacity > 1) {
7463 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
7464 }
7465 mMaximumObscuringOpacityForTouch = opacity;
7466 }
7467
setDisplayTopology(const DisplayTopologyGraph & displayTopologyGraph)7468 void InputDispatcher::DispatcherWindowInfo::setDisplayTopology(
7469 const DisplayTopologyGraph& displayTopologyGraph) {
7470 mTopology = displayTopologyGraph;
7471 }
7472
DispatcherTouchState(const DispatcherWindowInfo & windowInfos,const ConnectionManager & connections)7473 InputDispatcher::DispatcherTouchState::DispatcherTouchState(const DispatcherWindowInfo& windowInfos,
7474 const ConnectionManager& connections)
7475 : mWindowInfos(windowInfos), mConnectionManager(connections) {}
7476
getTargetFlags(const sp<WindowInfoHandle> & targetWindow,vec2 targetPosition,bool isSplit)7477 ftl::Flags<InputTarget::Flags> InputDispatcher::DispatcherTouchState::getTargetFlags(
7478 const sp<WindowInfoHandle>& targetWindow, vec2 targetPosition, bool isSplit) {
7479 ftl::Flags<InputTarget::Flags> targetFlags;
7480 if (canReceiveForegroundTouches(*targetWindow->getInfo())) {
7481 // There should only be one touched window that can be "foreground" for the pointer.
7482 targetFlags |= InputTarget::Flags::FOREGROUND;
7483 }
7484 if (isSplit) {
7485 targetFlags |= InputTarget::Flags::SPLIT;
7486 }
7487 if (mWindowInfos.isWindowObscuredAtPoint(targetWindow, targetPosition.x, targetPosition.y)) {
7488 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
7489 } else if (mWindowInfos.isWindowObscured(targetWindow)) {
7490 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
7491 }
7492 return targetFlags;
7493 }
7494
hasTouchingOrHoveringPointers(ui::LogicalDisplayId displayId,int32_t deviceId) const7495 bool InputDispatcher::DispatcherTouchState::hasTouchingOrHoveringPointers(
7496 ui::LogicalDisplayId displayId, int32_t deviceId) const {
7497 bool hasTouchingOrHoveringPointers = false;
7498 forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) {
7499 hasTouchingOrHoveringPointers =
7500 state.hasTouchingPointers(deviceId) || state.hasHoveringPointers(deviceId);
7501 return hasTouchingOrHoveringPointers;
7502 });
7503 return hasTouchingOrHoveringPointers;
7504 }
7505
isPointerInWindow(const sp<android::IBinder> & token,ui::LogicalDisplayId displayId,android::DeviceId deviceId,int32_t pointerId) const7506 bool InputDispatcher::DispatcherTouchState::isPointerInWindow(const sp<android::IBinder>& token,
7507 ui::LogicalDisplayId displayId,
7508 android::DeviceId deviceId,
7509 int32_t pointerId) const {
7510 bool isPointerInWindow = false;
7511 forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) {
7512 for (const TouchedWindow& window : state.windows) {
7513 if (window.windowHandle->getToken() == token &&
7514 (window.hasTouchingPointer(deviceId, pointerId) ||
7515 window.hasHoveringPointer(deviceId, pointerId))) {
7516 isPointerInWindow = true;
7517 return true;
7518 }
7519 }
7520 return false;
7521 });
7522 return isPointerInWindow;
7523 }
7524
7525 std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId>
findExistingTouchedWindowHandleAndDisplay(const sp<android::IBinder> & token) const7526 InputDispatcher::DispatcherTouchState::findExistingTouchedWindowHandleAndDisplay(
7527 const sp<android::IBinder>& token) const {
7528 std::optional<std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId>>
7529 touchedWindowHandleAndDisplay;
7530 forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, const TouchState& state) {
7531 for (const TouchedWindow& w : state.windows) {
7532 if (w.windowHandle->getToken() == token) {
7533 touchedWindowHandleAndDisplay.emplace(std::ref(w.windowHandle), displayId);
7534 return true;
7535 }
7536 }
7537 return false;
7538 });
7539 LOG_ALWAYS_FATAL_IF(!touchedWindowHandleAndDisplay.has_value(),
7540 "%s : Touch state is out of sync: No touched window for token", __func__);
7541 return touchedWindowHandleAndDisplay.value();
7542 }
7543
forAllTouchedWindows(std::function<void (const sp<gui::WindowInfoHandle> &)> f) const7544 void InputDispatcher::DispatcherTouchState::forAllTouchedWindows(
7545 std::function<void(const sp<gui::WindowInfoHandle>&)> f) const {
7546 forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, const TouchState& state) {
7547 for (const TouchedWindow& window : state.windows) {
7548 f(window.windowHandle);
7549 }
7550 return false;
7551 });
7552 }
7553
forAllTouchedWindowsOnDisplay(ui::LogicalDisplayId displayId,std::function<void (const sp<gui::WindowInfoHandle> &)> f) const7554 void InputDispatcher::DispatcherTouchState::forAllTouchedWindowsOnDisplay(
7555 ui::LogicalDisplayId displayId,
7556 std::function<void(const sp<gui::WindowInfoHandle>&)> f) const {
7557 forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) {
7558 for (const TouchedWindow& window : state.windows) {
7559 f(window.windowHandle);
7560 }
7561 return false;
7562 });
7563 }
7564
dump() const7565 std::string InputDispatcher::DispatcherTouchState::dump() const {
7566 std::string dump;
7567 if (mTouchStatesByDisplay.empty()) {
7568 dump += "TouchStatesByDisplay: <no displays touched>\n";
7569 } else {
7570 dump += "TouchStatesByDisplay:\n";
7571 for (const auto& [displayId, state] : mTouchStatesByDisplay) {
7572 std::string touchStateDump = addLinePrefix(state.dump(), INDENT);
7573 dump += INDENT + displayId.toString() + " : " + touchStateDump;
7574 }
7575 }
7576 if (mCursorStateByDisplay.empty()) {
7577 dump += "CursorStatesByDisplay: <no displays touched by cursor>\n";
7578 } else {
7579 dump += "CursorStatesByDisplay:\n";
7580 for (const auto& [displayId, state] : mCursorStateByDisplay) {
7581 std::string touchStateDump = addLinePrefix(state.dump(), INDENT);
7582 dump += INDENT + displayId.toString() + " : " + touchStateDump;
7583 }
7584 }
7585 return dump;
7586 }
7587
removeAllPointersForDevice(android::DeviceId deviceId)7588 void InputDispatcher::DispatcherTouchState::removeAllPointersForDevice(android::DeviceId deviceId) {
7589 forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, TouchState& state) {
7590 state.removeAllPointersForDevice(deviceId);
7591 return false;
7592 });
7593 }
7594
clear()7595 void InputDispatcher::DispatcherTouchState::clear() {
7596 mTouchStatesByDisplay.clear();
7597 mCursorStateByDisplay.clear();
7598 }
7599
saveTouchStateForMotionEntry(const android::inputdispatcher::MotionEntry & entry,android::inputdispatcher::TouchState && touchState)7600 void InputDispatcher::DispatcherTouchState::saveTouchStateForMotionEntry(
7601 const android::inputdispatcher::MotionEntry& entry,
7602 android::inputdispatcher::TouchState&& touchState) {
7603 if (touchState.windows.empty()) {
7604 eraseTouchStateForMotionEntry(entry);
7605 return;
7606 }
7607
7608 if (InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source)) {
7609 mCursorStateByDisplay[mWindowInfos.getPrimaryDisplayId(entry.displayId)] =
7610 std::move(touchState);
7611 } else {
7612 mTouchStatesByDisplay[entry.displayId] = std::move(touchState);
7613 }
7614 }
7615
eraseTouchStateForMotionEntry(const android::inputdispatcher::MotionEntry & entry)7616 void InputDispatcher::DispatcherTouchState::eraseTouchStateForMotionEntry(
7617 const android::inputdispatcher::MotionEntry& entry) {
7618 if (InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source)) {
7619 mCursorStateByDisplay.erase(mWindowInfos.getPrimaryDisplayId(entry.displayId));
7620 } else {
7621 mTouchStatesByDisplay.erase(entry.displayId);
7622 }
7623 }
7624
getTouchStateForMotionEntry(const android::inputdispatcher::MotionEntry & entry) const7625 const TouchState* InputDispatcher::DispatcherTouchState::getTouchStateForMotionEntry(
7626 const android::inputdispatcher::MotionEntry& entry) const {
7627 if (InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source)) {
7628 auto touchStateIt =
7629 mCursorStateByDisplay.find(mWindowInfos.getPrimaryDisplayId(entry.displayId));
7630 if (touchStateIt != mCursorStateByDisplay.end()) {
7631 return &touchStateIt->second;
7632 }
7633 } else {
7634 auto touchStateIt = mTouchStatesByDisplay.find(entry.displayId);
7635 if (touchStateIt != mTouchStatesByDisplay.end()) {
7636 return &touchStateIt->second;
7637 }
7638 }
7639 return nullptr;
7640 }
7641
forTouchAndCursorStatesOnDisplay(ui::LogicalDisplayId displayId,std::function<bool (const TouchState &)> f) const7642 void InputDispatcher::DispatcherTouchState::forTouchAndCursorStatesOnDisplay(
7643 ui::LogicalDisplayId displayId, std::function<bool(const TouchState&)> f) const {
7644 const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
7645 if (touchStateIt != mTouchStatesByDisplay.end() && f(touchStateIt->second)) {
7646 return;
7647 }
7648
7649 // DisplayId for the Cursor state may not be same as supplied displayId if display is part of
7650 // topology. Instead we should to check from the topology's primary display.
7651 const auto cursorStateIt =
7652 mCursorStateByDisplay.find(mWindowInfos.getPrimaryDisplayId(displayId));
7653 if (cursorStateIt != mCursorStateByDisplay.end()) {
7654 f(cursorStateIt->second);
7655 }
7656 }
7657
forTouchAndCursorStatesOnDisplay(ui::LogicalDisplayId displayId,std::function<bool (TouchState &)> f)7658 void InputDispatcher::DispatcherTouchState::forTouchAndCursorStatesOnDisplay(
7659 ui::LogicalDisplayId displayId, std::function<bool(TouchState&)> f) {
7660 const_cast<const DispatcherTouchState&>(*this)
7661 .forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) {
7662 return f(const_cast<TouchState&>(state));
7663 });
7664 }
7665
forAllTouchAndCursorStates(std::function<bool (ui::LogicalDisplayId,const TouchState &)> f) const7666 void InputDispatcher::DispatcherTouchState::forAllTouchAndCursorStates(
7667 std::function<bool(ui::LogicalDisplayId, const TouchState&)> f) const {
7668 for (auto& [displayId, state] : mTouchStatesByDisplay) {
7669 if (f(displayId, state)) {
7670 return;
7671 }
7672 }
7673 for (auto& [displayId, state] : mCursorStateByDisplay) {
7674 if (f(displayId, state)) {
7675 return;
7676 }
7677 }
7678 }
7679
forAllTouchAndCursorStates(std::function<bool (ui::LogicalDisplayId,TouchState &)> f)7680 void InputDispatcher::DispatcherTouchState::forAllTouchAndCursorStates(
7681 std::function<bool(ui::LogicalDisplayId, TouchState&)> f) {
7682 const_cast<const DispatcherTouchState&>(*this).forAllTouchAndCursorStates(
7683 [&](ui::LogicalDisplayId displayId, const TouchState& constState) {
7684 return f(displayId, const_cast<TouchState&>(constState));
7685 });
7686 }
7687
7688 std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>>
findTouchStateWindowAndDisplay(const sp<android::IBinder> & token)7689 InputDispatcher::DispatcherTouchState::findTouchStateWindowAndDisplay(
7690 const sp<android::IBinder>& token) {
7691 std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>>
7692 touchStateWindowAndDisplay;
7693 forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, TouchState& state) {
7694 for (TouchedWindow& w : state.windows) {
7695 if (w.windowHandle->getToken() == token) {
7696 touchStateWindowAndDisplay.emplace(std::ref(state), std::ref(w), displayId);
7697 return true;
7698 }
7699 }
7700 return false;
7701 });
7702 return touchStateWindowAndDisplay;
7703 }
7704
isStylusActiveInDisplay(ui::LogicalDisplayId displayId) const7705 bool InputDispatcher::DispatcherTouchState::isStylusActiveInDisplay(
7706 ui::LogicalDisplayId displayId) const {
7707 const auto it = mTouchStatesByDisplay.find(displayId);
7708 if (it == mTouchStatesByDisplay.end()) {
7709 return false;
7710 }
7711 const TouchState& state = it->second;
7712 return state.hasActiveStylus();
7713 }
7714
7715 } // namespace android::inputdispatcher
7716