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