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