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