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