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