blob: 32cb04eaed5f7f3b1645ae34535388ddbd751014 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
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
Michael Wright3dd60e22019-03-27 22:06:44 +000020#define LOG_NDEBUG 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
38#define DEBUG_FOCUS 0
39
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Michael Wrightd02c5b62014-02-10 15:10:22 -080048#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080049#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <limits.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080051#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070052#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080053#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <unistd.h>
55
Michael Wright2b3c3302018-03-02 17:19:13 +000056#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080057#include <android-base/stringprintf.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070058#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059#include <utils/Trace.h>
60#include <powermanager/PowerManager.h>
Robert Carr4e670e52018-08-15 13:26:12 -070061#include <binder/Binder.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080062
63#define INDENT " "
64#define INDENT2 " "
65#define INDENT3 " "
66#define INDENT4 " "
67
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080068using android::base::StringPrintf;
69
Michael Wrightd02c5b62014-02-10 15:10:22 -080070namespace android {
71
72// Default input dispatching timeout if there is no focused application or paused window
73// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000074constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Amount of time to allow for all pending events to be processed when an app switch
77// key is on the way. This is used to preempt input dispatch and drop input events
78// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000079constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080080
81// Amount of time to allow for an event to be dispatched (measured since its eventTime)
82// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow touch events to be streamed out to a connection before requiring
86// that the first event be finished. This value extends the ANR timeout by the specified
87// amount. For example, if streaming is allowed to get ahead by one second relative to the
88// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000089constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000092constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
93
94// Log a warning when an interception call takes longer than this to process.
95constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
99
Prabir Pradhan42611e02018-11-27 14:04:02 -0800100// Sequence number for synthesized or injected events.
101constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
102
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800112static std::string motionActionToString(int32_t action) {
113 // Convert MotionEvent action to string
114 switch(action & AMOTION_EVENT_ACTION_MASK) {
115 case AMOTION_EVENT_ACTION_DOWN:
116 return "DOWN";
117 case AMOTION_EVENT_ACTION_MOVE:
118 return "MOVE";
119 case AMOTION_EVENT_ACTION_UP:
120 return "UP";
121 case AMOTION_EVENT_ACTION_POINTER_DOWN:
122 return "POINTER_DOWN";
123 case AMOTION_EVENT_ACTION_POINTER_UP:
124 return "POINTER_UP";
125 }
126 return StringPrintf("%" PRId32, action);
127}
128
129static std::string keyActionToString(int32_t action) {
130 // Convert KeyEvent action to string
Michael Wright3dd60e22019-03-27 22:06:44 +0000131 switch (action) {
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800132 case AKEY_EVENT_ACTION_DOWN:
133 return "DOWN";
134 case AKEY_EVENT_ACTION_UP:
135 return "UP";
136 case AKEY_EVENT_ACTION_MULTIPLE:
137 return "MULTIPLE";
138 }
139 return StringPrintf("%" PRId32, action);
140}
141
Michael Wright3dd60e22019-03-27 22:06:44 +0000142static std::string dispatchModeToString(int32_t dispatchMode) {
143 switch (dispatchMode) {
144 case InputTarget::FLAG_DISPATCH_AS_IS:
145 return "DISPATCH_AS_IS";
146 case InputTarget::FLAG_DISPATCH_AS_OUTSIDE:
147 return "DISPATCH_AS_OUTSIDE";
148 case InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER:
149 return "DISPATCH_AS_HOVER_ENTER";
150 case InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT:
151 return "DISPATCH_AS_HOVER_EXIT";
152 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT:
153 return "DISPATCH_AS_SLIPPERY_EXIT";
154 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER:
155 return "DISPATCH_AS_SLIPPERY_ENTER";
156 }
157 return StringPrintf("%" PRId32, dispatchMode);
158}
159
Michael Wrightd02c5b62014-02-10 15:10:22 -0800160static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
161 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
162 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
163}
164
165static bool isValidKeyAction(int32_t action) {
166 switch (action) {
167 case AKEY_EVENT_ACTION_DOWN:
168 case AKEY_EVENT_ACTION_UP:
169 return true;
170 default:
171 return false;
172 }
173}
174
175static bool validateKeyEvent(int32_t action) {
176 if (! isValidKeyAction(action)) {
177 ALOGE("Key event has invalid action code 0x%x", action);
178 return false;
179 }
180 return true;
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 switch (action & AMOTION_EVENT_ACTION_MASK) {
185 case AMOTION_EVENT_ACTION_DOWN:
186 case AMOTION_EVENT_ACTION_UP:
187 case AMOTION_EVENT_ACTION_CANCEL:
188 case AMOTION_EVENT_ACTION_MOVE:
189 case AMOTION_EVENT_ACTION_OUTSIDE:
190 case AMOTION_EVENT_ACTION_HOVER_ENTER:
191 case AMOTION_EVENT_ACTION_HOVER_MOVE:
192 case AMOTION_EVENT_ACTION_HOVER_EXIT:
193 case AMOTION_EVENT_ACTION_SCROLL:
194 return true;
195 case AMOTION_EVENT_ACTION_POINTER_DOWN:
196 case AMOTION_EVENT_ACTION_POINTER_UP: {
197 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800198 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 }
Michael Wright7b159c92015-05-14 14:48:03 +0100200 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
201 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
202 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 default:
204 return false;
205 }
206}
207
Michael Wright7b159c92015-05-14 14:48:03 +0100208static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100210 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 ALOGE("Motion event has invalid action code 0x%x", action);
212 return false;
213 }
214 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000215 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 pointerCount, MAX_POINTERS);
217 return false;
218 }
219 BitSet32 pointerIdBits;
220 for (size_t i = 0; i < pointerCount; i++) {
221 int32_t id = pointerProperties[i].id;
222 if (id < 0 || id > MAX_POINTER_ID) {
223 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
224 id, MAX_POINTER_ID);
225 return false;
226 }
227 if (pointerIdBits.hasBit(id)) {
228 ALOGE("Motion event has duplicate pointer id %d", id);
229 return false;
230 }
231 pointerIdBits.markBit(id);
232 }
233 return true;
234}
235
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800236static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800238 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800239 return;
240 }
241
242 bool first = true;
243 Region::const_iterator cur = region.begin();
244 Region::const_iterator const tail = region.end();
245 while (cur != tail) {
246 if (first) {
247 first = false;
248 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800249 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800251 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 cur++;
253 }
254}
255
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700256/**
257 * Find the entry in std::unordered_map by key, and return it.
258 * If the entry is not found, return a default constructed entry.
259 *
260 * Useful when the entries are vectors, since an empty vector will be returned
261 * if the entry is not found.
262 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
263 */
264template <typename T, typename U>
265static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
266 auto it = map.find(key);
Tiger Huang721e26f2018-07-24 22:26:19 +0800267 return it != map.end() ? it->second : T{};
268}
269
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270
271// --- InputDispatcher ---
272
Garfield Tan00f511d2019-06-12 16:55:40 -0700273InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
274 : mPolicy(policy),
275 mPendingEvent(nullptr),
276 mLastDropReason(DROP_REASON_NOT_DROPPED),
277 mAppSwitchSawKeyDown(false),
278 mAppSwitchDueTime(LONG_LONG_MAX),
279 mNextUnblockedEvent(nullptr),
280 mDispatchEnabled(false),
281 mDispatchFrozen(false),
282 mInputFilterEnabled(false),
283 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
284 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800285 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800286 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800287
Yi Kong9b14ac62018-07-17 13:48:38 -0700288 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800289
290 policy->getDispatcherConfiguration(&mConfig);
291}
292
293InputDispatcher::~InputDispatcher() {
294 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800295 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296
297 resetKeyRepeatLocked();
298 releasePendingEventLocked();
299 drainInboundQueueLocked();
300 }
301
302 while (mConnectionsByFd.size() != 0) {
303 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
304 }
305}
306
307void InputDispatcher::dispatchOnce() {
308 nsecs_t nextWakeupTime = LONG_LONG_MAX;
309 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800310 std::scoped_lock _l(mLock);
311 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800312
313 // Run a dispatch loop if there are no pending commands.
314 // The dispatch loop might enqueue commands to run afterwards.
315 if (!haveCommandsLocked()) {
316 dispatchOnceInnerLocked(&nextWakeupTime);
317 }
318
319 // Run all pending commands if there are any.
320 // If any commands were run then force the next poll to wake up immediately.
321 if (runCommandsLockedInterruptible()) {
322 nextWakeupTime = LONG_LONG_MIN;
323 }
324 } // release lock
325
326 // Wait for callback or timeout or wake. (make sure we round up, not down)
327 nsecs_t currentTime = now();
328 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
329 mLooper->pollOnce(timeoutMillis);
330}
331
332void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
333 nsecs_t currentTime = now();
334
Jeff Browndc5992e2014-04-11 01:27:26 -0700335 // Reset the key repeat timer whenever normal dispatch is suspended while the
336 // device is in a non-interactive state. This is to ensure that we abort a key
337 // repeat if the device is just coming out of sleep.
338 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800339 resetKeyRepeatLocked();
340 }
341
342 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
343 if (mDispatchFrozen) {
344#if DEBUG_FOCUS
345 ALOGD("Dispatch frozen. Waiting some more.");
346#endif
347 return;
348 }
349
350 // Optimize latency of app switches.
351 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
352 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
353 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
354 if (mAppSwitchDueTime < *nextWakeupTime) {
355 *nextWakeupTime = mAppSwitchDueTime;
356 }
357
358 // Ready to start a new event.
359 // If we don't already have a pending event, go grab one.
360 if (! mPendingEvent) {
361 if (mInboundQueue.isEmpty()) {
362 if (isAppSwitchDue) {
363 // The inbound queue is empty so the app switch key we were waiting
364 // for will never arrive. Stop waiting for it.
365 resetPendingAppSwitchLocked(false);
366 isAppSwitchDue = false;
367 }
368
369 // Synthesize a key repeat if appropriate.
370 if (mKeyRepeatState.lastKeyEntry) {
371 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
372 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
373 } else {
374 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
375 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
376 }
377 }
378 }
379
380 // Nothing to do if there is no pending event.
381 if (!mPendingEvent) {
382 return;
383 }
384 } else {
385 // Inbound queue has at least one entry.
386 mPendingEvent = mInboundQueue.dequeueAtHead();
387 traceInboundQueueLengthLocked();
388 }
389
390 // Poke user activity for this event.
391 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
392 pokeUserActivityLocked(mPendingEvent);
393 }
394
395 // Get ready to dispatch the event.
396 resetANRTimeoutsLocked();
397 }
398
399 // Now we have an event to dispatch.
400 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700401 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800402 bool done = false;
403 DropReason dropReason = DROP_REASON_NOT_DROPPED;
404 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
405 dropReason = DROP_REASON_POLICY;
406 } else if (!mDispatchEnabled) {
407 dropReason = DROP_REASON_DISABLED;
408 }
409
410 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700411 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800412 }
413
414 switch (mPendingEvent->type) {
415 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
416 ConfigurationChangedEntry* typedEntry =
417 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
418 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
419 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
420 break;
421 }
422
423 case EventEntry::TYPE_DEVICE_RESET: {
424 DeviceResetEntry* typedEntry =
425 static_cast<DeviceResetEntry*>(mPendingEvent);
426 done = dispatchDeviceResetLocked(currentTime, typedEntry);
427 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
428 break;
429 }
430
431 case EventEntry::TYPE_KEY: {
432 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
433 if (isAppSwitchDue) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800434 if (isAppSwitchKeyEvent(typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800435 resetPendingAppSwitchLocked(true);
436 isAppSwitchDue = false;
437 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
438 dropReason = DROP_REASON_APP_SWITCH;
439 }
440 }
441 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800442 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800443 dropReason = DROP_REASON_STALE;
444 }
445 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
446 dropReason = DROP_REASON_BLOCKED;
447 }
448 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
449 break;
450 }
451
452 case EventEntry::TYPE_MOTION: {
453 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
454 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
455 dropReason = DROP_REASON_APP_SWITCH;
456 }
457 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800458 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800459 dropReason = DROP_REASON_STALE;
460 }
461 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
462 dropReason = DROP_REASON_BLOCKED;
463 }
464 done = dispatchMotionLocked(currentTime, typedEntry,
465 &dropReason, nextWakeupTime);
466 break;
467 }
468
469 default:
470 ALOG_ASSERT(false);
471 break;
472 }
473
474 if (done) {
475 if (dropReason != DROP_REASON_NOT_DROPPED) {
476 dropInboundEventLocked(mPendingEvent, dropReason);
477 }
Michael Wright3a981722015-06-10 15:26:13 +0100478 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800479
480 releasePendingEventLocked();
481 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
482 }
483}
484
485bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
486 bool needWake = mInboundQueue.isEmpty();
487 mInboundQueue.enqueueAtTail(entry);
488 traceInboundQueueLengthLocked();
489
490 switch (entry->type) {
491 case EventEntry::TYPE_KEY: {
492 // Optimize app switch latency.
493 // If the application takes too long to catch up then we drop all events preceding
494 // the app switch key.
495 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800496 if (isAppSwitchKeyEvent(keyEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800497 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
498 mAppSwitchSawKeyDown = true;
499 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
500 if (mAppSwitchSawKeyDown) {
501#if DEBUG_APP_SWITCH
502 ALOGD("App switch is pending!");
503#endif
504 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
505 mAppSwitchSawKeyDown = false;
506 needWake = true;
507 }
508 }
509 }
510 break;
511 }
512
513 case EventEntry::TYPE_MOTION: {
514 // Optimize case where the current application is unresponsive and the user
515 // decides to touch a window in a different application.
516 // If the application takes too long to catch up then we drop all events preceding
517 // the touch into the other window.
518 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
519 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
520 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
521 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700522 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800523 int32_t displayId = motionEntry->displayId;
524 int32_t x = int32_t(motionEntry->pointerCoords[0].
525 getAxisValue(AMOTION_EVENT_AXIS_X));
526 int32_t y = int32_t(motionEntry->pointerCoords[0].
527 getAxisValue(AMOTION_EVENT_AXIS_Y));
528 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700529 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700530 && touchedWindowHandle->getApplicationToken()
531 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532 // User touched a different application than the one we are waiting on.
533 // Flag the event, and start pruning the input queue.
534 mNextUnblockedEvent = motionEntry;
535 needWake = true;
536 }
537 }
538 break;
539 }
540 }
541
542 return needWake;
543}
544
545void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
546 entry->refCount += 1;
547 mRecentQueue.enqueueAtTail(entry);
548 if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
549 mRecentQueue.dequeueAtHead()->release();
550 }
551}
552
553sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800554 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800555 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800556 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
557 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 const InputWindowInfo* windowInfo = windowHandle->getInfo();
559 if (windowInfo->displayId == displayId) {
560 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561
562 if (windowInfo->visible) {
563 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
564 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
565 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
566 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800567 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
568 if (portalToDisplayId != ADISPLAY_ID_NONE
569 && portalToDisplayId != displayId) {
570 if (addPortalWindows) {
571 // For the monitoring channels of the display.
572 mTempTouchState.addPortalWindow(windowHandle);
573 }
574 return findTouchedWindowAtLocked(
575 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800577 // Found window.
578 return windowHandle;
579 }
580 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800581
582 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
583 mTempTouchState.addOrUpdateWindow(
584 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800586 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800587 }
588 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700589 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590}
591
Michael Wright3dd60e22019-03-27 22:06:44 +0000592std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
593 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
594 std::vector<TouchedMonitor> touchedMonitors;
595
596 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
597 addGestureMonitors(monitors, touchedMonitors);
598 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
599 const InputWindowInfo* windowInfo = portalWindow->getInfo();
600 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
601 addGestureMonitors(monitors, touchedMonitors,
602 -windowInfo->frameLeft, -windowInfo->frameTop);
603 }
604 return touchedMonitors;
605}
606
607void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
608 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset, float yOffset) {
609 if (monitors.empty()) {
610 return;
611 }
612 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
613 for (const Monitor& monitor : monitors) {
614 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
615 }
616}
617
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
619 const char* reason;
620 switch (dropReason) {
621 case DROP_REASON_POLICY:
622#if DEBUG_INBOUND_EVENT_DETAILS
623 ALOGD("Dropped event because policy consumed it.");
624#endif
625 reason = "inbound event was dropped because the policy consumed it";
626 break;
627 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100628 if (mLastDropReason != DROP_REASON_DISABLED) {
629 ALOGI("Dropped event because input dispatch is disabled.");
630 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631 reason = "inbound event was dropped because input dispatch is disabled";
632 break;
633 case DROP_REASON_APP_SWITCH:
634 ALOGI("Dropped event because of pending overdue app switch.");
635 reason = "inbound event was dropped because of pending overdue app switch";
636 break;
637 case DROP_REASON_BLOCKED:
638 ALOGI("Dropped event because the current application is not responding and the user "
639 "has started interacting with a different application.");
640 reason = "inbound event was dropped because the current application is not responding "
641 "and the user has started interacting with a different application";
642 break;
643 case DROP_REASON_STALE:
644 ALOGI("Dropped event because it is stale.");
645 reason = "inbound event was dropped because it is stale";
646 break;
647 default:
648 ALOG_ASSERT(false);
649 return;
650 }
651
652 switch (entry->type) {
653 case EventEntry::TYPE_KEY: {
654 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
655 synthesizeCancelationEventsForAllConnectionsLocked(options);
656 break;
657 }
658 case EventEntry::TYPE_MOTION: {
659 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
660 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
661 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
662 synthesizeCancelationEventsForAllConnectionsLocked(options);
663 } else {
664 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
665 synthesizeCancelationEventsForAllConnectionsLocked(options);
666 }
667 break;
668 }
669 }
670}
671
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800672static bool isAppSwitchKeyCode(int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800673 return keyCode == AKEYCODE_HOME
674 || keyCode == AKEYCODE_ENDCALL
675 || keyCode == AKEYCODE_APP_SWITCH;
676}
677
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800678bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800679 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
680 && isAppSwitchKeyCode(keyEntry->keyCode)
681 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
682 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
683}
684
685bool InputDispatcher::isAppSwitchPendingLocked() {
686 return mAppSwitchDueTime != LONG_LONG_MAX;
687}
688
689void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
690 mAppSwitchDueTime = LONG_LONG_MAX;
691
692#if DEBUG_APP_SWITCH
693 if (handled) {
694 ALOGD("App switch has arrived.");
695 } else {
696 ALOGD("App switch was abandoned.");
697 }
698#endif
699}
700
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800701bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800702 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
703}
704
705bool InputDispatcher::haveCommandsLocked() const {
706 return !mCommandQueue.isEmpty();
707}
708
709bool InputDispatcher::runCommandsLockedInterruptible() {
710 if (mCommandQueue.isEmpty()) {
711 return false;
712 }
713
714 do {
715 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
716
717 Command command = commandEntry->command;
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700718 command(*this, commandEntry); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719
720 commandEntry->connection.clear();
721 delete commandEntry;
722 } while (! mCommandQueue.isEmpty());
723 return true;
724}
725
726InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
727 CommandEntry* commandEntry = new CommandEntry(command);
728 mCommandQueue.enqueueAtTail(commandEntry);
729 return commandEntry;
730}
731
732void InputDispatcher::drainInboundQueueLocked() {
733 while (! mInboundQueue.isEmpty()) {
734 EventEntry* entry = mInboundQueue.dequeueAtHead();
735 releaseInboundEventLocked(entry);
736 }
737 traceInboundQueueLengthLocked();
738}
739
740void InputDispatcher::releasePendingEventLocked() {
741 if (mPendingEvent) {
742 resetANRTimeoutsLocked();
743 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700744 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800745 }
746}
747
748void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
749 InjectionState* injectionState = entry->injectionState;
750 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
751#if DEBUG_DISPATCH_CYCLE
752 ALOGD("Injected inbound event was dropped.");
753#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800754 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800755 }
756 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700757 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758 }
759 addRecentEventLocked(entry);
760 entry->release();
761}
762
763void InputDispatcher::resetKeyRepeatLocked() {
764 if (mKeyRepeatState.lastKeyEntry) {
765 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700766 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767 }
768}
769
770InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
771 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
772
773 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700774 uint32_t policyFlags = entry->policyFlags &
775 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776 if (entry->refCount == 1) {
777 entry->recycle();
778 entry->eventTime = currentTime;
779 entry->policyFlags = policyFlags;
780 entry->repeatCount += 1;
781 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800782 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100783 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800784 entry->action, entry->flags, entry->keyCode, entry->scanCode,
785 entry->metaState, entry->repeatCount + 1, entry->downTime);
786
787 mKeyRepeatState.lastKeyEntry = newEntry;
788 entry->release();
789
790 entry = newEntry;
791 }
792 entry->syntheticRepeat = true;
793
794 // Increment reference count since we keep a reference to the event in
795 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
796 entry->refCount += 1;
797
798 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
799 return entry;
800}
801
802bool InputDispatcher::dispatchConfigurationChangedLocked(
803 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
804#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700805 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806#endif
807
808 // Reset key repeating in case a keyboard device was added or removed or something.
809 resetKeyRepeatLocked();
810
811 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700812 CommandEntry* commandEntry =
813 postCommandLocked(&InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800814 commandEntry->eventTime = entry->eventTime;
815 return true;
816}
817
818bool InputDispatcher::dispatchDeviceResetLocked(
819 nsecs_t currentTime, DeviceResetEntry* entry) {
820#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700821 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
822 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800823#endif
824
825 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
826 "device was reset");
827 options.deviceId = entry->deviceId;
828 synthesizeCancelationEventsForAllConnectionsLocked(options);
829 return true;
830}
831
832bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
833 DropReason* dropReason, nsecs_t* nextWakeupTime) {
834 // Preprocessing.
835 if (! entry->dispatchInProgress) {
836 if (entry->repeatCount == 0
837 && entry->action == AKEY_EVENT_ACTION_DOWN
838 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
839 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
840 if (mKeyRepeatState.lastKeyEntry
841 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
842 // We have seen two identical key downs in a row which indicates that the device
843 // driver is automatically generating key repeats itself. We take note of the
844 // repeat here, but we disable our own next key repeat timer since it is clear that
845 // we will not need to synthesize key repeats ourselves.
846 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
847 resetKeyRepeatLocked();
848 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
849 } else {
850 // Not a repeat. Save key down state in case we do see a repeat later.
851 resetKeyRepeatLocked();
852 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
853 }
854 mKeyRepeatState.lastKeyEntry = entry;
855 entry->refCount += 1;
856 } else if (! entry->syntheticRepeat) {
857 resetKeyRepeatLocked();
858 }
859
860 if (entry->repeatCount == 1) {
861 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
862 } else {
863 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
864 }
865
866 entry->dispatchInProgress = true;
867
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800868 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
870
871 // Handle case where the policy asked us to try again later last time.
872 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
873 if (currentTime < entry->interceptKeyWakeupTime) {
874 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
875 *nextWakeupTime = entry->interceptKeyWakeupTime;
876 }
877 return false; // wait until next wakeup
878 }
879 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
880 entry->interceptKeyWakeupTime = 0;
881 }
882
883 // Give the policy a chance to intercept the key.
884 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
885 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
886 CommandEntry* commandEntry = postCommandLocked(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700887 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800888 sp<InputWindowHandle> focusedWindowHandle =
889 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
890 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700891 commandEntry->inputChannel =
892 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800893 }
894 commandEntry->keyEntry = entry;
895 entry->refCount += 1;
896 return false; // wait for the command to run
897 } else {
898 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
899 }
900 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
901 if (*dropReason == DROP_REASON_NOT_DROPPED) {
902 *dropReason = DROP_REASON_POLICY;
903 }
904 }
905
906 // Clean up if dropping the event.
907 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800908 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800910 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 return true;
912 }
913
914 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800915 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
917 entry, inputTargets, nextWakeupTime);
918 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
919 return false;
920 }
921
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800922 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800923 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
924 return true;
925 }
926
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800927 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000928 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929
930 // Dispatch the key.
931 dispatchEventLocked(currentTime, entry, inputTargets);
932 return true;
933}
934
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800935void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100937 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
938 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800939 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800940 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100941 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800943 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800944#endif
945}
946
947bool InputDispatcher::dispatchMotionLocked(
948 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000949 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800950 // Preprocessing.
951 if (! entry->dispatchInProgress) {
952 entry->dispatchInProgress = true;
953
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800954 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800955 }
956
957 // Clean up if dropping the event.
958 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800959 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
961 return true;
962 }
963
964 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
965
966 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800967 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800968
969 bool conflictingPointerActions = false;
970 int32_t injectionResult;
971 if (isPointerEvent) {
972 // Pointer event. (eg. touchscreen)
973 injectionResult = findTouchedWindowTargetsLocked(currentTime,
974 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
975 } else {
976 // Non touch event. (eg. trackball)
977 injectionResult = findFocusedWindowTargetsLocked(currentTime,
978 entry, inputTargets, nextWakeupTime);
979 }
980 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
981 return false;
982 }
983
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800984 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100986 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
987 CancelationOptions::Mode mode(isPointerEvent ?
988 CancelationOptions::CANCEL_POINTER_EVENTS :
989 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
990 CancelationOptions options(mode, "input event injection failed");
991 synthesizeCancelationEventsForMonitorsLocked(options);
992 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800993 return true;
994 }
995
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800996 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000997 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800998
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800999 if (isPointerEvent) {
1000 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1001 if (stateIndex >= 0) {
1002 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001003 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001004 // The event has gone through these portal windows, so we add monitoring targets of
1005 // the corresponding displays as well.
1006 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001007 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001008 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001009 -windowInfo->frameLeft, -windowInfo->frameTop);
1010 }
1011 }
1012 }
1013 }
1014
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015 // Dispatch the motion.
1016 if (conflictingPointerActions) {
1017 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
1018 "conflicting pointer actions");
1019 synthesizeCancelationEventsForAllConnectionsLocked(options);
1020 }
1021 dispatchEventLocked(currentTime, entry, inputTargets);
1022 return true;
1023}
1024
1025
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001026void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001028 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1029 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01001030 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1031 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08001032 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001033 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001034 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001035 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 entry->metaState, entry->buttonState,
1037 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +08001038 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039
1040 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1041 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1042 "x=%f, y=%f, pressure=%f, size=%f, "
1043 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001044 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -08001045 i, entry->pointerProperties[i].id,
1046 entry->pointerProperties[i].toolType,
1047 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1048 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1049 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1050 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1051 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1052 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1053 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1054 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001055 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056 }
1057#endif
1058}
1059
1060void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001061 EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001062 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063#if DEBUG_DISPATCH_CYCLE
1064 ALOGD("dispatchEventToCurrentInputTargets");
1065#endif
1066
1067 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1068
1069 pokeUserActivityLocked(eventEntry);
1070
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001071 for (const InputTarget& inputTarget : inputTargets) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001072 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1073 if (connectionIndex >= 0) {
1074 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1075 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1076 } else {
1077#if DEBUG_FOCUS
1078 ALOGD("Dropping event delivery to target with channel '%s' because it "
1079 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001080 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001081#endif
1082 }
1083 }
1084}
1085
1086int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1087 const EventEntry* entry,
1088 const sp<InputApplicationHandle>& applicationHandle,
1089 const sp<InputWindowHandle>& windowHandle,
1090 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001091 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1093#if DEBUG_FOCUS
1094 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1095#endif
1096 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1097 mInputTargetWaitStartTime = currentTime;
1098 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1099 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001100 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101 }
1102 } else {
1103 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1104#if DEBUG_FOCUS
1105 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001106 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 reason);
1108#endif
1109 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001110 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001112 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 timeout = applicationHandle->getDispatchingTimeout(
1114 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1115 } else {
1116 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1117 }
1118
1119 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1120 mInputTargetWaitStartTime = currentTime;
1121 mInputTargetWaitTimeoutTime = currentTime + timeout;
1122 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001123 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124
Yi Kong9b14ac62018-07-17 13:48:38 -07001125 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001126 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127 }
Robert Carr740167f2018-10-11 19:03:41 -07001128 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1129 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 }
1131 }
1132 }
1133
1134 if (mInputTargetWaitTimeoutExpired) {
1135 return INPUT_EVENT_INJECTION_TIMED_OUT;
1136 }
1137
1138 if (currentTime >= mInputTargetWaitTimeoutTime) {
1139 onANRLocked(currentTime, applicationHandle, windowHandle,
1140 entry->eventTime, mInputTargetWaitStartTime, reason);
1141
1142 // Force poll loop to wake up immediately on next iteration once we get the
1143 // ANR response back from the policy.
1144 *nextWakeupTime = LONG_LONG_MIN;
1145 return INPUT_EVENT_INJECTION_PENDING;
1146 } else {
1147 // Force poll loop to wake up when timeout is due.
1148 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1149 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1150 }
1151 return INPUT_EVENT_INJECTION_PENDING;
1152 }
1153}
1154
Robert Carr803535b2018-08-02 16:38:15 -07001155void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1156 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1157 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1158 state.removeWindowByToken(token);
1159 }
1160}
1161
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1163 const sp<InputChannel>& inputChannel) {
1164 if (newTimeout > 0) {
1165 // Extend the timeout.
1166 mInputTargetWaitTimeoutTime = now() + newTimeout;
1167 } else {
1168 // Give up.
1169 mInputTargetWaitTimeoutExpired = true;
1170
1171 // Input state will not be realistic. Mark it out of sync.
1172 if (inputChannel.get()) {
1173 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1174 if (connectionIndex >= 0) {
1175 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
Robert Carr803535b2018-08-02 16:38:15 -07001176 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177
Robert Carr803535b2018-08-02 16:38:15 -07001178 if (token != nullptr) {
1179 removeWindowByTokenLocked(token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180 }
1181
1182 if (connection->status == Connection::STATUS_NORMAL) {
1183 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1184 "application not responding");
1185 synthesizeCancelationEventsForConnectionLocked(connection, options);
1186 }
1187 }
1188 }
1189 }
1190}
1191
1192nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1193 nsecs_t currentTime) {
1194 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1195 return currentTime - mInputTargetWaitStartTime;
1196 }
1197 return 0;
1198}
1199
1200void InputDispatcher::resetANRTimeoutsLocked() {
1201#if DEBUG_FOCUS
1202 ALOGD("Resetting ANR timeouts.");
1203#endif
1204
1205 // Reset input target wait timeout.
1206 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001207 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208}
1209
Tiger Huang721e26f2018-07-24 22:26:19 +08001210/**
1211 * Get the display id that the given event should go to. If this event specifies a valid display id,
1212 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1213 * Focused display is the display that the user most recently interacted with.
1214 */
1215int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1216 int32_t displayId;
1217 switch (entry->type) {
1218 case EventEntry::TYPE_KEY: {
1219 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1220 displayId = typedEntry->displayId;
1221 break;
1222 }
1223 case EventEntry::TYPE_MOTION: {
1224 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1225 displayId = typedEntry->displayId;
1226 break;
1227 }
1228 default: {
1229 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1230 return ADISPLAY_ID_NONE;
1231 }
1232 }
1233 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1234}
1235
Michael Wrightd02c5b62014-02-10 15:10:22 -08001236int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001237 const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001239 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240
Tiger Huang721e26f2018-07-24 22:26:19 +08001241 int32_t displayId = getTargetDisplayId(entry);
1242 sp<InputWindowHandle> focusedWindowHandle =
1243 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1244 sp<InputApplicationHandle> focusedApplicationHandle =
1245 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1246
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247 // If there is no currently focused window and no focused application
1248 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001249 if (focusedWindowHandle == nullptr) {
1250 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001252 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 "Waiting because no window has focus but there is a "
1254 "focused application that may eventually add a window "
1255 "when it finishes starting up.");
1256 goto Unresponsive;
1257 }
1258
Arthur Hung3b413f22018-10-26 18:05:34 +08001259 ALOGI("Dropping event because there is no focused window or focused application in display "
1260 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1262 goto Failed;
1263 }
1264
1265 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001266 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001267 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1268 goto Failed;
1269 }
1270
Jeff Brownffb49772014-10-10 19:01:34 -07001271 // Check whether the window is ready for more input.
1272 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001273 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001274 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001275 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001276 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001277 goto Unresponsive;
1278 }
1279
1280 // Success! Output targets.
1281 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001282 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1284 inputTargets);
1285
1286 // Done.
1287Failed:
1288Unresponsive:
1289 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001290 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291#if DEBUG_FOCUS
1292 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1293 "timeSpentWaitingForApplication=%0.1fms",
1294 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1295#endif
1296 return injectionResult;
1297}
1298
1299int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001300 const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001301 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001302 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 enum InjectionPermission {
1304 INJECTION_PERMISSION_UNKNOWN,
1305 INJECTION_PERMISSION_GRANTED,
1306 INJECTION_PERMISSION_DENIED
1307 };
1308
Michael Wrightd02c5b62014-02-10 15:10:22 -08001309 // For security reasons, we defer updating the touch state until we are sure that
1310 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311 int32_t displayId = entry->displayId;
1312 int32_t action = entry->action;
1313 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1314
1315 // Update the touch state as needed based on the properties of the touch event.
1316 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1317 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1318 sp<InputWindowHandle> newHoverWindowHandle;
1319
Jeff Brownf086ddb2014-02-11 14:28:48 -08001320 // Copy current touch state into mTempTouchState.
1321 // This state is always reset at the end of this function, so if we don't find state
1322 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001323 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001324 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1325 if (oldStateIndex >= 0) {
1326 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1327 mTempTouchState.copyFrom(*oldState);
1328 }
1329
1330 bool isSplit = mTempTouchState.split;
1331 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1332 && (mTempTouchState.deviceId != entry->deviceId
1333 || mTempTouchState.source != entry->source
1334 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001335 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1336 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1337 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1338 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1339 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1340 || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001341 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001342 bool wrongDevice = false;
1343 if (newGesture) {
1344 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001345 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001346#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001347 ALOGD("Dropping event because a pointer for a different device is already down "
1348 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001350 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1352 switchedDevice = false;
1353 wrongDevice = true;
1354 goto Failed;
1355 }
1356 mTempTouchState.reset();
1357 mTempTouchState.down = down;
1358 mTempTouchState.deviceId = entry->deviceId;
1359 mTempTouchState.source = entry->source;
1360 mTempTouchState.displayId = displayId;
1361 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001362 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1363#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001364 ALOGI("Dropping move event because a pointer for a different device is already active "
1365 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001366#endif
1367 // TODO: test multiple simultaneous input streams.
1368 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1369 switchedDevice = false;
1370 wrongDevice = true;
1371 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001372 }
1373
1374 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1375 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1376
Garfield Tan00f511d2019-06-12 16:55:40 -07001377 int32_t x;
1378 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001379 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001380 // Always dispatch mouse events to cursor position.
1381 if (isFromMouse) {
1382 x = int32_t(entry->xCursorPosition);
1383 y = int32_t(entry->yCursorPosition);
1384 } else {
1385 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1386 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1387 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001388 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001389 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +00001390 displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
1391
1392 std::vector<TouchedMonitor> newGestureMonitors = isDown
1393 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1394 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395
Michael Wrightd02c5b62014-02-10 15:10:22 -08001396 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001397 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001399 // New window supports splitting, but we should never split mouse events.
1400 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 } else if (isSplit) {
1402 // New window does not support splitting but we have already split events.
1403 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001404 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 }
1406
1407 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001408 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001409 // Try to assign the pointer to the first foreground window we find, if there is one.
1410 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001411 }
1412
1413 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1414 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
1415 "(%d, %d) in display %" PRId32 ".", x, y, displayId);
1416 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1417 goto Failed;
1418 }
1419
1420 if (newTouchedWindowHandle != nullptr) {
1421 // Set target flags.
1422 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1423 if (isSplit) {
1424 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001425 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001426 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1427 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1428 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1429 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1430 }
1431
1432 // Update hover state.
1433 if (isHoverAction) {
1434 newHoverWindowHandle = newTouchedWindowHandle;
1435 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1436 newHoverWindowHandle = mLastHoverWindowHandle;
1437 }
1438
1439 // Update the temporary touch state.
1440 BitSet32 pointerIds;
1441 if (isSplit) {
1442 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1443 pointerIds.markBit(pointerId);
1444 }
1445 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001446 }
1447
Michael Wright3dd60e22019-03-27 22:06:44 +00001448 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449 } else {
1450 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1451
1452 // If the pointer is not currently down, then ignore the event.
1453 if (! mTempTouchState.down) {
1454#if DEBUG_FOCUS
1455 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001456 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457#endif
1458 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1459 goto Failed;
1460 }
1461
1462 // Check whether touches should slip outside of the current foreground window.
1463 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1464 && entry->pointerCount == 1
1465 && mTempTouchState.isSlippery()) {
1466 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1467 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1468
1469 sp<InputWindowHandle> oldTouchedWindowHandle =
1470 mTempTouchState.getFirstForegroundWindowHandle();
1471 sp<InputWindowHandle> newTouchedWindowHandle =
1472 findTouchedWindowAtLocked(displayId, x, y);
1473 if (oldTouchedWindowHandle != newTouchedWindowHandle
Michael Wright3dd60e22019-03-27 22:06:44 +00001474 && oldTouchedWindowHandle != nullptr
Yi Kong9b14ac62018-07-17 13:48:38 -07001475 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001477 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001478 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001479 newTouchedWindowHandle->getName().c_str(),
1480 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001481#endif
1482 // Make a slippery exit from the old window.
1483 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1484 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1485
1486 // Make a slippery entrance into the new window.
1487 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1488 isSplit = true;
1489 }
1490
1491 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1492 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1493 if (isSplit) {
1494 targetFlags |= InputTarget::FLAG_SPLIT;
1495 }
1496 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1497 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1498 }
1499
1500 BitSet32 pointerIds;
1501 if (isSplit) {
1502 pointerIds.markBit(entry->pointerProperties[0].id);
1503 }
1504 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1505 }
1506 }
1507 }
1508
1509 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1510 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001511 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001512#if DEBUG_HOVER
1513 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001514 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001515#endif
1516 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1517 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1518 }
1519
1520 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001521 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001522#if DEBUG_HOVER
1523 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001524 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525#endif
1526 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1527 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1528 }
1529 }
1530
1531 // Check permission to inject into all touched foreground windows and ensure there
1532 // is at least one touched foreground window.
1533 {
1534 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001535 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1537 haveForegroundWindow = true;
1538 if (! checkInjectionPermission(touchedWindow.windowHandle,
1539 entry->injectionState)) {
1540 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1541 injectionPermission = INJECTION_PERMISSION_DENIED;
1542 goto Failed;
1543 }
1544 }
1545 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001546 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1547 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001548#if DEBUG_FOCUS
Michael Wright3dd60e22019-03-27 22:06:44 +00001549 ALOGD("Dropping event because there is no touched foreground window in display %"
1550 PRId32 " or gesture monitor to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001551#endif
1552 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1553 goto Failed;
1554 }
1555
1556 // Permission granted to injection into all touched foreground windows.
1557 injectionPermission = INJECTION_PERMISSION_GRANTED;
1558 }
1559
1560 // Check whether windows listening for outside touches are owned by the same UID. If it is
1561 // set the policy flag that we will not reveal coordinate information to this window.
1562 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1563 sp<InputWindowHandle> foregroundWindowHandle =
1564 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001565 if (foregroundWindowHandle) {
1566 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1567 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1568 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1569 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1570 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1571 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1572 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1573 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001574 }
1575 }
1576 }
1577 }
1578
1579 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001580 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001581 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001582 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001583 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001584 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001585 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001586 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001587 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001588 goto Unresponsive;
1589 }
1590 }
1591 }
1592
1593 // If this is the first pointer going down and the touched window has a wallpaper
1594 // then also add the touched wallpaper windows so they are locked in for the duration
1595 // of the touch gesture.
1596 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1597 // engine only supports touch events. We would need to add a mechanism similar
1598 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1599 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1600 sp<InputWindowHandle> foregroundWindowHandle =
1601 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001602 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001603 const std::vector<sp<InputWindowHandle>> windowHandles =
1604 getWindowHandlesLocked(displayId);
1605 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 const InputWindowInfo* info = windowHandle->getInfo();
1607 if (info->displayId == displayId
1608 && windowHandle->getInfo()->layoutParamsType
1609 == InputWindowInfo::TYPE_WALLPAPER) {
1610 mTempTouchState.addOrUpdateWindow(windowHandle,
1611 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001612 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 | InputTarget::FLAG_DISPATCH_AS_IS,
1614 BitSet32(0));
1615 }
1616 }
1617 }
1618 }
1619
1620 // Success! Output targets.
1621 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1622
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001623 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1625 touchedWindow.pointerIds, inputTargets);
1626 }
1627
Michael Wright3dd60e22019-03-27 22:06:44 +00001628 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1629 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
1630 touchedMonitor.yOffset, inputTargets);
1631 }
1632
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633 // Drop the outside or hover touch windows since we will not care about them
1634 // in the next iteration.
1635 mTempTouchState.filterNonAsIsTouchWindows();
1636
1637Failed:
1638 // Check injection permission once and for all.
1639 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001640 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641 injectionPermission = INJECTION_PERMISSION_GRANTED;
1642 } else {
1643 injectionPermission = INJECTION_PERMISSION_DENIED;
1644 }
1645 }
1646
1647 // Update final pieces of touch state if the injector had permission.
1648 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1649 if (!wrongDevice) {
1650 if (switchedDevice) {
1651#if DEBUG_FOCUS
1652 ALOGD("Conflicting pointer actions: Switched to a different device.");
1653#endif
1654 *outConflictingPointerActions = true;
1655 }
1656
1657 if (isHoverAction) {
1658 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001659 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001660#if DEBUG_FOCUS
1661 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1662#endif
1663 *outConflictingPointerActions = true;
1664 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001665 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1667 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001668 mTempTouchState.deviceId = entry->deviceId;
1669 mTempTouchState.source = entry->source;
1670 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001671 }
1672 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1673 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1674 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001675 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001676 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1677 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001678 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679#if DEBUG_FOCUS
1680 ALOGD("Conflicting pointer actions: Down received while already down.");
1681#endif
1682 *outConflictingPointerActions = true;
1683 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001684 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1685 // One pointer went up.
1686 if (isSplit) {
1687 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1688 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1689
1690 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001691 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001692 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1693 touchedWindow.pointerIds.clearBit(pointerId);
1694 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001695 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 continue;
1697 }
1698 }
1699 i += 1;
1700 }
1701 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001702 }
1703
1704 // Save changes unless the action was scroll in which case the temporary touch
1705 // state was only valid for this one action.
1706 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1707 if (mTempTouchState.displayId >= 0) {
1708 if (oldStateIndex >= 0) {
1709 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1710 } else {
1711 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1712 }
1713 } else if (oldStateIndex >= 0) {
1714 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001716 }
1717
1718 // Update hover state.
1719 mLastHoverWindowHandle = newHoverWindowHandle;
1720 }
1721 } else {
1722#if DEBUG_FOCUS
1723 ALOGD("Not updating touch focus because injection was denied.");
1724#endif
1725 }
1726
1727Unresponsive:
1728 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1729 mTempTouchState.reset();
1730
1731 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001732 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733#if DEBUG_FOCUS
1734 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1735 "timeSpentWaitingForApplication=%0.1fms",
1736 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1737#endif
1738 return injectionResult;
1739}
1740
1741void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001742 int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001743 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1744 if (inputChannel == nullptr) {
1745 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1746 return;
1747 }
1748
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001750 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001751 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 target.flags = targetFlags;
1753 target.xOffset = - windowInfo->frameLeft;
1754 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001755 target.globalScaleFactor = windowInfo->globalScaleFactor;
1756 target.windowXScale = windowInfo->windowXScale;
1757 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001759 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001760}
1761
Michael Wright3dd60e22019-03-27 22:06:44 +00001762void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
1763 int32_t displayId, float xOffset, float yOffset) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001764
Michael Wright3dd60e22019-03-27 22:06:44 +00001765 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1766 mGlobalMonitorsByDisplay.find(displayId);
1767
1768 if (it != mGlobalMonitorsByDisplay.end()) {
1769 const std::vector<Monitor>& monitors = it->second;
1770 for (const Monitor& monitor : monitors) {
1771 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001772 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001773 }
1774}
1775
Michael Wright3dd60e22019-03-27 22:06:44 +00001776void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor,
1777 float xOffset, float yOffset, std::vector<InputTarget>& inputTargets) {
1778 InputTarget target;
1779 target.inputChannel = monitor.inputChannel;
1780 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1781 target.xOffset = xOffset;
1782 target.yOffset = yOffset;
1783 target.pointerIds.clear();
1784 target.globalScaleFactor = 1.0f;
1785 inputTargets.push_back(target);
1786}
1787
Michael Wrightd02c5b62014-02-10 15:10:22 -08001788bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1789 const InjectionState* injectionState) {
1790 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001791 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001792 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1793 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001794 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1796 "owned by uid %d",
1797 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001798 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001799 windowHandle->getInfo()->ownerUid);
1800 } else {
1801 ALOGW("Permission denied: injecting event from pid %d uid %d",
1802 injectionState->injectorPid, injectionState->injectorUid);
1803 }
1804 return false;
1805 }
1806 return true;
1807}
1808
1809bool InputDispatcher::isWindowObscuredAtPointLocked(
1810 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1811 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001812 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1813 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001814 if (otherHandle == windowHandle) {
1815 break;
1816 }
1817
1818 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1819 if (otherInfo->displayId == displayId
1820 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1821 && otherInfo->frameContainsPoint(x, y)) {
1822 return true;
1823 }
1824 }
1825 return false;
1826}
1827
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001828
1829bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1830 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001831 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001832 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001833 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001834 if (otherHandle == windowHandle) {
1835 break;
1836 }
1837
1838 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1839 if (otherInfo->displayId == displayId
1840 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1841 && otherInfo->overlaps(windowInfo)) {
1842 return true;
1843 }
1844 }
1845 return false;
1846}
1847
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001848std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001849 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1850 const char* targetType) {
1851 // If the window is paused then keep waiting.
1852 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001853 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001854 }
1855
1856 // If the window's connection is not registered then keep waiting.
Robert Carr5c8a0262018-10-03 16:30:44 -07001857 ssize_t connectionIndex = getConnectionIndexLocked(
1858 getInputChannelLocked(windowHandle->getToken()));
Jeff Brownffb49772014-10-10 19:01:34 -07001859 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001860 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001861 "registered with the input dispatcher. The window may be in the process "
1862 "of being removed.", targetType);
1863 }
1864
1865 // If the connection is dead then keep waiting.
1866 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1867 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001868 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001869 "The window may be in the process of being removed.", targetType,
1870 connection->getStatusLabel());
1871 }
1872
1873 // If the connection is backed up then keep waiting.
1874 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001875 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001876 "Outbound queue length: %zu. Wait queue length: %zu.",
1877 targetType, connection->outboundQueue.size(),
1878 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07001879 }
1880
1881 // Ensure that the dispatch queues aren't too far backed up for this event.
1882 if (eventEntry->type == EventEntry::TYPE_KEY) {
1883 // If the event is a key event, then we must wait for all previous events to
1884 // complete before delivering it because previous events may have the
1885 // side-effect of transferring focus to a different window and we want to
1886 // ensure that the following keys are sent to the new window.
1887 //
1888 // Suppose the user touches a button in a window then immediately presses "A".
1889 // If the button causes a pop-up window to appear then we want to ensure that
1890 // the "A" key is delivered to the new pop-up window. This is because users
1891 // often anticipate pending UI changes when typing on a keyboard.
1892 // To obtain this behavior, we must serialize key events with respect to all
1893 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001894 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001895 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001896 "finished processing all of the input events that were previously "
1897 "delivered to it. Outbound queue length: %zu. Wait queue length: "
1898 "%zu.",
1899 targetType, connection->outboundQueue.size(),
1900 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001901 }
Jeff Brownffb49772014-10-10 19:01:34 -07001902 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001903 // Touch events can always be sent to a window immediately because the user intended
1904 // to touch whatever was visible at the time. Even if focus changes or a new
1905 // window appears moments later, the touch event was meant to be delivered to
1906 // whatever window happened to be on screen at the time.
1907 //
1908 // Generic motion events, such as trackball or joystick events are a little trickier.
1909 // Like key events, generic motion events are delivered to the focused window.
1910 // Unlike key events, generic motion events don't tend to transfer focus to other
1911 // windows and it is not important for them to be serialized. So we prefer to deliver
1912 // generic motion events as soon as possible to improve efficiency and reduce lag
1913 // through batching.
1914 //
1915 // The one case where we pause input event delivery is when the wait queue is piling
1916 // up with lots of events because the application is not responding.
1917 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001918 if (!connection->waitQueue.empty() &&
1919 currentTime >=
1920 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001921 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001922 "finished processing certain input events that were delivered to "
1923 "it over "
1924 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
1925 "%0.1fms.",
1926 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1927 connection->waitQueue.size(),
1928 (currentTime - connection->waitQueue.front()->deliveryTime) *
1929 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001930 }
1931 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001932 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933}
1934
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001935std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001936 const sp<InputApplicationHandle>& applicationHandle,
1937 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001938 if (applicationHandle != nullptr) {
1939 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001940 std::string label(applicationHandle->getName());
1941 label += " - ";
1942 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943 return label;
1944 } else {
1945 return applicationHandle->getName();
1946 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001947 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001948 return windowHandle->getName();
1949 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001950 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001951 }
1952}
1953
1954void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001955 int32_t displayId = getTargetDisplayId(eventEntry);
1956 sp<InputWindowHandle> focusedWindowHandle =
1957 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1958 if (focusedWindowHandle != nullptr) {
1959 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001960 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1961#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001962 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001963#endif
1964 return;
1965 }
1966 }
1967
1968 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1969 switch (eventEntry->type) {
1970 case EventEntry::TYPE_MOTION: {
1971 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1972 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1973 return;
1974 }
1975
1976 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1977 eventType = USER_ACTIVITY_EVENT_TOUCH;
1978 }
1979 break;
1980 }
1981 case EventEntry::TYPE_KEY: {
1982 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1983 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1984 return;
1985 }
1986 eventType = USER_ACTIVITY_EVENT_BUTTON;
1987 break;
1988 }
1989 }
1990
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001991 CommandEntry* commandEntry =
1992 postCommandLocked(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001993 commandEntry->eventTime = eventEntry->eventTime;
1994 commandEntry->userActivityEventType = eventType;
1995}
1996
1997void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1998 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001999 if (ATRACE_ENABLED()) {
2000 std::string message = StringPrintf(
2001 "prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2002 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2003 ATRACE_NAME(message.c_str());
2004 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002005#if DEBUG_DISPATCH_CYCLE
2006 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08002007 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
2008 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002009 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002010 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002011 inputTarget->globalScaleFactor,
2012 inputTarget->windowXScale, inputTarget->windowYScale,
2013 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014#endif
2015
2016 // Skip this event if the connection status is not normal.
2017 // We don't want to enqueue additional outbound events if the connection is broken.
2018 if (connection->status != Connection::STATUS_NORMAL) {
2019#if DEBUG_DISPATCH_CYCLE
2020 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002021 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002022#endif
2023 return;
2024 }
2025
2026 // Split a motion event if needed.
2027 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2028 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2029
2030 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2031 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
2032 MotionEntry* splitMotionEntry = splitMotionEvent(
2033 originalMotionEntry, inputTarget->pointerIds);
2034 if (!splitMotionEntry) {
2035 return; // split event was dropped
2036 }
2037#if DEBUG_FOCUS
2038 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002039 connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002040 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002041#endif
2042 enqueueDispatchEntriesLocked(currentTime, connection,
2043 splitMotionEntry, inputTarget);
2044 splitMotionEntry->release();
2045 return;
2046 }
2047 }
2048
2049 // Not splitting. Enqueue dispatch entries for the event as is.
2050 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2051}
2052
2053void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
2054 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002055 if (ATRACE_ENABLED()) {
2056 std::string message = StringPrintf(
2057 "enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2058 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2059 ATRACE_NAME(message.c_str());
2060 }
2061
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002062 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063
2064 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002065 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002066 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002067 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002069 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002071 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002073 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002074 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002075 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2077
2078 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002079 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002080 startDispatchCycleLocked(currentTime, connection);
2081 }
2082}
2083
chaviw8c9cf542019-03-25 13:02:48 -07002084void InputDispatcher::enqueueDispatchEntryLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002085 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2086 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002087 if (ATRACE_ENABLED()) {
2088 std::string message = StringPrintf(
2089 "enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2090 connection->getInputChannelName().c_str(),
2091 dispatchModeToString(dispatchMode).c_str());
2092 ATRACE_NAME(message.c_str());
2093 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002094 int32_t inputTargetFlags = inputTarget->flags;
2095 if (!(inputTargetFlags & dispatchMode)) {
2096 return;
2097 }
2098 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2099
2100 // This is a new event.
2101 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2102 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2103 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002104 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2105 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002106
2107 // Apply target flags and update the connection's input state.
2108 switch (eventEntry->type) {
2109 case EventEntry::TYPE_KEY: {
2110 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2111 dispatchEntry->resolvedAction = keyEntry->action;
2112 dispatchEntry->resolvedFlags = keyEntry->flags;
2113
2114 if (!connection->inputState.trackKey(keyEntry,
2115 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2116#if DEBUG_DISPATCH_CYCLE
2117 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002118 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002119#endif
2120 delete dispatchEntry;
2121 return; // skip the inconsistent event
2122 }
2123 break;
2124 }
2125
2126 case EventEntry::TYPE_MOTION: {
2127 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2128 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2129 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2130 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2131 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2132 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2133 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2134 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2135 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2136 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2137 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2138 } else {
2139 dispatchEntry->resolvedAction = motionEntry->action;
2140 }
2141 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2142 && !connection->inputState.isHovering(
2143 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2144#if DEBUG_DISPATCH_CYCLE
2145 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002146 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147#endif
2148 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2149 }
2150
2151 dispatchEntry->resolvedFlags = motionEntry->flags;
2152 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2153 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2154 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002155 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2156 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2157 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158
2159 if (!connection->inputState.trackMotion(motionEntry,
2160 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2161#if DEBUG_DISPATCH_CYCLE
2162 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002163 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002164#endif
2165 delete dispatchEntry;
2166 return; // skip the inconsistent event
2167 }
chaviw8c9cf542019-03-25 13:02:48 -07002168
chaviwfd6d3512019-03-25 13:23:49 -07002169 dispatchPointerDownOutsideFocus(motionEntry->source,
chaviw8c9cf542019-03-25 13:02:48 -07002170 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
2171
Michael Wrightd02c5b62014-02-10 15:10:22 -08002172 break;
2173 }
2174 }
2175
2176 // Remember that we are waiting for this dispatch to complete.
2177 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002178 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002179 }
2180
2181 // Enqueue the dispatch entry.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002182 connection->outboundQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002183 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002184
2185}
2186
chaviwfd6d3512019-03-25 13:23:49 -07002187void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
chaviw8c9cf542019-03-25 13:02:48 -07002188 const sp<IBinder>& newToken) {
2189 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002190 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2191 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002192 return;
2193 }
2194
2195 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2196 if (inputWindowHandle == nullptr) {
2197 return;
2198 }
2199
chaviw8c9cf542019-03-25 13:02:48 -07002200 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002201 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002202
2203 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2204
2205 if (!hasFocusChanged) {
2206 return;
2207 }
2208
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07002209 CommandEntry* commandEntry =
2210 postCommandLocked(&InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002211 commandEntry->newToken = newToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002212}
2213
2214void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2215 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002216 if (ATRACE_ENABLED()) {
2217 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
2218 connection->getInputChannelName().c_str());
2219 ATRACE_NAME(message.c_str());
2220 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221#if DEBUG_DISPATCH_CYCLE
2222 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002223 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002224#endif
2225
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002226 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2227 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 dispatchEntry->deliveryTime = currentTime;
2229
2230 // Publish the event.
2231 status_t status;
2232 EventEntry* eventEntry = dispatchEntry->eventEntry;
2233 switch (eventEntry->type) {
2234 case EventEntry::TYPE_KEY: {
2235 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2236
2237 // Publish the key event.
2238 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002239 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2241 keyEntry->keyCode, keyEntry->scanCode,
2242 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2243 keyEntry->eventTime);
2244 break;
2245 }
2246
2247 case EventEntry::TYPE_MOTION: {
2248 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2249
2250 PointerCoords scaledCoords[MAX_POINTERS];
2251 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2252
2253 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002254 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002255 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2256 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002257 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2258 float wxs = dispatchEntry->windowXScale;
2259 float wys = dispatchEntry->windowYScale;
2260 xOffset = dispatchEntry->xOffset * wxs;
2261 yOffset = dispatchEntry->yOffset * wys;
2262 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002263 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002265 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 }
2267 usingCoords = scaledCoords;
2268 }
2269 } else {
2270 xOffset = 0.0f;
2271 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272
2273 // We don't want the dispatch target to know.
2274 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002275 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002276 scaledCoords[i].clear();
2277 }
2278 usingCoords = scaledCoords;
2279 }
2280 }
2281
2282 // Publish the motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002283 status =
2284 connection->inputPublisher
2285 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2286 motionEntry->source, motionEntry->displayId,
2287 dispatchEntry->resolvedAction,
2288 motionEntry->actionButton,
2289 dispatchEntry->resolvedFlags,
2290 motionEntry->edgeFlags, motionEntry->metaState,
2291 motionEntry->buttonState,
2292 motionEntry->classification, xOffset, yOffset,
2293 motionEntry->xPrecision, motionEntry->yPrecision,
2294 motionEntry->xCursorPosition,
2295 motionEntry->yCursorPosition, motionEntry->downTime,
2296 motionEntry->eventTime, motionEntry->pointerCount,
2297 motionEntry->pointerProperties, usingCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002298 break;
2299 }
2300
2301 default:
2302 ALOG_ASSERT(false);
2303 return;
2304 }
2305
2306 // Check the result.
2307 if (status) {
2308 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002309 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2311 "This is unexpected because the wait queue is empty, so the pipe "
2312 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002313 "event to it, status=%d", connection->getInputChannelName().c_str(),
2314 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2316 } else {
2317 // Pipe is full and we are waiting for the app to finish process some events
2318 // before sending more events to it.
2319#if DEBUG_DISPATCH_CYCLE
2320 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2321 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002322 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002323#endif
2324 connection->inputPublisherBlocked = true;
2325 }
2326 } else {
2327 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002328 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002329 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2330 }
2331 return;
2332 }
2333
2334 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002335 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2336 connection->outboundQueue.end(),
2337 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002338 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002339 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002340 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 }
2342}
2343
2344void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2345 const sp<Connection>& connection, uint32_t seq, bool handled) {
2346#if DEBUG_DISPATCH_CYCLE
2347 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002348 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002349#endif
2350
2351 connection->inputPublisherBlocked = false;
2352
2353 if (connection->status == Connection::STATUS_BROKEN
2354 || connection->status == Connection::STATUS_ZOMBIE) {
2355 return;
2356 }
2357
2358 // Notify other system components and prepare to start the next dispatch cycle.
2359 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2360}
2361
2362void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2363 const sp<Connection>& connection, bool notify) {
2364#if DEBUG_DISPATCH_CYCLE
2365 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002366 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002367#endif
2368
2369 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002370 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002371 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002372 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002373 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002374
2375 // The connection appears to be unrecoverably broken.
2376 // Ignore already broken or zombie connections.
2377 if (connection->status == Connection::STATUS_NORMAL) {
2378 connection->status = Connection::STATUS_BROKEN;
2379
2380 if (notify) {
2381 // Notify other system components.
2382 onDispatchCycleBrokenLocked(currentTime, connection);
2383 }
2384 }
2385}
2386
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002387void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2388 while (!queue.empty()) {
2389 DispatchEntry* dispatchEntry = queue.front();
2390 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002391 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002392 }
2393}
2394
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002395void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002396 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002397 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002398 }
2399 delete dispatchEntry;
2400}
2401
2402int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2403 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2404
2405 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002406 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002407
2408 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2409 if (connectionIndex < 0) {
2410 ALOGE("Received spurious receive callback for unknown input channel. "
2411 "fd=%d, events=0x%x", fd, events);
2412 return 0; // remove the callback
2413 }
2414
2415 bool notify;
2416 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2417 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2418 if (!(events & ALOOPER_EVENT_INPUT)) {
2419 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002420 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002421 return 1;
2422 }
2423
2424 nsecs_t currentTime = now();
2425 bool gotOne = false;
2426 status_t status;
2427 for (;;) {
2428 uint32_t seq;
2429 bool handled;
2430 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2431 if (status) {
2432 break;
2433 }
2434 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2435 gotOne = true;
2436 }
2437 if (gotOne) {
2438 d->runCommandsLockedInterruptible();
2439 if (status == WOULD_BLOCK) {
2440 return 1;
2441 }
2442 }
2443
2444 notify = status != DEAD_OBJECT || !connection->monitor;
2445 if (notify) {
2446 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002447 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002448 }
2449 } else {
2450 // Monitor channels are never explicitly unregistered.
2451 // We do it automatically when the remote endpoint is closed so don't warn
2452 // about them.
2453 notify = !connection->monitor;
2454 if (notify) {
2455 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002456 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457 }
2458 }
2459
2460 // Unregister the channel.
2461 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2462 return 0; // remove the callback
2463 } // release lock
2464}
2465
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002466void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
Michael Wrightd02c5b62014-02-10 15:10:22 -08002467 const CancelationOptions& options) {
2468 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2469 synthesizeCancelationEventsForConnectionLocked(
2470 mConnectionsByFd.valueAt(i), options);
2471 }
2472}
2473
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002474void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002475 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002476 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2477 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2478}
2479
2480void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2481 const CancelationOptions& options,
2482 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2483 for (const auto& it : monitorsByDisplay) {
2484 const std::vector<Monitor>& monitors = it.second;
2485 for (const Monitor& monitor : monitors) {
2486 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002487 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002488 }
2489}
2490
Michael Wrightd02c5b62014-02-10 15:10:22 -08002491void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2492 const sp<InputChannel>& channel, const CancelationOptions& options) {
2493 ssize_t index = getConnectionIndexLocked(channel);
2494 if (index >= 0) {
2495 synthesizeCancelationEventsForConnectionLocked(
2496 mConnectionsByFd.valueAt(index), options);
2497 }
2498}
2499
2500void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2501 const sp<Connection>& connection, const CancelationOptions& options) {
2502 if (connection->status == Connection::STATUS_BROKEN) {
2503 return;
2504 }
2505
2506 nsecs_t currentTime = now();
2507
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002508 std::vector<EventEntry*> cancelationEvents;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002509 connection->inputState.synthesizeCancelationEvents(currentTime,
2510 cancelationEvents, options);
2511
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002512 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002514 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002515 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002516 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002517 options.reason, options.mode);
2518#endif
2519 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002520 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002521 switch (cancelationEventEntry->type) {
2522 case EventEntry::TYPE_KEY:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002523 logOutboundKeyDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002524 static_cast<KeyEntry*>(cancelationEventEntry));
2525 break;
2526 case EventEntry::TYPE_MOTION:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002527 logOutboundMotionDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528 static_cast<MotionEntry*>(cancelationEventEntry));
2529 break;
2530 }
2531
2532 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002533 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2534 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002535 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002536 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2537 target.xOffset = -windowInfo->frameLeft;
2538 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002539 target.globalScaleFactor = windowInfo->globalScaleFactor;
2540 target.windowXScale = windowInfo->windowXScale;
2541 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002542 } else {
2543 target.xOffset = 0;
2544 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002545 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002546 }
2547 target.inputChannel = connection->inputChannel;
2548 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2549
chaviw8c9cf542019-03-25 13:02:48 -07002550 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Michael Wrightd02c5b62014-02-10 15:10:22 -08002551 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2552
2553 cancelationEventEntry->release();
2554 }
2555
2556 startDispatchCycleLocked(currentTime, connection);
2557 }
2558}
2559
2560InputDispatcher::MotionEntry*
2561InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2562 ALOG_ASSERT(pointerIds.value != 0);
2563
2564 uint32_t splitPointerIndexMap[MAX_POINTERS];
2565 PointerProperties splitPointerProperties[MAX_POINTERS];
2566 PointerCoords splitPointerCoords[MAX_POINTERS];
2567
2568 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2569 uint32_t splitPointerCount = 0;
2570
2571 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2572 originalPointerIndex++) {
2573 const PointerProperties& pointerProperties =
2574 originalMotionEntry->pointerProperties[originalPointerIndex];
2575 uint32_t pointerId = uint32_t(pointerProperties.id);
2576 if (pointerIds.hasBit(pointerId)) {
2577 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2578 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2579 splitPointerCoords[splitPointerCount].copyFrom(
2580 originalMotionEntry->pointerCoords[originalPointerIndex]);
2581 splitPointerCount += 1;
2582 }
2583 }
2584
2585 if (splitPointerCount != pointerIds.count()) {
2586 // This is bad. We are missing some of the pointers that we expected to deliver.
2587 // Most likely this indicates that we received an ACTION_MOVE events that has
2588 // different pointer ids than we expected based on the previous ACTION_DOWN
2589 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2590 // in this way.
2591 ALOGW("Dropping split motion event because the pointer count is %d but "
2592 "we expected there to be %d pointers. This probably means we received "
2593 "a broken sequence of pointer ids from the input device.",
2594 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002595 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596 }
2597
2598 int32_t action = originalMotionEntry->action;
2599 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2600 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2601 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2602 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2603 const PointerProperties& pointerProperties =
2604 originalMotionEntry->pointerProperties[originalPointerIndex];
2605 uint32_t pointerId = uint32_t(pointerProperties.id);
2606 if (pointerIds.hasBit(pointerId)) {
2607 if (pointerIds.count() == 1) {
2608 // The first/last pointer went down/up.
2609 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2610 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2611 } else {
2612 // A secondary pointer went down/up.
2613 uint32_t splitPointerIndex = 0;
2614 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2615 splitPointerIndex += 1;
2616 }
2617 action = maskedAction | (splitPointerIndex
2618 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2619 }
2620 } else {
2621 // An unrelated pointer changed.
2622 action = AMOTION_EVENT_ACTION_MOVE;
2623 }
2624 }
2625
Garfield Tan00f511d2019-06-12 16:55:40 -07002626 MotionEntry* splitMotionEntry =
2627 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2628 originalMotionEntry->deviceId, originalMotionEntry->source,
2629 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2630 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2631 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2632 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2633 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2634 originalMotionEntry->xCursorPosition,
2635 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2636 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002637
2638 if (originalMotionEntry->injectionState) {
2639 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2640 splitMotionEntry->injectionState->refCount += 1;
2641 }
2642
2643 return splitMotionEntry;
2644}
2645
2646void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2647#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002648 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002649#endif
2650
2651 bool needWake;
2652 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002653 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002654
Prabir Pradhan42611e02018-11-27 14:04:02 -08002655 ConfigurationChangedEntry* newEntry =
2656 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002657 needWake = enqueueInboundEventLocked(newEntry);
2658 } // release lock
2659
2660 if (needWake) {
2661 mLooper->wake();
2662 }
2663}
2664
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002665/**
2666 * If one of the meta shortcuts is detected, process them here:
2667 * Meta + Backspace -> generate BACK
2668 * Meta + Enter -> generate HOME
2669 * This will potentially overwrite keyCode and metaState.
2670 */
2671void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2672 int32_t& keyCode, int32_t& metaState) {
2673 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2674 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2675 if (keyCode == AKEYCODE_DEL) {
2676 newKeyCode = AKEYCODE_BACK;
2677 } else if (keyCode == AKEYCODE_ENTER) {
2678 newKeyCode = AKEYCODE_HOME;
2679 }
2680 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002681 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002682 struct KeyReplacement replacement = {keyCode, deviceId};
2683 mReplacedKeys.add(replacement, newKeyCode);
2684 keyCode = newKeyCode;
2685 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2686 }
2687 } else if (action == AKEY_EVENT_ACTION_UP) {
2688 // In order to maintain a consistent stream of up and down events, check to see if the key
2689 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2690 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002691 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002692 struct KeyReplacement replacement = {keyCode, deviceId};
2693 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2694 if (index >= 0) {
2695 keyCode = mReplacedKeys.valueAt(index);
2696 mReplacedKeys.removeItemsAt(index);
2697 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2698 }
2699 }
2700}
2701
Michael Wrightd02c5b62014-02-10 15:10:22 -08002702void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2703#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002704 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002705 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002706 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002707 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002708 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002709 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002710#endif
2711 if (!validateKeyEvent(args->action)) {
2712 return;
2713 }
2714
2715 uint32_t policyFlags = args->policyFlags;
2716 int32_t flags = args->flags;
2717 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002718 // InputDispatcher tracks and generates key repeats on behalf of
2719 // whatever notifies it, so repeatCount should always be set to 0
2720 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2722 policyFlags |= POLICY_FLAG_VIRTUAL;
2723 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002725 if (policyFlags & POLICY_FLAG_FUNCTION) {
2726 metaState |= AMETA_FUNCTION_ON;
2727 }
2728
2729 policyFlags |= POLICY_FLAG_TRUSTED;
2730
Michael Wright78f24442014-08-06 15:55:28 -07002731 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002732 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002733
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002735 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002736 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737 args->downTime, args->eventTime);
2738
Michael Wright2b3c3302018-03-02 17:19:13 +00002739 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002740 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002741 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2742 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2743 std::to_string(t.duration().count()).c_str());
2744 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002745
Michael Wrightd02c5b62014-02-10 15:10:22 -08002746 bool needWake;
2747 { // acquire lock
2748 mLock.lock();
2749
2750 if (shouldSendKeyToInputFilterLocked(args)) {
2751 mLock.unlock();
2752
2753 policyFlags |= POLICY_FLAG_FILTERED;
2754 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2755 return; // event was consumed by the filter
2756 }
2757
2758 mLock.lock();
2759 }
2760
Prabir Pradhan42611e02018-11-27 14:04:02 -08002761 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002762 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002763 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002764 metaState, repeatCount, args->downTime);
2765
2766 needWake = enqueueInboundEventLocked(newEntry);
2767 mLock.unlock();
2768 } // release lock
2769
2770 if (needWake) {
2771 mLooper->wake();
2772 }
2773}
2774
2775bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2776 return mInputFilterEnabled;
2777}
2778
2779void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2780#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002781 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002782 ", policyFlags=0x%x, "
2783 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2784 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002785 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002786 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2787 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2788 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2789 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002790 for (uint32_t i = 0; i < args->pointerCount; i++) {
2791 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2792 "x=%f, y=%f, pressure=%f, size=%f, "
2793 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2794 "orientation=%f",
2795 i, args->pointerProperties[i].id,
2796 args->pointerProperties[i].toolType,
2797 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2798 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2799 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2800 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2801 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2802 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2803 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2804 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2805 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2806 }
2807#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002808 if (!validateMotionEvent(args->action, args->actionButton,
2809 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 return;
2811 }
2812
2813 uint32_t policyFlags = args->policyFlags;
2814 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002815
2816 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002817 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002818 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2819 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2820 std::to_string(t.duration().count()).c_str());
2821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002822
2823 bool needWake;
2824 { // acquire lock
2825 mLock.lock();
2826
2827 if (shouldSendMotionToInputFilterLocked(args)) {
2828 mLock.unlock();
2829
2830 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002831 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2832 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2833 args->buttonState, args->classification, 0, 0, args->xPrecision,
2834 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2835 args->downTime, args->eventTime, args->pointerCount,
2836 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837
2838 policyFlags |= POLICY_FLAG_FILTERED;
2839 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2840 return; // event was consumed by the filter
2841 }
2842
2843 mLock.lock();
2844 }
2845
2846 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002847 MotionEntry* newEntry =
2848 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2849 args->displayId, policyFlags, args->action, args->actionButton,
2850 args->flags, args->metaState, args->buttonState,
2851 args->classification, args->edgeFlags, args->xPrecision,
2852 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2853 args->downTime, args->pointerCount, args->pointerProperties,
2854 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855
2856 needWake = enqueueInboundEventLocked(newEntry);
2857 mLock.unlock();
2858 } // release lock
2859
2860 if (needWake) {
2861 mLooper->wake();
2862 }
2863}
2864
2865bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002866 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002867}
2868
2869void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2870#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002871 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2872 "switchMask=0x%08x",
2873 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002874#endif
2875
2876 uint32_t policyFlags = args->policyFlags;
2877 policyFlags |= POLICY_FLAG_TRUSTED;
2878 mPolicy->notifySwitch(args->eventTime,
2879 args->switchValues, args->switchMask, policyFlags);
2880}
2881
2882void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2883#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002884 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002885 args->eventTime, args->deviceId);
2886#endif
2887
2888 bool needWake;
2889 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002890 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002891
Prabir Pradhan42611e02018-11-27 14:04:02 -08002892 DeviceResetEntry* newEntry =
2893 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002894 needWake = enqueueInboundEventLocked(newEntry);
2895 } // release lock
2896
2897 if (needWake) {
2898 mLooper->wake();
2899 }
2900}
2901
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002902int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002903 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2904 uint32_t policyFlags) {
2905#if DEBUG_INBOUND_EVENT_DETAILS
2906 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002907 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2908 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909#endif
2910
2911 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2912
2913 policyFlags |= POLICY_FLAG_INJECTED;
2914 if (hasInjectionPermission(injectorPid, injectorUid)) {
2915 policyFlags |= POLICY_FLAG_TRUSTED;
2916 }
2917
2918 EventEntry* firstInjectedEntry;
2919 EventEntry* lastInjectedEntry;
2920 switch (event->getType()) {
2921 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002922 KeyEvent keyEvent;
2923 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2924 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002925 if (! validateKeyEvent(action)) {
2926 return INPUT_EVENT_INJECTION_FAILED;
2927 }
2928
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002929 int32_t flags = keyEvent.getFlags();
2930 int32_t keyCode = keyEvent.getKeyCode();
2931 int32_t metaState = keyEvent.getMetaState();
2932 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2933 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002934 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002935 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002936 keyEvent.getDownTime(), keyEvent.getEventTime());
2937
Michael Wrightd02c5b62014-02-10 15:10:22 -08002938 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2939 policyFlags |= POLICY_FLAG_VIRTUAL;
2940 }
2941
2942 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002943 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002944 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002945 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2946 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2947 std::to_string(t.duration().count()).c_str());
2948 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002949 }
2950
Michael Wrightd02c5b62014-02-10 15:10:22 -08002951 mLock.lock();
Prabir Pradhan42611e02018-11-27 14:04:02 -08002952 firstInjectedEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002953 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002954 policyFlags, action, flags,
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002955 keyEvent.getKeyCode(), keyEvent.getScanCode(), keyEvent.getMetaState(),
2956 keyEvent.getRepeatCount(), keyEvent.getDownTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002957 lastInjectedEntry = firstInjectedEntry;
2958 break;
2959 }
2960
2961 case AINPUT_EVENT_TYPE_MOTION: {
2962 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963 int32_t action = motionEvent->getAction();
2964 size_t pointerCount = motionEvent->getPointerCount();
2965 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002966 int32_t actionButton = motionEvent->getActionButton();
Charles Chen3611f1f2019-01-29 17:26:18 +08002967 int32_t displayId = motionEvent->getDisplayId();
Michael Wright7b159c92015-05-14 14:48:03 +01002968 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002969 return INPUT_EVENT_INJECTION_FAILED;
2970 }
2971
2972 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2973 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002974 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002975 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002976 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2977 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2978 std::to_string(t.duration().count()).c_str());
2979 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002980 }
2981
2982 mLock.lock();
2983 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2984 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Garfield Tan00f511d2019-06-12 16:55:40 -07002985 firstInjectedEntry =
2986 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2987 motionEvent->getDeviceId(), motionEvent->getSource(),
2988 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2989 motionEvent->getFlags(), motionEvent->getMetaState(),
2990 motionEvent->getButtonState(), motionEvent->getClassification(),
2991 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2992 motionEvent->getYPrecision(), motionEvent->getRawXCursorPosition(),
2993 motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
2994 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2995 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002996 lastInjectedEntry = firstInjectedEntry;
2997 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2998 sampleEventTimes += 1;
2999 samplePointerCoords += pointerCount;
Garfield Tan00f511d2019-06-12 16:55:40 -07003000 MotionEntry* nextInjectedEntry =
3001 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3002 motionEvent->getDeviceId(), motionEvent->getSource(),
3003 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3004 motionEvent->getFlags(), motionEvent->getMetaState(),
3005 motionEvent->getButtonState(), motionEvent->getClassification(),
3006 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3007 motionEvent->getYPrecision(),
3008 motionEvent->getRawXCursorPosition(),
3009 motionEvent->getRawYCursorPosition(),
3010 motionEvent->getDownTime(), uint32_t(pointerCount),
3011 pointerProperties, samplePointerCoords,
3012 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013 lastInjectedEntry->next = nextInjectedEntry;
3014 lastInjectedEntry = nextInjectedEntry;
3015 }
3016 break;
3017 }
3018
3019 default:
3020 ALOGW("Cannot inject event of type %d", event->getType());
3021 return INPUT_EVENT_INJECTION_FAILED;
3022 }
3023
3024 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3025 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3026 injectionState->injectionIsAsync = true;
3027 }
3028
3029 injectionState->refCount += 1;
3030 lastInjectedEntry->injectionState = injectionState;
3031
3032 bool needWake = false;
Yi Kong9b14ac62018-07-17 13:48:38 -07003033 for (EventEntry* entry = firstInjectedEntry; entry != nullptr; ) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003034 EventEntry* nextEntry = entry->next;
3035 needWake |= enqueueInboundEventLocked(entry);
3036 entry = nextEntry;
3037 }
3038
3039 mLock.unlock();
3040
3041 if (needWake) {
3042 mLooper->wake();
3043 }
3044
3045 int32_t injectionResult;
3046 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003047 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048
3049 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3050 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3051 } else {
3052 for (;;) {
3053 injectionResult = injectionState->injectionResult;
3054 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3055 break;
3056 }
3057
3058 nsecs_t remainingTimeout = endTime - now();
3059 if (remainingTimeout <= 0) {
3060#if DEBUG_INJECTION
3061 ALOGD("injectInputEvent - Timed out waiting for injection result "
3062 "to become available.");
3063#endif
3064 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3065 break;
3066 }
3067
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003068 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003069 }
3070
3071 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3072 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
3073 while (injectionState->pendingForegroundDispatches != 0) {
3074#if DEBUG_INJECTION
3075 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
3076 injectionState->pendingForegroundDispatches);
3077#endif
3078 nsecs_t remainingTimeout = endTime - now();
3079 if (remainingTimeout <= 0) {
3080#if DEBUG_INJECTION
3081 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3082 "dispatches to finish.");
3083#endif
3084 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3085 break;
3086 }
3087
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003088 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003089 }
3090 }
3091 }
3092
3093 injectionState->release();
3094 } // release lock
3095
3096#if DEBUG_INJECTION
3097 ALOGD("injectInputEvent - Finished with result %d. "
3098 "injectorPid=%d, injectorUid=%d",
3099 injectionResult, injectorPid, injectorUid);
3100#endif
3101
3102 return injectionResult;
3103}
3104
3105bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3106 return injectorUid == 0
3107 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3108}
3109
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003110void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003111 InjectionState* injectionState = entry->injectionState;
3112 if (injectionState) {
3113#if DEBUG_INJECTION
3114 ALOGD("Setting input event injection result to %d. "
3115 "injectorPid=%d, injectorUid=%d",
3116 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
3117#endif
3118
3119 if (injectionState->injectionIsAsync
3120 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
3121 // Log the outcome since the injector did not wait for the injection result.
3122 switch (injectionResult) {
3123 case INPUT_EVENT_INJECTION_SUCCEEDED:
3124 ALOGV("Asynchronous input event injection succeeded.");
3125 break;
3126 case INPUT_EVENT_INJECTION_FAILED:
3127 ALOGW("Asynchronous input event injection failed.");
3128 break;
3129 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3130 ALOGW("Asynchronous input event injection permission denied.");
3131 break;
3132 case INPUT_EVENT_INJECTION_TIMED_OUT:
3133 ALOGW("Asynchronous input event injection timed out.");
3134 break;
3135 }
3136 }
3137
3138 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003139 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003140 }
3141}
3142
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003143void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144 InjectionState* injectionState = entry->injectionState;
3145 if (injectionState) {
3146 injectionState->pendingForegroundDispatches += 1;
3147 }
3148}
3149
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003150void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003151 InjectionState* injectionState = entry->injectionState;
3152 if (injectionState) {
3153 injectionState->pendingForegroundDispatches -= 1;
3154
3155 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003156 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003157 }
3158 }
3159}
3160
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003161std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3162 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003163 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003164}
3165
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003167 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003168 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003169 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3170 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003171 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003172 return windowHandle;
3173 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003174 }
3175 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003176 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177}
3178
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003179bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003180 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003181 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3182 for (const sp<InputWindowHandle>& handle : windowHandles) {
3183 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003184 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003185 ALOGE("Found window %s in display %" PRId32
3186 ", but it should belong to display %" PRId32,
3187 windowHandle->getName().c_str(), it.first,
3188 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003189 }
3190 return true;
3191 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192 }
3193 }
3194 return false;
3195}
3196
Robert Carr5c8a0262018-10-03 16:30:44 -07003197sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3198 size_t count = mInputChannelsByToken.count(token);
3199 if (count == 0) {
3200 return nullptr;
3201 }
3202 return mInputChannelsByToken.at(token);
3203}
3204
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003205void InputDispatcher::updateWindowHandlesForDisplayLocked(
3206 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3207 if (inputWindowHandles.empty()) {
3208 // Remove all handles on a display if there are no windows left.
3209 mWindowHandlesByDisplay.erase(displayId);
3210 return;
3211 }
3212
3213 // Since we compare the pointer of input window handles across window updates, we need
3214 // to make sure the handle object for the same window stays unchanged across updates.
3215 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
3216 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3217 for (const sp<InputWindowHandle>& handle : oldHandles) {
3218 oldHandlesByTokens[handle->getToken()] = handle;
3219 }
3220
3221 std::vector<sp<InputWindowHandle>> newHandles;
3222 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3223 if (!handle->updateInfo()) {
3224 // handle no longer valid
3225 continue;
3226 }
3227
3228 const InputWindowInfo* info = handle->getInfo();
3229 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3230 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3231 const bool noInputChannel =
3232 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3233 const bool canReceiveInput =
3234 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3235 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3236 if (canReceiveInput && !noInputChannel) {
3237 ALOGE("Window handle %s has no registered input channel",
3238 handle->getName().c_str());
3239 }
3240 continue;
3241 }
3242
3243 if (info->displayId != displayId) {
3244 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3245 handle->getName().c_str(), displayId, info->displayId);
3246 continue;
3247 }
3248
3249 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3250 const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
3251 oldHandle->updateFrom(handle);
3252 newHandles.push_back(oldHandle);
3253 } else {
3254 newHandles.push_back(handle);
3255 }
3256 }
3257
3258 // Insert or replace
3259 mWindowHandlesByDisplay[displayId] = newHandles;
3260}
3261
Arthur Hungb92218b2018-08-14 12:00:21 +08003262/**
3263 * Called from InputManagerService, update window handle list by displayId that can receive input.
3264 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3265 * If set an empty list, remove all handles from the specific display.
3266 * For focused handle, check if need to change and send a cancel event to previous one.
3267 * For removed handle, check if need to send a cancel event if already in touch.
3268 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003269void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
chaviw291d88a2019-02-14 10:33:58 -08003270 int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003272 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003273#endif
3274 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003275 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003276
Arthur Hungb92218b2018-08-14 12:00:21 +08003277 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003278 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3279 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003280
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003281 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3282
Tiger Huang721e26f2018-07-24 22:26:19 +08003283 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003284 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003285 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3286 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3287 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3288 windowHandle->getInfo()->visible) {
3289 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003290 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003291 if (windowHandle == mLastHoverWindowHandle) {
3292 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294 }
3295
3296 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003297 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003298 }
3299
Tiger Huang721e26f2018-07-24 22:26:19 +08003300 sp<InputWindowHandle> oldFocusedWindowHandle =
3301 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3302
3303 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3304 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003306 ALOGD("Focus left window: %s in display %" PRId32,
3307 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003308#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003309 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3310 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003311 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3313 "focus left window");
3314 synthesizeCancelationEventsForInputChannelLocked(
3315 focusedInputChannel, options);
3316 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003317 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003319 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003320#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003321 ALOGD("Focus entered window: %s in display %" PRId32,
3322 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003324 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003325 }
Robert Carrf759f162018-11-13 12:57:11 -08003326
3327 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003328 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003329 }
3330
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 }
3332
Arthur Hungb92218b2018-08-14 12:00:21 +08003333 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3334 if (stateIndex >= 0) {
3335 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003336 for (size_t i = 0; i < state.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003337 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003338 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003340 ALOGD("Touched window was removed: %s in display %" PRId32,
3341 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003343 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003344 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003345 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003346 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3347 "touched window was removed");
3348 synthesizeCancelationEventsForInputChannelLocked(
3349 touchedInputChannel, options);
3350 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003351 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003352 } else {
3353 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003354 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003355 }
3356 }
3357
3358 // Release information for windows that are no longer present.
3359 // This ensures that unused input channels are released promptly.
3360 // Otherwise, they might stick around until the window handle is destroyed
3361 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003362 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003363 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003364#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003365 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003366#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003367 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003368 }
3369 }
3370 } // release lock
3371
3372 // Wake up poll loop since it may need to make new input dispatching choices.
3373 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003374
3375 if (setInputWindowsListener) {
3376 setInputWindowsListener->onSetInputWindowsFinished();
3377 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378}
3379
3380void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003381 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003382#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003383 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384#endif
3385 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003386 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387
Tiger Huang721e26f2018-07-24 22:26:19 +08003388 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3389 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003390 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003391 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3392 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003393 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003394 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003395 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003397 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003399 oldFocusedApplicationHandle.clear();
3400 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401 }
3402
3403#if DEBUG_FOCUS
3404 //logDispatchStateLocked();
3405#endif
3406 } // release lock
3407
3408 // Wake up poll loop since it may need to make new input dispatching choices.
3409 mLooper->wake();
3410}
3411
Tiger Huang721e26f2018-07-24 22:26:19 +08003412/**
3413 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3414 * the display not specified.
3415 *
3416 * We track any unreleased events for each window. If a window loses the ability to receive the
3417 * released event, we will send a cancel event to it. So when the focused display is changed, we
3418 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3419 * display. The display-specified events won't be affected.
3420 */
3421void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3422#if DEBUG_FOCUS
3423 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3424#endif
3425 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003426 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003427
3428 if (mFocusedDisplayId != displayId) {
3429 sp<InputWindowHandle> oldFocusedWindowHandle =
3430 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3431 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003432 sp<InputChannel> inputChannel =
3433 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003434 if (inputChannel != nullptr) {
3435 CancelationOptions options(
Michael Wright3dd60e22019-03-27 22:06:44 +00003436 CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Tiger Huang721e26f2018-07-24 22:26:19 +08003437 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003438 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003439 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3440 }
3441 }
3442 mFocusedDisplayId = displayId;
3443
3444 // Sanity check
3445 sp<InputWindowHandle> newFocusedWindowHandle =
3446 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003447 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003448
Tiger Huang721e26f2018-07-24 22:26:19 +08003449 if (newFocusedWindowHandle == nullptr) {
3450 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3451 if (!mFocusedWindowHandlesByDisplay.empty()) {
3452 ALOGE("But another display has a focused window:");
3453 for (auto& it : mFocusedWindowHandlesByDisplay) {
3454 const int32_t displayId = it.first;
3455 const sp<InputWindowHandle>& windowHandle = it.second;
3456 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3457 displayId, windowHandle->getName().c_str());
3458 }
3459 }
3460 }
3461 }
3462
3463#if DEBUG_FOCUS
3464 logDispatchStateLocked();
3465#endif
3466 } // release lock
3467
3468 // Wake up poll loop since it may need to make new input dispatching choices.
3469 mLooper->wake();
3470}
3471
Michael Wrightd02c5b62014-02-10 15:10:22 -08003472void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3473#if DEBUG_FOCUS
3474 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3475#endif
3476
3477 bool changed;
3478 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003479 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480
3481 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3482 if (mDispatchFrozen && !frozen) {
3483 resetANRTimeoutsLocked();
3484 }
3485
3486 if (mDispatchEnabled && !enabled) {
3487 resetAndDropEverythingLocked("dispatcher is being disabled");
3488 }
3489
3490 mDispatchEnabled = enabled;
3491 mDispatchFrozen = frozen;
3492 changed = true;
3493 } else {
3494 changed = false;
3495 }
3496
3497#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003498 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003499#endif
3500 } // release lock
3501
3502 if (changed) {
3503 // Wake up poll loop since it may need to make new input dispatching choices.
3504 mLooper->wake();
3505 }
3506}
3507
3508void InputDispatcher::setInputFilterEnabled(bool enabled) {
3509#if DEBUG_FOCUS
3510 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3511#endif
3512
3513 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003514 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515
3516 if (mInputFilterEnabled == enabled) {
3517 return;
3518 }
3519
3520 mInputFilterEnabled = enabled;
3521 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3522 } // release lock
3523
3524 // Wake up poll loop since there might be work to do to drop everything.
3525 mLooper->wake();
3526}
3527
chaviwfbe5d9c2018-12-26 12:23:37 -08003528bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3529 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003531 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003533 return true;
3534 }
3535
Michael Wrightd02c5b62014-02-10 15:10:22 -08003536 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003537 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003538
chaviwfbe5d9c2018-12-26 12:23:37 -08003539 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3540 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003541 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003542 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003543 return false;
3544 }
chaviw4f2dd402018-12-26 15:30:27 -08003545#if DEBUG_FOCUS
3546 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3547 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3548#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003549 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3550#if DEBUG_FOCUS
3551 ALOGD("Cannot transfer focus because windows are on different displays.");
3552#endif
3553 return false;
3554 }
3555
3556 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003557 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3558 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3559 for (size_t i = 0; i < state.windows.size(); i++) {
3560 const TouchedWindow& touchedWindow = state.windows[i];
3561 if (touchedWindow.windowHandle == fromWindowHandle) {
3562 int32_t oldTargetFlags = touchedWindow.targetFlags;
3563 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003565 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003566
Jeff Brownf086ddb2014-02-11 14:28:48 -08003567 int32_t newTargetFlags = oldTargetFlags
3568 & (InputTarget::FLAG_FOREGROUND
3569 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3570 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003571
Jeff Brownf086ddb2014-02-11 14:28:48 -08003572 found = true;
3573 goto Found;
3574 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 }
3576 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003577Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003578
3579 if (! found) {
3580#if DEBUG_FOCUS
3581 ALOGD("Focus transfer failed because from window did not have focus.");
3582#endif
3583 return false;
3584 }
3585
chaviwfbe5d9c2018-12-26 12:23:37 -08003586
3587 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3588 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003589 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3590 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3591 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3592 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3593 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3594
3595 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3596 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3597 "transferring touch focus from this window to another window");
3598 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3599 }
3600
3601#if DEBUG_FOCUS
3602 logDispatchStateLocked();
3603#endif
3604 } // release lock
3605
3606 // Wake up poll loop since it may need to make new input dispatching choices.
3607 mLooper->wake();
3608 return true;
3609}
3610
3611void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3612#if DEBUG_FOCUS
3613 ALOGD("Resetting and dropping all events (%s).", reason);
3614#endif
3615
3616 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3617 synthesizeCancelationEventsForAllConnectionsLocked(options);
3618
3619 resetKeyRepeatLocked();
3620 releasePendingEventLocked();
3621 drainInboundQueueLocked();
3622 resetANRTimeoutsLocked();
3623
Jeff Brownf086ddb2014-02-11 14:28:48 -08003624 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003625 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003626 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627}
3628
3629void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003630 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003631 dumpDispatchStateLocked(dump);
3632
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003633 std::istringstream stream(dump);
3634 std::string line;
3635
3636 while (std::getline(stream, line, '\n')) {
3637 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003638 }
3639}
3640
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003641void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003642 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3643 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3644 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003645 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003646
Tiger Huang721e26f2018-07-24 22:26:19 +08003647 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3648 dump += StringPrintf(INDENT "FocusedApplications:\n");
3649 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3650 const int32_t displayId = it.first;
3651 const sp<InputApplicationHandle>& applicationHandle = it.second;
3652 dump += StringPrintf(
3653 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3654 displayId,
3655 applicationHandle->getName().c_str(),
3656 applicationHandle->getDispatchingTimeout(
3657 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3658 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003659 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003660 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003662
3663 if (!mFocusedWindowHandlesByDisplay.empty()) {
3664 dump += StringPrintf(INDENT "FocusedWindows:\n");
3665 for (auto& it : mFocusedWindowHandlesByDisplay) {
3666 const int32_t displayId = it.first;
3667 const sp<InputWindowHandle>& windowHandle = it.second;
3668 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3669 displayId, windowHandle->getName().c_str());
3670 }
3671 } else {
3672 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003674
Jeff Brownf086ddb2014-02-11 14:28:48 -08003675 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003676 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003677 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3678 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003679 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003680 state.displayId, toString(state.down), toString(state.split),
3681 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003682 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003683 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003684 for (size_t i = 0; i < state.windows.size(); i++) {
3685 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003686 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3687 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003688 touchedWindow.pointerIds.value,
3689 touchedWindow.targetFlags);
3690 }
3691 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003692 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003693 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003694 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003695 dump += INDENT3 "Portal windows:\n";
3696 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003697 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003698 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3699 i, portalWindowHandle->getName().c_str());
3700 }
3701 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003702 }
3703 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003704 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003705 }
3706
Arthur Hungb92218b2018-08-14 12:00:21 +08003707 if (!mWindowHandlesByDisplay.empty()) {
3708 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003709 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003710 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003711 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003712 dump += INDENT2 "Windows:\n";
3713 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003714 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003715 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003716
Arthur Hungb92218b2018-08-14 12:00:21 +08003717 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003718 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003719 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003720 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003721 "touchableRegion=",
3722 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003723 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003724 toString(windowInfo->paused),
3725 toString(windowInfo->hasFocus),
3726 toString(windowInfo->hasWallpaper),
3727 toString(windowInfo->visible),
3728 toString(windowInfo->canReceiveKeys),
3729 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3730 windowInfo->layer,
3731 windowInfo->frameLeft, windowInfo->frameTop,
3732 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003733 windowInfo->globalScaleFactor,
3734 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003735 dumpRegion(dump, windowInfo->touchableRegion);
3736 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3737 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3738 windowInfo->ownerPid, windowInfo->ownerUid,
3739 windowInfo->dispatchingTimeout / 1000000.0);
3740 }
3741 } else {
3742 dump += INDENT2 "Windows: <none>\n";
3743 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003744 }
3745 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003746 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003747 }
3748
Michael Wright3dd60e22019-03-27 22:06:44 +00003749 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
3750 for (auto& it : mGlobalMonitorsByDisplay) {
3751 const std::vector<Monitor>& monitors = it.second;
3752 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3753 dumpMonitors(dump, monitors);
3754 }
3755 for (auto& it : mGestureMonitorsByDisplay) {
3756 const std::vector<Monitor>& monitors = it.second;
3757 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3758 dumpMonitors(dump, monitors);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003759 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003760 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003761 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762 }
3763
3764 nsecs_t currentTime = now();
3765
3766 // Dump recently dispatched or dropped events from oldest to newest.
3767 if (!mRecentQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003768 dump += StringPrintf(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769 for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003770 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003772 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003773 (currentTime - entry->eventTime) * 0.000001f);
3774 }
3775 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003776 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777 }
3778
3779 // Dump event currently being dispatched.
3780 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003781 dump += INDENT "PendingEvent:\n";
3782 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003784 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3786 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003787 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788 }
3789
3790 // Dump inbound events from oldest to newest.
3791 if (!mInboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003792 dump += StringPrintf(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003794 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003796 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 (currentTime - entry->eventTime) * 0.000001f);
3798 }
3799 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003800 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003801 }
3802
Michael Wright78f24442014-08-06 15:55:28 -07003803 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003804 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003805 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3806 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3807 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003808 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003809 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3810 }
3811 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003812 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003813 }
3814
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003816 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003817 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3818 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003819 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003821 i, connection->getInputChannelName().c_str(),
3822 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003823 connection->getStatusLabel(), toString(connection->monitor),
3824 toString(connection->inputPublisherBlocked));
3825
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003826 if (!connection->outboundQueue.empty()) {
3827 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
3828 connection->outboundQueue.size());
3829 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003830 dump.append(INDENT4);
3831 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003832 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003833 entry->targetFlags, entry->resolvedAction,
3834 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3835 }
3836 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003837 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003838 }
3839
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003840 if (!connection->waitQueue.empty()) {
3841 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
3842 connection->waitQueue.size());
3843 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003844 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003845 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003846 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003847 "age=%0.1fms, wait=%0.1fms\n",
3848 entry->targetFlags, entry->resolvedAction,
3849 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3850 (currentTime - entry->deliveryTime) * 0.000001f);
3851 }
3852 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003853 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854 }
3855 }
3856 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003857 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 }
3859
3860 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003861 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862 (mAppSwitchDueTime - now()) / 1000000.0);
3863 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003864 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 }
3866
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003867 dump += INDENT "Configuration:\n";
3868 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003869 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003870 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871 mConfig.keyRepeatTimeout * 0.000001f);
3872}
3873
Michael Wright3dd60e22019-03-27 22:06:44 +00003874void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3875 const size_t numMonitors = monitors.size();
3876 for (size_t i = 0; i < numMonitors; i++) {
3877 const Monitor& monitor = monitors[i];
3878 const sp<InputChannel>& channel = monitor.inputChannel;
3879 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3880 dump += "\n";
3881 }
3882}
3883
3884status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3885 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003886#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003887 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3888 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889#endif
3890
3891 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003892 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003893
3894 if (getConnectionIndexLocked(inputChannel) >= 0) {
3895 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003896 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003897 return BAD_VALUE;
3898 }
3899
Michael Wright3dd60e22019-03-27 22:06:44 +00003900 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003901
3902 int fd = inputChannel->getFd();
3903 mConnectionsByFd.add(fd, connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07003904 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905
Michael Wrightd02c5b62014-02-10 15:10:22 -08003906 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3907 } // release lock
3908
3909 // Wake the looper because some connections have changed.
3910 mLooper->wake();
3911 return OK;
3912}
3913
Michael Wright3dd60e22019-03-27 22:06:44 +00003914status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
3915 int32_t displayId, bool isGestureMonitor) {
3916 { // acquire lock
3917 std::scoped_lock _l(mLock);
3918
3919 if (displayId < 0) {
3920 ALOGW("Attempted to register input monitor without a specified display.");
3921 return BAD_VALUE;
3922 }
3923
3924 if (inputChannel->getToken() == nullptr) {
3925 ALOGW("Attempted to register input monitor without an identifying token.");
3926 return BAD_VALUE;
3927 }
3928
3929 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3930
3931 const int fd = inputChannel->getFd();
3932 mConnectionsByFd.add(fd, connection);
3933 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3934
3935 auto& monitorsByDisplay = isGestureMonitor
3936 ? mGestureMonitorsByDisplay
3937 : mGlobalMonitorsByDisplay;
3938 monitorsByDisplay[displayId].emplace_back(inputChannel);
3939
3940 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3941
3942 }
3943 // Wake the looper because some connections have changed.
3944 mLooper->wake();
3945 return OK;
3946}
3947
Michael Wrightd02c5b62014-02-10 15:10:22 -08003948status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3949#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003950 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951#endif
3952
3953 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003954 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003955
3956 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3957 if (status) {
3958 return status;
3959 }
3960 } // release lock
3961
3962 // Wake the poll loop because removing the connection may have changed the current
3963 // synchronization state.
3964 mLooper->wake();
3965 return OK;
3966}
3967
3968status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3969 bool notify) {
3970 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3971 if (connectionIndex < 0) {
3972 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003973 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 return BAD_VALUE;
3975 }
3976
3977 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3978 mConnectionsByFd.removeItemsAt(connectionIndex);
3979
Robert Carr5c8a0262018-10-03 16:30:44 -07003980 mInputChannelsByToken.erase(inputChannel->getToken());
3981
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982 if (connection->monitor) {
3983 removeMonitorChannelLocked(inputChannel);
3984 }
3985
3986 mLooper->removeFd(inputChannel->getFd());
3987
3988 nsecs_t currentTime = now();
3989 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3990
3991 connection->status = Connection::STATUS_ZOMBIE;
3992 return OK;
3993}
3994
3995void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003996 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
3997 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
3998}
3999
4000void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
4001 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
4002 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end(); ) {
4003 std::vector<Monitor>& monitors = it->second;
4004 const size_t numMonitors = monitors.size();
4005 for (size_t i = 0; i < numMonitors; i++) {
4006 if (monitors[i].inputChannel == inputChannel) {
4007 monitors.erase(monitors.begin() + i);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004008 break;
4009 }
4010 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004011 if (monitors.empty()) {
4012 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004013 } else {
4014 ++it;
4015 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004016 }
4017}
4018
Michael Wright3dd60e22019-03-27 22:06:44 +00004019status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4020 { // acquire lock
4021 std::scoped_lock _l(mLock);
4022 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4023
4024 if (!foundDisplayId) {
4025 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4026 return BAD_VALUE;
4027 }
4028 int32_t displayId = foundDisplayId.value();
4029
4030 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4031 if (stateIndex < 0) {
4032 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4033 return BAD_VALUE;
4034 }
4035
4036 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4037 std::optional<int32_t> foundDeviceId;
4038 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4039 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4040 foundDeviceId = state.deviceId;
4041 }
4042 }
4043 if (!foundDeviceId || !state.down) {
4044 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
4045 " Ignoring.");
4046 return BAD_VALUE;
4047 }
4048 int32_t deviceId = foundDeviceId.value();
4049
4050 // Send cancel events to all the input channels we're stealing from.
4051 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4052 "gesture monitor stole pointer stream");
4053 options.deviceId = deviceId;
4054 options.displayId = displayId;
4055 for (const TouchedWindow& window : state.windows) {
4056 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4057 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4058 }
4059 // Then clear the current touch state so we stop dispatching to them as well.
4060 state.filterNonMonitors();
4061 }
4062 return OK;
4063}
4064
4065
4066std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4067 const sp<IBinder>& token) {
4068 for (const auto& it : mGestureMonitorsByDisplay) {
4069 const std::vector<Monitor>& monitors = it.second;
4070 for (const Monitor& monitor : monitors) {
4071 if (monitor.inputChannel->getToken() == token) {
4072 return it.first;
4073 }
4074 }
4075 }
4076 return std::nullopt;
4077}
4078
Michael Wrightd02c5b62014-02-10 15:10:22 -08004079ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004080 if (inputChannel == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08004081 return -1;
4082 }
4083
Robert Carr4e670e52018-08-15 13:26:12 -07004084 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
4085 sp<Connection> connection = mConnectionsByFd.valueAt(i);
4086 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
4087 return i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004088 }
4089 }
Robert Carr4e670e52018-08-15 13:26:12 -07004090
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 return -1;
4092}
4093
4094void InputDispatcher::onDispatchCycleFinishedLocked(
4095 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004096 CommandEntry* commandEntry =
4097 postCommandLocked(&InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004098 commandEntry->connection = connection;
4099 commandEntry->eventTime = currentTime;
4100 commandEntry->seq = seq;
4101 commandEntry->handled = handled;
4102}
4103
4104void InputDispatcher::onDispatchCycleBrokenLocked(
4105 nsecs_t currentTime, const sp<Connection>& connection) {
4106 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004107 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004108
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004109 CommandEntry* commandEntry =
4110 postCommandLocked(&InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004111 commandEntry->connection = connection;
4112}
4113
chaviw0c06c6e2019-01-09 13:27:07 -08004114void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
4115 const sp<InputWindowHandle>& newFocus) {
4116 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4117 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004118 CommandEntry* commandEntry =
4119 postCommandLocked(&InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004120 commandEntry->oldToken = oldToken;
4121 commandEntry->newToken = newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004122}
4123
Michael Wrightd02c5b62014-02-10 15:10:22 -08004124void InputDispatcher::onANRLocked(
4125 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
4126 const sp<InputWindowHandle>& windowHandle,
4127 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
4128 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4129 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4130 ALOGI("Application is not responding: %s. "
4131 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004132 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004133 dispatchLatency, waitDuration, reason);
4134
4135 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004136 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004137 struct tm tm;
4138 localtime_r(&t, &tm);
4139 char timestr[64];
4140 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4141 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004142 mLastANRState += INDENT "ANR:\n";
4143 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
4144 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004145 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004146 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4147 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4148 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004149 dumpDispatchStateLocked(mLastANRState);
4150
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004151 CommandEntry* commandEntry =
4152 postCommandLocked(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004153 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07004154 commandEntry->inputChannel = windowHandle != nullptr ?
4155 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 commandEntry->reason = reason;
4157}
4158
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004159void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
Michael Wrightd02c5b62014-02-10 15:10:22 -08004160 CommandEntry* commandEntry) {
4161 mLock.unlock();
4162
4163 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4164
4165 mLock.lock();
4166}
4167
4168void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
4169 CommandEntry* commandEntry) {
4170 sp<Connection> connection = commandEntry->connection;
4171
4172 if (connection->status != Connection::STATUS_ZOMBIE) {
4173 mLock.unlock();
4174
Robert Carr803535b2018-08-02 16:38:15 -07004175 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004176
4177 mLock.lock();
4178 }
4179}
4180
Robert Carrf759f162018-11-13 12:57:11 -08004181void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
4182 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004183 sp<IBinder> oldToken = commandEntry->oldToken;
4184 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004185 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004186 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004187 mLock.lock();
4188}
4189
Michael Wrightd02c5b62014-02-10 15:10:22 -08004190void InputDispatcher::doNotifyANRLockedInterruptible(
4191 CommandEntry* commandEntry) {
4192 mLock.unlock();
4193
4194 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07004195 commandEntry->inputApplicationHandle,
4196 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004197 commandEntry->reason);
4198
4199 mLock.lock();
4200
4201 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07004202 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203}
4204
4205void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4206 CommandEntry* commandEntry) {
4207 KeyEntry* entry = commandEntry->keyEntry;
4208
4209 KeyEvent event;
4210 initializeKeyEvent(&event, entry);
4211
4212 mLock.unlock();
4213
Michael Wright2b3c3302018-03-02 17:19:13 +00004214 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07004215 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
4216 commandEntry->inputChannel->getToken() : nullptr;
4217 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004218 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004219 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4220 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
4221 std::to_string(t.duration().count()).c_str());
4222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223
4224 mLock.lock();
4225
4226 if (delay < 0) {
4227 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4228 } else if (!delay) {
4229 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4230 } else {
4231 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4232 entry->interceptKeyWakeupTime = now() + delay;
4233 }
4234 entry->release();
4235}
4236
chaviwfd6d3512019-03-25 13:23:49 -07004237void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4238 mLock.unlock();
4239 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4240 mLock.lock();
4241}
4242
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
4244 CommandEntry* commandEntry) {
4245 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004246 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004247 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004248 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004249
4250 // Handle post-event policy actions.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004251 std::deque<InputDispatcher::DispatchEntry*>::iterator dispatchEntryIt =
4252 connection->findWaitQueueEntry(seq);
4253 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004254 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004255 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004256 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004257
4258 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4259 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4260 std::string msg =
4261 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4262 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4263 dispatchEntry->eventEntry->appendDescription(msg);
4264 ALOGI("%s", msg.c_str());
4265 }
4266
4267 bool restartEvent;
4268 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4269 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4270 restartEvent =
4271 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
4272 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4273 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4274 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4275 handled);
4276 } else {
4277 restartEvent = false;
4278 }
4279
4280 // Dequeue the event and start the next cycle.
4281 // Note that because the lock might have been released, it is possible that the
4282 // contents of the wait queue to have been drained, so we need to double-check
4283 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004284 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4285 if (dispatchEntryIt != connection->waitQueue.end()) {
4286 dispatchEntry = *dispatchEntryIt;
4287 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004288 traceWaitQueueLength(connection);
4289 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004290 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004291 traceOutboundQueueLength(connection);
4292 } else {
4293 releaseDispatchEntry(dispatchEntry);
4294 }
4295 }
4296
4297 // Start the next dispatch cycle for this connection.
4298 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004299}
4300
4301bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4302 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004303 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004304 if (!handled) {
4305 // Report the key as unhandled, since the fallback was not handled.
4306 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4307 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004308 return false;
4309 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004311 // Get the fallback key state.
4312 // Clear it out after dispatching the UP.
4313 int32_t originalKeyCode = keyEntry->keyCode;
4314 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4315 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4316 connection->inputState.removeFallbackKey(originalKeyCode);
4317 }
4318
4319 if (handled || !dispatchEntry->hasForegroundTarget()) {
4320 // If the application handles the original key for which we previously
4321 // generated a fallback or if the window is not a foreground window,
4322 // then cancel the associated fallback key, if any.
4323 if (fallbackKeyCode != -1) {
4324 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004326 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004327 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4328 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4329 keyEntry->policyFlags);
4330#endif
4331 KeyEvent event;
4332 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004333 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334
4335 mLock.unlock();
4336
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004337 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4338 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004339
4340 mLock.lock();
4341
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004342 // Cancel the fallback key.
4343 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004345 "application handled the original non-fallback key "
4346 "or is no longer a foreground target, "
4347 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004348 options.keyCode = fallbackKeyCode;
4349 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004351 connection->inputState.removeFallbackKey(originalKeyCode);
4352 }
4353 } else {
4354 // If the application did not handle a non-fallback key, first check
4355 // that we are in a good state to perform unhandled key event processing
4356 // Then ask the policy what to do with it.
4357 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4358 && keyEntry->repeatCount == 0;
4359 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004360#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004361 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4362 "since this is not an initial down. "
4363 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4364 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4365 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004366#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004367 return false;
4368 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004369
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004370 // Dispatch the unhandled key to the policy.
4371#if DEBUG_OUTBOUND_EVENT_DETAILS
4372 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4373 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4374 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4375 keyEntry->policyFlags);
4376#endif
4377 KeyEvent event;
4378 initializeKeyEvent(&event, keyEntry);
4379
4380 mLock.unlock();
4381
4382 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4383 &event, keyEntry->policyFlags, &event);
4384
4385 mLock.lock();
4386
4387 if (connection->status != Connection::STATUS_NORMAL) {
4388 connection->inputState.removeFallbackKey(originalKeyCode);
4389 return false;
4390 }
4391
4392 // Latch the fallback keycode for this key on an initial down.
4393 // The fallback keycode cannot change at any other point in the lifecycle.
4394 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004396 fallbackKeyCode = event.getKeyCode();
4397 } else {
4398 fallbackKeyCode = AKEYCODE_UNKNOWN;
4399 }
4400 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4401 }
4402
4403 ALOG_ASSERT(fallbackKeyCode != -1);
4404
4405 // Cancel the fallback key if the policy decides not to send it anymore.
4406 // We will continue to dispatch the key to the policy but we will no
4407 // longer dispatch a fallback key to the application.
4408 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4409 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4410#if DEBUG_OUTBOUND_EVENT_DETAILS
4411 if (fallback) {
4412 ALOGD("Unhandled key event: Policy requested to send key %d"
4413 "as a fallback for %d, but on the DOWN it had requested "
4414 "to send %d instead. Fallback canceled.",
4415 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4416 } else {
4417 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4418 "but on the DOWN it had requested to send %d. "
4419 "Fallback canceled.",
4420 originalKeyCode, fallbackKeyCode);
4421 }
4422#endif
4423
4424 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4425 "canceling fallback, policy no longer desires it");
4426 options.keyCode = fallbackKeyCode;
4427 synthesizeCancelationEventsForConnectionLocked(connection, options);
4428
4429 fallback = false;
4430 fallbackKeyCode = AKEYCODE_UNKNOWN;
4431 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4432 connection->inputState.setFallbackKey(originalKeyCode,
4433 fallbackKeyCode);
4434 }
4435 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004436
4437#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004438 {
4439 std::string msg;
4440 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4441 connection->inputState.getFallbackKeys();
4442 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4443 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4444 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004445 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004446 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4447 fallbackKeys.size(), msg.c_str());
4448 }
4449#endif
4450
4451 if (fallback) {
4452 // Restart the dispatch cycle using the fallback key.
4453 keyEntry->eventTime = event.getEventTime();
4454 keyEntry->deviceId = event.getDeviceId();
4455 keyEntry->source = event.getSource();
4456 keyEntry->displayId = event.getDisplayId();
4457 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4458 keyEntry->keyCode = fallbackKeyCode;
4459 keyEntry->scanCode = event.getScanCode();
4460 keyEntry->metaState = event.getMetaState();
4461 keyEntry->repeatCount = event.getRepeatCount();
4462 keyEntry->downTime = event.getDownTime();
4463 keyEntry->syntheticRepeat = false;
4464
4465#if DEBUG_OUTBOUND_EVENT_DETAILS
4466 ALOGD("Unhandled key event: Dispatching fallback key. "
4467 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4468 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4469#endif
4470 return true; // restart the event
4471 } else {
4472#if DEBUG_OUTBOUND_EVENT_DETAILS
4473 ALOGD("Unhandled key event: No fallback key.");
4474#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004475
4476 // Report the key as unhandled, since there is no fallback key.
4477 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 }
4479 }
4480 return false;
4481}
4482
4483bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4484 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4485 return false;
4486}
4487
4488void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4489 mLock.unlock();
4490
4491 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4492
4493 mLock.lock();
4494}
4495
4496void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004497 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4499 entry->downTime, entry->eventTime);
4500}
4501
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004502void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004503 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4504 // TODO Write some statistics about how long we spend waiting.
4505}
4506
4507void InputDispatcher::traceInboundQueueLengthLocked() {
4508 if (ATRACE_ENABLED()) {
4509 ATRACE_INT("iq", mInboundQueue.count());
4510 }
4511}
4512
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004513void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004514 if (ATRACE_ENABLED()) {
4515 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004516 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004517 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004518 }
4519}
4520
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004521void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004522 if (ATRACE_ENABLED()) {
4523 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004524 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004525 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004526 }
4527}
4528
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004529void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004530 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004531
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004532 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004533 dumpDispatchStateLocked(dump);
4534
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004535 if (!mLastANRState.empty()) {
4536 dump += "\nInput Dispatcher State at time of last ANR:\n";
4537 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004538 }
4539}
4540
4541void InputDispatcher::monitor() {
4542 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004543 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004544 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004545 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004546}
4547
4548
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549// --- InputDispatcher::InjectionState ---
4550
4551InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4552 refCount(1),
4553 injectorPid(injectorPid), injectorUid(injectorUid),
4554 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4555 pendingForegroundDispatches(0) {
4556}
4557
4558InputDispatcher::InjectionState::~InjectionState() {
4559}
4560
4561void InputDispatcher::InjectionState::release() {
4562 refCount -= 1;
4563 if (refCount == 0) {
4564 delete this;
4565 } else {
4566 ALOG_ASSERT(refCount > 0);
4567 }
4568}
4569
4570
4571// --- InputDispatcher::EventEntry ---
4572
Prabir Pradhan42611e02018-11-27 14:04:02 -08004573InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4574 nsecs_t eventTime, uint32_t policyFlags) :
4575 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4576 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577}
4578
4579InputDispatcher::EventEntry::~EventEntry() {
4580 releaseInjectionState();
4581}
4582
4583void InputDispatcher::EventEntry::release() {
4584 refCount -= 1;
4585 if (refCount == 0) {
4586 delete this;
4587 } else {
4588 ALOG_ASSERT(refCount > 0);
4589 }
4590}
4591
4592void InputDispatcher::EventEntry::releaseInjectionState() {
4593 if (injectionState) {
4594 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004595 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004596 }
4597}
4598
4599
4600// --- InputDispatcher::ConfigurationChangedEntry ---
4601
Prabir Pradhan42611e02018-11-27 14:04:02 -08004602InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4603 uint32_t sequenceNum, nsecs_t eventTime) :
4604 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605}
4606
4607InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4608}
4609
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004610void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4611 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004612}
4613
4614
4615// --- InputDispatcher::DeviceResetEntry ---
4616
Prabir Pradhan42611e02018-11-27 14:04:02 -08004617InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4618 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4619 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004620 deviceId(deviceId) {
4621}
4622
4623InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4624}
4625
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004626void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4627 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004628 deviceId, policyFlags);
4629}
4630
4631
4632// --- InputDispatcher::KeyEntry ---
4633
Prabir Pradhan42611e02018-11-27 14:04:02 -08004634InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004635 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004636 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4637 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004638 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004639 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4641 repeatCount(repeatCount), downTime(downTime),
4642 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4643 interceptKeyWakeupTime(0) {
4644}
4645
4646InputDispatcher::KeyEntry::~KeyEntry() {
4647}
4648
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004649void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004650 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004651 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4652 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004653 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004654 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004655}
4656
4657void InputDispatcher::KeyEntry::recycle() {
4658 releaseInjectionState();
4659
4660 dispatchInProgress = false;
4661 syntheticRepeat = false;
4662 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4663 interceptKeyWakeupTime = 0;
4664}
4665
4666
4667// --- InputDispatcher::MotionEntry ---
4668
Garfield Tan00f511d2019-06-12 16:55:40 -07004669InputDispatcher::MotionEntry::MotionEntry(
4670 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4671 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004672 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004673 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4674 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004675 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004676 float xOffset, float yOffset)
4677 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004678 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004679 deviceId(deviceId),
4680 source(source),
4681 displayId(displayId),
4682 action(action),
4683 actionButton(actionButton),
4684 flags(flags),
4685 metaState(metaState),
4686 buttonState(buttonState),
4687 classification(classification),
4688 edgeFlags(edgeFlags),
4689 xPrecision(xPrecision),
4690 yPrecision(yPrecision),
4691 xCursorPosition(xCursorPosition),
4692 yCursorPosition(yCursorPosition),
4693 downTime(downTime),
4694 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004695 for (uint32_t i = 0; i < pointerCount; i++) {
4696 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4697 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004698 if (xOffset || yOffset) {
4699 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004701 }
4702}
4703
4704InputDispatcher::MotionEntry::~MotionEntry() {
4705}
4706
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004707void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004708 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004709 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4710 "buttonState=0x%08x, "
4711 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4712 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4713 deviceId, source, displayId, motionActionToString(action).c_str(),
4714 actionButton, flags, metaState, buttonState,
4715 motionClassificationToString(classification), edgeFlags, xPrecision,
4716 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004717
Michael Wrightd02c5b62014-02-10 15:10:22 -08004718 for (uint32_t i = 0; i < pointerCount; i++) {
4719 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004720 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004721 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004722 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004723 pointerCoords[i].getX(), pointerCoords[i].getY());
4724 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004725 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726}
4727
4728
4729// --- InputDispatcher::DispatchEntry ---
4730
4731volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4732
4733InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004734 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4735 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004736 seq(nextSeq()),
4737 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004738 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4739 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004740 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4741 eventEntry->refCount += 1;
4742}
4743
4744InputDispatcher::DispatchEntry::~DispatchEntry() {
4745 eventEntry->release();
4746}
4747
4748uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4749 // Sequence number 0 is reserved and will never be returned.
4750 uint32_t seq;
4751 do {
4752 seq = android_atomic_inc(&sNextSeqAtomic);
4753 } while (!seq);
4754 return seq;
4755}
4756
4757
4758// --- InputDispatcher::InputState ---
4759
4760InputDispatcher::InputState::InputState() {
4761}
4762
4763InputDispatcher::InputState::~InputState() {
4764}
4765
4766bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004767 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004768}
4769
4770bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4771 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004772 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004773 if (memento.deviceId == deviceId
4774 && memento.source == source
4775 && memento.displayId == displayId
4776 && memento.hovering) {
4777 return true;
4778 }
4779 }
4780 return false;
4781}
4782
4783bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4784 int32_t action, int32_t flags) {
4785 switch (action) {
4786 case AKEY_EVENT_ACTION_UP: {
4787 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4788 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4789 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4790 mFallbackKeys.removeItemsAt(i);
4791 } else {
4792 i += 1;
4793 }
4794 }
4795 }
4796 ssize_t index = findKeyMemento(entry);
4797 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004798 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004799 return true;
4800 }
4801 /* FIXME: We can't just drop the key up event because that prevents creating
4802 * popup windows that are automatically shown when a key is held and then
4803 * dismissed when the key is released. The problem is that the popup will
4804 * not have received the original key down, so the key up will be considered
4805 * to be inconsistent with its observed state. We could perhaps handle this
4806 * by synthesizing a key down but that will cause other problems.
4807 *
4808 * So for now, allow inconsistent key up events to be dispatched.
4809 *
4810#if DEBUG_OUTBOUND_EVENT_DETAILS
4811 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4812 "keyCode=%d, scanCode=%d",
4813 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4814#endif
4815 return false;
4816 */
4817 return true;
4818 }
4819
4820 case AKEY_EVENT_ACTION_DOWN: {
4821 ssize_t index = findKeyMemento(entry);
4822 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004823 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824 }
4825 addKeyMemento(entry, flags);
4826 return true;
4827 }
4828
4829 default:
4830 return true;
4831 }
4832}
4833
4834bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4835 int32_t action, int32_t flags) {
4836 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4837 switch (actionMasked) {
4838 case AMOTION_EVENT_ACTION_UP:
4839 case AMOTION_EVENT_ACTION_CANCEL: {
4840 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4841 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004842 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004843 return true;
4844 }
4845#if DEBUG_OUTBOUND_EVENT_DETAILS
4846 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004847 "displayId=%" PRId32 ", actionMasked=%d",
4848 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004849#endif
4850 return false;
4851 }
4852
4853 case AMOTION_EVENT_ACTION_DOWN: {
4854 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4855 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004856 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004857 }
4858 addMotionMemento(entry, flags, false /*hovering*/);
4859 return true;
4860 }
4861
4862 case AMOTION_EVENT_ACTION_POINTER_UP:
4863 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4864 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004865 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4866 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4867 // generate cancellation events for these since they're based in relative rather than
4868 // absolute units.
4869 return true;
4870 }
4871
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004873
4874 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4875 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4876 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4877 // other value and we need to track the motion so we can send cancellation events for
4878 // anything generating fallback events (e.g. DPad keys for joystick movements).
4879 if (index >= 0) {
4880 if (entry->pointerCoords[0].isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004881 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wright38dcdff2014-03-19 12:06:10 -07004882 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004883 MotionMemento& memento = mMotionMementos[index];
Michael Wright38dcdff2014-03-19 12:06:10 -07004884 memento.setPointers(entry);
4885 }
4886 } else if (!entry->pointerCoords[0].isEmpty()) {
4887 addMotionMemento(entry, flags, false /*hovering*/);
4888 }
4889
4890 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4891 return true;
4892 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004893 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004894 MotionMemento& memento = mMotionMementos[index];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895 memento.setPointers(entry);
4896 return true;
4897 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004898#if DEBUG_OUTBOUND_EVENT_DETAILS
4899 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004900 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4901 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902#endif
4903 return false;
4904 }
4905
4906 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4907 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4908 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004909 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004910 return true;
4911 }
4912#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004913 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4914 "displayId=%" PRId32,
4915 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004916#endif
4917 return false;
4918 }
4919
4920 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4921 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4922 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4923 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004924 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 }
4926 addMotionMemento(entry, flags, true /*hovering*/);
4927 return true;
4928 }
4929
4930 default:
4931 return true;
4932 }
4933}
4934
4935ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4936 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004937 const KeyMemento& memento = mKeyMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938 if (memento.deviceId == entry->deviceId
4939 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004940 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004941 && memento.keyCode == entry->keyCode
4942 && memento.scanCode == entry->scanCode) {
4943 return i;
4944 }
4945 }
4946 return -1;
4947}
4948
4949ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4950 bool hovering) const {
4951 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004952 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004953 if (memento.deviceId == entry->deviceId
4954 && memento.source == entry->source
4955 && memento.displayId == entry->displayId
4956 && memento.hovering == hovering) {
4957 return i;
4958 }
4959 }
4960 return -1;
4961}
4962
4963void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004964 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004965 memento.deviceId = entry->deviceId;
4966 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004967 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968 memento.keyCode = entry->keyCode;
4969 memento.scanCode = entry->scanCode;
4970 memento.metaState = entry->metaState;
4971 memento.flags = flags;
4972 memento.downTime = entry->downTime;
4973 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004974 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975}
4976
4977void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4978 int32_t flags, bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004979 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004980 memento.deviceId = entry->deviceId;
4981 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004982 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983 memento.flags = flags;
4984 memento.xPrecision = entry->xPrecision;
4985 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07004986 memento.xCursorPosition = entry->xCursorPosition;
4987 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004988 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004989 memento.setPointers(entry);
4990 memento.hovering = hovering;
4991 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004992 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004993}
4994
4995void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4996 pointerCount = entry->pointerCount;
4997 for (uint32_t i = 0; i < entry->pointerCount; i++) {
4998 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
4999 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
5000 }
5001}
5002
5003void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005004 std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
5005 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005006 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005007 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005008 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08005009 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
5010 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
5011 }
5012 }
5013
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005014 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005015 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08005016 const int32_t action = memento.hovering ?
5017 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005018 outEvents.push_back(
5019 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5020 memento.source, memento.displayId, memento.policyFlags, action,
5021 0 /*actionButton*/, memento.flags, AMETA_NONE,
5022 0 /*buttonState*/, MotionClassification::NONE,
5023 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5024 memento.yPrecision, memento.xCursorPosition,
5025 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5026 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5027 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005028 }
5029 }
5030}
5031
5032void InputDispatcher::InputState::clear() {
5033 mKeyMementos.clear();
5034 mMotionMementos.clear();
5035 mFallbackKeys.clear();
5036}
5037
5038void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5039 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005040 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
5042 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005043 const MotionMemento& otherMemento = other.mMotionMementos[j];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005044 if (memento.deviceId == otherMemento.deviceId
5045 && memento.source == otherMemento.source
5046 && memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005047 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005048 } else {
5049 j += 1;
5050 }
5051 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005052 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005053 }
5054 }
5055}
5056
5057int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5058 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5059 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5060}
5061
5062void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
5063 int32_t fallbackKeyCode) {
5064 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5065 if (index >= 0) {
5066 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5067 } else {
5068 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5069 }
5070}
5071
5072void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5073 mFallbackKeys.removeItem(originalKeyCode);
5074}
5075
5076bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
5077 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005078 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005079 return false;
5080 }
5081
Michael Wright3dd60e22019-03-27 22:06:44 +00005082 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5083 return false;
5084 }
5085
5086 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087 return false;
5088 }
5089
5090 switch (options.mode) {
5091 case CancelationOptions::CANCEL_ALL_EVENTS:
5092 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5093 return true;
5094 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5095 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5096 default:
5097 return false;
5098 }
5099}
5100
5101bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5102 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005103 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5104 return false;
5105 }
5106
5107 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005108 return false;
5109 }
5110
5111 switch (options.mode) {
5112 case CancelationOptions::CANCEL_ALL_EVENTS:
5113 return true;
5114 case CancelationOptions::CANCEL_POINTER_EVENTS:
5115 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5116 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5117 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5118 default:
5119 return false;
5120 }
5121}
5122
5123
5124// --- InputDispatcher::Connection ---
5125
Robert Carr803535b2018-08-02 16:38:15 -07005126InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
5127 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128 monitor(monitor),
5129 inputPublisher(inputChannel), inputPublisherBlocked(false) {
5130}
5131
5132InputDispatcher::Connection::~Connection() {
5133}
5134
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005135const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005136 if (inputChannel != nullptr) {
5137 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005138 }
5139 if (monitor) {
5140 return "monitor";
5141 }
5142 return "?";
5143}
5144
5145const char* InputDispatcher::Connection::getStatusLabel() const {
5146 switch (status) {
5147 case STATUS_NORMAL:
5148 return "NORMAL";
5149
5150 case STATUS_BROKEN:
5151 return "BROKEN";
5152
5153 case STATUS_ZOMBIE:
5154 return "ZOMBIE";
5155
5156 default:
5157 return "UNKNOWN";
5158 }
5159}
5160
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005161std::deque<InputDispatcher::DispatchEntry*>::iterator
5162InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
5163 for (std::deque<DispatchEntry*>::iterator it = waitQueue.begin(); it != waitQueue.end(); it++) {
5164 if ((*it)->seq == seq) {
5165 return it;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005166 }
5167 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005168 return waitQueue.end();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005169}
5170
Michael Wright3dd60e22019-03-27 22:06:44 +00005171// --- InputDispatcher::Monitor
5172InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel) :
5173 inputChannel(inputChannel) {
5174}
5175
Michael Wrightd02c5b62014-02-10 15:10:22 -08005176
5177// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005178//
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07005180 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005181 seq(0), handled(false) {
5182}
5183
5184InputDispatcher::CommandEntry::~CommandEntry() {
5185}
5186
Michael Wright3dd60e22019-03-27 22:06:44 +00005187// --- InputDispatcher::TouchedMonitor ---
5188InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
5189 float yOffset) : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {
5190}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191
5192// --- InputDispatcher::TouchState ---
5193
5194InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005195 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005196}
5197
5198InputDispatcher::TouchState::~TouchState() {
5199}
5200
5201void InputDispatcher::TouchState::reset() {
5202 down = false;
5203 split = false;
5204 deviceId = -1;
5205 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005206 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005207 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005208 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005209 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005210}
5211
5212void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5213 down = other.down;
5214 split = other.split;
5215 deviceId = other.deviceId;
5216 source = other.source;
5217 displayId = other.displayId;
5218 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005219 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005220 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005221}
5222
5223void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
5224 int32_t targetFlags, BitSet32 pointerIds) {
5225 if (targetFlags & InputTarget::FLAG_SPLIT) {
5226 split = true;
5227 }
5228
5229 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005230 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005231 if (touchedWindow.windowHandle == windowHandle) {
5232 touchedWindow.targetFlags |= targetFlags;
5233 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5234 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5235 }
5236 touchedWindow.pointerIds.value |= pointerIds.value;
5237 return;
5238 }
5239 }
5240
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005241 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005242 touchedWindow.windowHandle = windowHandle;
5243 touchedWindow.targetFlags = targetFlags;
5244 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005245 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005246}
5247
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005248void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5249 size_t numWindows = portalWindows.size();
5250 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005251 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005252 return;
5253 }
5254 }
5255 portalWindows.push_back(windowHandle);
5256}
5257
Michael Wright3dd60e22019-03-27 22:06:44 +00005258void InputDispatcher::TouchState::addGestureMonitors(
5259 const std::vector<TouchedMonitor>& newMonitors) {
5260 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5261 gestureMonitors.reserve(newSize);
5262 gestureMonitors.insert(std::end(gestureMonitors),
5263 std::begin(newMonitors), std::end(newMonitors));
5264}
5265
Michael Wrightd02c5b62014-02-10 15:10:22 -08005266void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5267 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005268 if (windows[i].windowHandle == windowHandle) {
5269 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005270 return;
5271 }
5272 }
5273}
5274
Robert Carr803535b2018-08-02 16:38:15 -07005275void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5276 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005277 if (windows[i].windowHandle->getToken() == token) {
5278 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005279 return;
5280 }
5281 }
5282}
5283
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
5285 for (size_t i = 0 ; i < windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005286 TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005287 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
5288 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
5289 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5290 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5291 i += 1;
5292 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005293 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005294 }
5295 }
5296}
5297
Michael Wright3dd60e22019-03-27 22:06:44 +00005298void InputDispatcher::TouchState::filterNonMonitors() {
5299 windows.clear();
5300 portalWindows.clear();
5301}
5302
Michael Wrightd02c5b62014-02-10 15:10:22 -08005303sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5304 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005305 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5307 return window.windowHandle;
5308 }
5309 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005310 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005311}
5312
5313bool InputDispatcher::TouchState::isSlippery() const {
5314 // Must have exactly one foreground window.
5315 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005316 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005317 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5318 if (haveSlipperyForegroundWindow
5319 || !(window.windowHandle->getInfo()->layoutParamsFlags
5320 & InputWindowInfo::FLAG_SLIPPERY)) {
5321 return false;
5322 }
5323 haveSlipperyForegroundWindow = true;
5324 }
5325 }
5326 return haveSlipperyForegroundWindow;
5327}
5328
5329
5330// --- InputDispatcherThread ---
5331
5332InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5333 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5334}
5335
5336InputDispatcherThread::~InputDispatcherThread() {
5337}
5338
5339bool InputDispatcherThread::threadLoop() {
5340 mDispatcher->dispatchOnce();
5341 return true;
5342}
5343
5344} // namespace android