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