blob: 2e984d9ca927a5ecf68e524edef2f09f5e782836 [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
20//#define LOG_NDEBUG 0
21
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>
49#include <limits.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080050#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070051#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070053#include <unistd.h>
54
Michael Wright2b3c3302018-03-02 17:19:13 +000055#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080056#include <android-base/stringprintf.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070057#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070058#include <utils/Trace.h>
59#include <powermanager/PowerManager.h>
60#include <ui/Region.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080061
62#define INDENT " "
63#define INDENT2 " "
64#define INDENT3 " "
65#define INDENT4 " "
66
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080067using android::base::StringPrintf;
68
Michael Wrightd02c5b62014-02-10 15:10:22 -080069namespace android {
70
71// Default input dispatching timeout if there is no focused application or paused window
72// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000073constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080074
75// Amount of time to allow for all pending events to be processed when an app switch
76// key is on the way. This is used to preempt input dispatch and drop input events
77// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000078constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080079
80// Amount of time to allow for an event to be dispatched (measured since its eventTime)
81// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000082constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080083
84// Amount of time to allow touch events to be streamed out to a connection before requiring
85// that the first event be finished. This value extends the ANR timeout by the specified
86// amount. For example, if streaming is allowed to get ahead by one second relative to the
87// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000088constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080089
90// 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 +000091constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
92
93// Log a warning when an interception call takes longer than this to process.
94constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
96// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000097constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
98
Michael Wrightd02c5b62014-02-10 15:10:22 -080099
100static inline nsecs_t now() {
101 return systemTime(SYSTEM_TIME_MONOTONIC);
102}
103
104static inline const char* toString(bool value) {
105 return value ? "true" : "false";
106}
107
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800108static std::string motionActionToString(int32_t action) {
109 // Convert MotionEvent action to string
110 switch(action & AMOTION_EVENT_ACTION_MASK) {
111 case AMOTION_EVENT_ACTION_DOWN:
112 return "DOWN";
113 case AMOTION_EVENT_ACTION_MOVE:
114 return "MOVE";
115 case AMOTION_EVENT_ACTION_UP:
116 return "UP";
117 case AMOTION_EVENT_ACTION_POINTER_DOWN:
118 return "POINTER_DOWN";
119 case AMOTION_EVENT_ACTION_POINTER_UP:
120 return "POINTER_UP";
121 }
122 return StringPrintf("%" PRId32, action);
123}
124
125static std::string keyActionToString(int32_t action) {
126 // Convert KeyEvent action to string
127 switch(action) {
128 case AKEY_EVENT_ACTION_DOWN:
129 return "DOWN";
130 case AKEY_EVENT_ACTION_UP:
131 return "UP";
132 case AKEY_EVENT_ACTION_MULTIPLE:
133 return "MULTIPLE";
134 }
135 return StringPrintf("%" PRId32, action);
136}
137
Michael Wrightd02c5b62014-02-10 15:10:22 -0800138static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
139 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
140 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
141}
142
143static bool isValidKeyAction(int32_t action) {
144 switch (action) {
145 case AKEY_EVENT_ACTION_DOWN:
146 case AKEY_EVENT_ACTION_UP:
147 return true;
148 default:
149 return false;
150 }
151}
152
153static bool validateKeyEvent(int32_t action) {
154 if (! isValidKeyAction(action)) {
155 ALOGE("Key event has invalid action code 0x%x", action);
156 return false;
157 }
158 return true;
159}
160
Michael Wright7b159c92015-05-14 14:48:03 +0100161static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800162 switch (action & AMOTION_EVENT_ACTION_MASK) {
163 case AMOTION_EVENT_ACTION_DOWN:
164 case AMOTION_EVENT_ACTION_UP:
165 case AMOTION_EVENT_ACTION_CANCEL:
166 case AMOTION_EVENT_ACTION_MOVE:
167 case AMOTION_EVENT_ACTION_OUTSIDE:
168 case AMOTION_EVENT_ACTION_HOVER_ENTER:
169 case AMOTION_EVENT_ACTION_HOVER_MOVE:
170 case AMOTION_EVENT_ACTION_HOVER_EXIT:
171 case AMOTION_EVENT_ACTION_SCROLL:
172 return true;
173 case AMOTION_EVENT_ACTION_POINTER_DOWN:
174 case AMOTION_EVENT_ACTION_POINTER_UP: {
175 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800176 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 }
Michael Wright7b159c92015-05-14 14:48:03 +0100178 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
179 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
180 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 default:
182 return false;
183 }
184}
185
Michael Wright7b159c92015-05-14 14:48:03 +0100186static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800187 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100188 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 ALOGE("Motion event has invalid action code 0x%x", action);
190 return false;
191 }
192 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000193 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800194 pointerCount, MAX_POINTERS);
195 return false;
196 }
197 BitSet32 pointerIdBits;
198 for (size_t i = 0; i < pointerCount; i++) {
199 int32_t id = pointerProperties[i].id;
200 if (id < 0 || id > MAX_POINTER_ID) {
201 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
202 id, MAX_POINTER_ID);
203 return false;
204 }
205 if (pointerIdBits.hasBit(id)) {
206 ALOGE("Motion event has duplicate pointer id %d", id);
207 return false;
208 }
209 pointerIdBits.markBit(id);
210 }
211 return true;
212}
213
214static bool isMainDisplay(int32_t displayId) {
215 return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
216}
217
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800218static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800220 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 return;
222 }
223
224 bool first = true;
225 Region::const_iterator cur = region.begin();
226 Region::const_iterator const tail = region.end();
227 while (cur != tail) {
228 if (first) {
229 first = false;
230 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800231 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800233 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800234 cur++;
235 }
236}
237
Tiger Huang721e26f2018-07-24 22:26:19 +0800238template<typename T, typename U>
239static T getValueByKey(std::unordered_map<U, T>& map, U key) {
240 typename std::unordered_map<U, T>::const_iterator it = map.find(key);
241 return it != map.end() ? it->second : T{};
242}
243
Michael Wrightd02c5b62014-02-10 15:10:22 -0800244
245// --- InputDispatcher ---
246
247InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
248 mPolicy(policy),
Yi Kong9b14ac62018-07-17 13:48:38 -0700249 mPendingEvent(nullptr), mLastDropReason(DROP_REASON_NOT_DROPPED),
Michael Wright3a981722015-06-10 15:26:13 +0100250 mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
Yi Kong9b14ac62018-07-17 13:48:38 -0700251 mNextUnblockedEvent(nullptr),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
Tiger Huang721e26f2018-07-24 22:26:19 +0800253 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
255 mLooper = new Looper(false);
256
Yi Kong9b14ac62018-07-17 13:48:38 -0700257 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258
259 policy->getDispatcherConfiguration(&mConfig);
260}
261
262InputDispatcher::~InputDispatcher() {
263 { // acquire lock
264 AutoMutex _l(mLock);
265
266 resetKeyRepeatLocked();
267 releasePendingEventLocked();
268 drainInboundQueueLocked();
269 }
270
271 while (mConnectionsByFd.size() != 0) {
272 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
273 }
274}
275
276void InputDispatcher::dispatchOnce() {
277 nsecs_t nextWakeupTime = LONG_LONG_MAX;
278 { // acquire lock
279 AutoMutex _l(mLock);
280 mDispatcherIsAliveCondition.broadcast();
281
282 // Run a dispatch loop if there are no pending commands.
283 // The dispatch loop might enqueue commands to run afterwards.
284 if (!haveCommandsLocked()) {
285 dispatchOnceInnerLocked(&nextWakeupTime);
286 }
287
288 // Run all pending commands if there are any.
289 // If any commands were run then force the next poll to wake up immediately.
290 if (runCommandsLockedInterruptible()) {
291 nextWakeupTime = LONG_LONG_MIN;
292 }
293 } // release lock
294
295 // Wait for callback or timeout or wake. (make sure we round up, not down)
296 nsecs_t currentTime = now();
297 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
298 mLooper->pollOnce(timeoutMillis);
299}
300
301void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
302 nsecs_t currentTime = now();
303
Jeff Browndc5992e2014-04-11 01:27:26 -0700304 // Reset the key repeat timer whenever normal dispatch is suspended while the
305 // device is in a non-interactive state. This is to ensure that we abort a key
306 // repeat if the device is just coming out of sleep.
307 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800308 resetKeyRepeatLocked();
309 }
310
311 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
312 if (mDispatchFrozen) {
313#if DEBUG_FOCUS
314 ALOGD("Dispatch frozen. Waiting some more.");
315#endif
316 return;
317 }
318
319 // Optimize latency of app switches.
320 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
321 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
322 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
323 if (mAppSwitchDueTime < *nextWakeupTime) {
324 *nextWakeupTime = mAppSwitchDueTime;
325 }
326
327 // Ready to start a new event.
328 // If we don't already have a pending event, go grab one.
329 if (! mPendingEvent) {
330 if (mInboundQueue.isEmpty()) {
331 if (isAppSwitchDue) {
332 // The inbound queue is empty so the app switch key we were waiting
333 // for will never arrive. Stop waiting for it.
334 resetPendingAppSwitchLocked(false);
335 isAppSwitchDue = false;
336 }
337
338 // Synthesize a key repeat if appropriate.
339 if (mKeyRepeatState.lastKeyEntry) {
340 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
341 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
342 } else {
343 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
344 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
345 }
346 }
347 }
348
349 // Nothing to do if there is no pending event.
350 if (!mPendingEvent) {
351 return;
352 }
353 } else {
354 // Inbound queue has at least one entry.
355 mPendingEvent = mInboundQueue.dequeueAtHead();
356 traceInboundQueueLengthLocked();
357 }
358
359 // Poke user activity for this event.
360 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
361 pokeUserActivityLocked(mPendingEvent);
362 }
363
364 // Get ready to dispatch the event.
365 resetANRTimeoutsLocked();
366 }
367
368 // Now we have an event to dispatch.
369 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700370 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800371 bool done = false;
372 DropReason dropReason = DROP_REASON_NOT_DROPPED;
373 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
374 dropReason = DROP_REASON_POLICY;
375 } else if (!mDispatchEnabled) {
376 dropReason = DROP_REASON_DISABLED;
377 }
378
379 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700380 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800381 }
382
383 switch (mPendingEvent->type) {
384 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
385 ConfigurationChangedEntry* typedEntry =
386 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
387 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
388 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
389 break;
390 }
391
392 case EventEntry::TYPE_DEVICE_RESET: {
393 DeviceResetEntry* typedEntry =
394 static_cast<DeviceResetEntry*>(mPendingEvent);
395 done = dispatchDeviceResetLocked(currentTime, typedEntry);
396 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
397 break;
398 }
399
400 case EventEntry::TYPE_KEY: {
401 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
402 if (isAppSwitchDue) {
403 if (isAppSwitchKeyEventLocked(typedEntry)) {
404 resetPendingAppSwitchLocked(true);
405 isAppSwitchDue = false;
406 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
407 dropReason = DROP_REASON_APP_SWITCH;
408 }
409 }
410 if (dropReason == DROP_REASON_NOT_DROPPED
411 && isStaleEventLocked(currentTime, typedEntry)) {
412 dropReason = DROP_REASON_STALE;
413 }
414 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
415 dropReason = DROP_REASON_BLOCKED;
416 }
417 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
418 break;
419 }
420
421 case EventEntry::TYPE_MOTION: {
422 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
423 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
424 dropReason = DROP_REASON_APP_SWITCH;
425 }
426 if (dropReason == DROP_REASON_NOT_DROPPED
427 && isStaleEventLocked(currentTime, typedEntry)) {
428 dropReason = DROP_REASON_STALE;
429 }
430 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
431 dropReason = DROP_REASON_BLOCKED;
432 }
433 done = dispatchMotionLocked(currentTime, typedEntry,
434 &dropReason, nextWakeupTime);
435 break;
436 }
437
438 default:
439 ALOG_ASSERT(false);
440 break;
441 }
442
443 if (done) {
444 if (dropReason != DROP_REASON_NOT_DROPPED) {
445 dropInboundEventLocked(mPendingEvent, dropReason);
446 }
Michael Wright3a981722015-06-10 15:26:13 +0100447 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800448
449 releasePendingEventLocked();
450 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
451 }
452}
453
454bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
455 bool needWake = mInboundQueue.isEmpty();
456 mInboundQueue.enqueueAtTail(entry);
457 traceInboundQueueLengthLocked();
458
459 switch (entry->type) {
460 case EventEntry::TYPE_KEY: {
461 // Optimize app switch latency.
462 // If the application takes too long to catch up then we drop all events preceding
463 // the app switch key.
464 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
465 if (isAppSwitchKeyEventLocked(keyEntry)) {
466 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
467 mAppSwitchSawKeyDown = true;
468 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
469 if (mAppSwitchSawKeyDown) {
470#if DEBUG_APP_SWITCH
471 ALOGD("App switch is pending!");
472#endif
473 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
474 mAppSwitchSawKeyDown = false;
475 needWake = true;
476 }
477 }
478 }
479 break;
480 }
481
482 case EventEntry::TYPE_MOTION: {
483 // Optimize case where the current application is unresponsive and the user
484 // decides to touch a window in a different application.
485 // If the application takes too long to catch up then we drop all events preceding
486 // the touch into the other window.
487 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
488 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
489 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
490 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Yi Kong9b14ac62018-07-17 13:48:38 -0700491 && mInputTargetWaitApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800492 int32_t displayId = motionEntry->displayId;
493 int32_t x = int32_t(motionEntry->pointerCoords[0].
494 getAxisValue(AMOTION_EVENT_AXIS_X));
495 int32_t y = int32_t(motionEntry->pointerCoords[0].
496 getAxisValue(AMOTION_EVENT_AXIS_Y));
497 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700498 if (touchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -0800499 && touchedWindowHandle->inputApplicationHandle
500 != mInputTargetWaitApplicationHandle) {
501 // User touched a different application than the one we are waiting on.
502 // Flag the event, and start pruning the input queue.
503 mNextUnblockedEvent = motionEntry;
504 needWake = true;
505 }
506 }
507 break;
508 }
509 }
510
511 return needWake;
512}
513
514void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
515 entry->refCount += 1;
516 mRecentQueue.enqueueAtTail(entry);
517 if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
518 mRecentQueue.dequeueAtHead()->release();
519 }
520}
521
522sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
523 int32_t x, int32_t y) {
524 // Traverse windows from front to back to find touched window.
Arthur Hungb92218b2018-08-14 12:00:21 +0800525 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
526 size_t numWindows = windowHandles.size();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800527 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800528 sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800529 const InputWindowInfo* windowInfo = windowHandle->getInfo();
530 if (windowInfo->displayId == displayId) {
531 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532
533 if (windowInfo->visible) {
534 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
535 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
536 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
537 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
538 // Found window.
539 return windowHandle;
540 }
541 }
542 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800543 }
544 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700545 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800546}
547
548void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
549 const char* reason;
550 switch (dropReason) {
551 case DROP_REASON_POLICY:
552#if DEBUG_INBOUND_EVENT_DETAILS
553 ALOGD("Dropped event because policy consumed it.");
554#endif
555 reason = "inbound event was dropped because the policy consumed it";
556 break;
557 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100558 if (mLastDropReason != DROP_REASON_DISABLED) {
559 ALOGI("Dropped event because input dispatch is disabled.");
560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561 reason = "inbound event was dropped because input dispatch is disabled";
562 break;
563 case DROP_REASON_APP_SWITCH:
564 ALOGI("Dropped event because of pending overdue app switch.");
565 reason = "inbound event was dropped because of pending overdue app switch";
566 break;
567 case DROP_REASON_BLOCKED:
568 ALOGI("Dropped event because the current application is not responding and the user "
569 "has started interacting with a different application.");
570 reason = "inbound event was dropped because the current application is not responding "
571 "and the user has started interacting with a different application";
572 break;
573 case DROP_REASON_STALE:
574 ALOGI("Dropped event because it is stale.");
575 reason = "inbound event was dropped because it is stale";
576 break;
577 default:
578 ALOG_ASSERT(false);
579 return;
580 }
581
582 switch (entry->type) {
583 case EventEntry::TYPE_KEY: {
584 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
585 synthesizeCancelationEventsForAllConnectionsLocked(options);
586 break;
587 }
588 case EventEntry::TYPE_MOTION: {
589 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
590 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
591 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
592 synthesizeCancelationEventsForAllConnectionsLocked(options);
593 } else {
594 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
595 synthesizeCancelationEventsForAllConnectionsLocked(options);
596 }
597 break;
598 }
599 }
600}
601
602bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
603 return keyCode == AKEYCODE_HOME
604 || keyCode == AKEYCODE_ENDCALL
605 || keyCode == AKEYCODE_APP_SWITCH;
606}
607
608bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
609 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
610 && isAppSwitchKeyCode(keyEntry->keyCode)
611 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
612 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
613}
614
615bool InputDispatcher::isAppSwitchPendingLocked() {
616 return mAppSwitchDueTime != LONG_LONG_MAX;
617}
618
619void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
620 mAppSwitchDueTime = LONG_LONG_MAX;
621
622#if DEBUG_APP_SWITCH
623 if (handled) {
624 ALOGD("App switch has arrived.");
625 } else {
626 ALOGD("App switch was abandoned.");
627 }
628#endif
629}
630
631bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
632 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
633}
634
635bool InputDispatcher::haveCommandsLocked() const {
636 return !mCommandQueue.isEmpty();
637}
638
639bool InputDispatcher::runCommandsLockedInterruptible() {
640 if (mCommandQueue.isEmpty()) {
641 return false;
642 }
643
644 do {
645 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
646
647 Command command = commandEntry->command;
648 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
649
650 commandEntry->connection.clear();
651 delete commandEntry;
652 } while (! mCommandQueue.isEmpty());
653 return true;
654}
655
656InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
657 CommandEntry* commandEntry = new CommandEntry(command);
658 mCommandQueue.enqueueAtTail(commandEntry);
659 return commandEntry;
660}
661
662void InputDispatcher::drainInboundQueueLocked() {
663 while (! mInboundQueue.isEmpty()) {
664 EventEntry* entry = mInboundQueue.dequeueAtHead();
665 releaseInboundEventLocked(entry);
666 }
667 traceInboundQueueLengthLocked();
668}
669
670void InputDispatcher::releasePendingEventLocked() {
671 if (mPendingEvent) {
672 resetANRTimeoutsLocked();
673 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700674 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800675 }
676}
677
678void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
679 InjectionState* injectionState = entry->injectionState;
680 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
681#if DEBUG_DISPATCH_CYCLE
682 ALOGD("Injected inbound event was dropped.");
683#endif
684 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
685 }
686 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700687 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800688 }
689 addRecentEventLocked(entry);
690 entry->release();
691}
692
693void InputDispatcher::resetKeyRepeatLocked() {
694 if (mKeyRepeatState.lastKeyEntry) {
695 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700696 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697 }
698}
699
700InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
701 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
702
703 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700704 uint32_t policyFlags = entry->policyFlags &
705 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706 if (entry->refCount == 1) {
707 entry->recycle();
708 entry->eventTime = currentTime;
709 entry->policyFlags = policyFlags;
710 entry->repeatCount += 1;
711 } else {
712 KeyEntry* newEntry = new KeyEntry(currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100713 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 entry->action, entry->flags, entry->keyCode, entry->scanCode,
715 entry->metaState, entry->repeatCount + 1, entry->downTime);
716
717 mKeyRepeatState.lastKeyEntry = newEntry;
718 entry->release();
719
720 entry = newEntry;
721 }
722 entry->syntheticRepeat = true;
723
724 // Increment reference count since we keep a reference to the event in
725 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
726 entry->refCount += 1;
727
728 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
729 return entry;
730}
731
732bool InputDispatcher::dispatchConfigurationChangedLocked(
733 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
734#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700735 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800736#endif
737
738 // Reset key repeating in case a keyboard device was added or removed or something.
739 resetKeyRepeatLocked();
740
741 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
742 CommandEntry* commandEntry = postCommandLocked(
743 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
744 commandEntry->eventTime = entry->eventTime;
745 return true;
746}
747
748bool InputDispatcher::dispatchDeviceResetLocked(
749 nsecs_t currentTime, DeviceResetEntry* entry) {
750#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700751 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
752 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800753#endif
754
755 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
756 "device was reset");
757 options.deviceId = entry->deviceId;
758 synthesizeCancelationEventsForAllConnectionsLocked(options);
759 return true;
760}
761
762bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
763 DropReason* dropReason, nsecs_t* nextWakeupTime) {
764 // Preprocessing.
765 if (! entry->dispatchInProgress) {
766 if (entry->repeatCount == 0
767 && entry->action == AKEY_EVENT_ACTION_DOWN
768 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
769 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
770 if (mKeyRepeatState.lastKeyEntry
771 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
772 // We have seen two identical key downs in a row which indicates that the device
773 // driver is automatically generating key repeats itself. We take note of the
774 // repeat here, but we disable our own next key repeat timer since it is clear that
775 // we will not need to synthesize key repeats ourselves.
776 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
777 resetKeyRepeatLocked();
778 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
779 } else {
780 // Not a repeat. Save key down state in case we do see a repeat later.
781 resetKeyRepeatLocked();
782 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
783 }
784 mKeyRepeatState.lastKeyEntry = entry;
785 entry->refCount += 1;
786 } else if (! entry->syntheticRepeat) {
787 resetKeyRepeatLocked();
788 }
789
790 if (entry->repeatCount == 1) {
791 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
792 } else {
793 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
794 }
795
796 entry->dispatchInProgress = true;
797
798 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
799 }
800
801 // Handle case where the policy asked us to try again later last time.
802 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
803 if (currentTime < entry->interceptKeyWakeupTime) {
804 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
805 *nextWakeupTime = entry->interceptKeyWakeupTime;
806 }
807 return false; // wait until next wakeup
808 }
809 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
810 entry->interceptKeyWakeupTime = 0;
811 }
812
813 // Give the policy a chance to intercept the key.
814 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
815 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
816 CommandEntry* commandEntry = postCommandLocked(
817 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800818 sp<InputWindowHandle> focusedWindowHandle =
819 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
820 if (focusedWindowHandle != nullptr) {
821 commandEntry->inputWindowHandle = focusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822 }
823 commandEntry->keyEntry = entry;
824 entry->refCount += 1;
825 return false; // wait for the command to run
826 } else {
827 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
828 }
829 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
830 if (*dropReason == DROP_REASON_NOT_DROPPED) {
831 *dropReason = DROP_REASON_POLICY;
832 }
833 }
834
835 // Clean up if dropping the event.
836 if (*dropReason != DROP_REASON_NOT_DROPPED) {
837 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
838 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
839 return true;
840 }
841
842 // Identify targets.
843 Vector<InputTarget> inputTargets;
844 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
845 entry, inputTargets, nextWakeupTime);
846 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
847 return false;
848 }
849
850 setInjectionResultLocked(entry, injectionResult);
851 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
852 return true;
853 }
854
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800855 // Add monitor channels from event's or focused display.
856 addMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800857
858 // Dispatch the key.
859 dispatchEventLocked(currentTime, entry, inputTargets);
860 return true;
861}
862
863void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
864#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100865 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
866 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
867 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800868 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100869 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800870 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
871 entry->repeatCount, entry->downTime);
872#endif
873}
874
875bool InputDispatcher::dispatchMotionLocked(
876 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
877 // Preprocessing.
878 if (! entry->dispatchInProgress) {
879 entry->dispatchInProgress = true;
880
881 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
882 }
883
884 // Clean up if dropping the event.
885 if (*dropReason != DROP_REASON_NOT_DROPPED) {
886 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
887 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
888 return true;
889 }
890
891 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
892
893 // Identify targets.
894 Vector<InputTarget> inputTargets;
895
896 bool conflictingPointerActions = false;
897 int32_t injectionResult;
898 if (isPointerEvent) {
899 // Pointer event. (eg. touchscreen)
900 injectionResult = findTouchedWindowTargetsLocked(currentTime,
901 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
902 } else {
903 // Non touch event. (eg. trackball)
904 injectionResult = findFocusedWindowTargetsLocked(currentTime,
905 entry, inputTargets, nextWakeupTime);
906 }
907 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
908 return false;
909 }
910
911 setInjectionResultLocked(entry, injectionResult);
912 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100913 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
914 CancelationOptions::Mode mode(isPointerEvent ?
915 CancelationOptions::CANCEL_POINTER_EVENTS :
916 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
917 CancelationOptions options(mode, "input event injection failed");
918 synthesizeCancelationEventsForMonitorsLocked(options);
919 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800920 return true;
921 }
922
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800923 // Add monitor channels from event's or focused display.
924 addMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800925
926 // Dispatch the motion.
927 if (conflictingPointerActions) {
928 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
929 "conflicting pointer actions");
930 synthesizeCancelationEventsForAllConnectionsLocked(options);
931 }
932 dispatchEventLocked(currentTime, entry, inputTargets);
933 return true;
934}
935
936
937void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
938#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800939 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
940 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +0100941 "action=0x%x, actionButton=0x%x, flags=0x%x, "
942 "metaState=0x%x, buttonState=0x%x,"
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700943 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800944 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800945 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100946 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800947 entry->metaState, entry->buttonState,
948 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
949 entry->downTime);
950
951 for (uint32_t i = 0; i < entry->pointerCount; i++) {
952 ALOGD(" Pointer %d: id=%d, toolType=%d, "
953 "x=%f, y=%f, pressure=%f, size=%f, "
954 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -0800955 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956 i, entry->pointerProperties[i].id,
957 entry->pointerProperties[i].toolType,
958 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
959 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
960 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
961 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
962 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
963 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
964 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
965 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -0800966 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967 }
968#endif
969}
970
971void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
972 EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
973#if DEBUG_DISPATCH_CYCLE
974 ALOGD("dispatchEventToCurrentInputTargets");
975#endif
976
977 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
978
979 pokeUserActivityLocked(eventEntry);
980
981 for (size_t i = 0; i < inputTargets.size(); i++) {
982 const InputTarget& inputTarget = inputTargets.itemAt(i);
983
984 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
985 if (connectionIndex >= 0) {
986 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
987 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
988 } else {
989#if DEBUG_FOCUS
990 ALOGD("Dropping event delivery to target with channel '%s' because it "
991 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800992 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800993#endif
994 }
995 }
996}
997
998int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
999 const EventEntry* entry,
1000 const sp<InputApplicationHandle>& applicationHandle,
1001 const sp<InputWindowHandle>& windowHandle,
1002 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001003 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001004 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1005#if DEBUG_FOCUS
1006 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1007#endif
1008 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1009 mInputTargetWaitStartTime = currentTime;
1010 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1011 mInputTargetWaitTimeoutExpired = false;
1012 mInputTargetWaitApplicationHandle.clear();
1013 }
1014 } else {
1015 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1016#if DEBUG_FOCUS
1017 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001018 getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019 reason);
1020#endif
1021 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001022 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001023 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001024 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 timeout = applicationHandle->getDispatchingTimeout(
1026 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1027 } else {
1028 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1029 }
1030
1031 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1032 mInputTargetWaitStartTime = currentTime;
1033 mInputTargetWaitTimeoutTime = currentTime + timeout;
1034 mInputTargetWaitTimeoutExpired = false;
1035 mInputTargetWaitApplicationHandle.clear();
1036
Yi Kong9b14ac62018-07-17 13:48:38 -07001037 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001038 mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
1039 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001040 if (mInputTargetWaitApplicationHandle == nullptr && applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001041 mInputTargetWaitApplicationHandle = applicationHandle;
1042 }
1043 }
1044 }
1045
1046 if (mInputTargetWaitTimeoutExpired) {
1047 return INPUT_EVENT_INJECTION_TIMED_OUT;
1048 }
1049
1050 if (currentTime >= mInputTargetWaitTimeoutTime) {
1051 onANRLocked(currentTime, applicationHandle, windowHandle,
1052 entry->eventTime, mInputTargetWaitStartTime, reason);
1053
1054 // Force poll loop to wake up immediately on next iteration once we get the
1055 // ANR response back from the policy.
1056 *nextWakeupTime = LONG_LONG_MIN;
1057 return INPUT_EVENT_INJECTION_PENDING;
1058 } else {
1059 // Force poll loop to wake up when timeout is due.
1060 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1061 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1062 }
1063 return INPUT_EVENT_INJECTION_PENDING;
1064 }
1065}
1066
1067void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1068 const sp<InputChannel>& inputChannel) {
1069 if (newTimeout > 0) {
1070 // Extend the timeout.
1071 mInputTargetWaitTimeoutTime = now() + newTimeout;
1072 } else {
1073 // Give up.
1074 mInputTargetWaitTimeoutExpired = true;
1075
1076 // Input state will not be realistic. Mark it out of sync.
1077 if (inputChannel.get()) {
1078 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1079 if (connectionIndex >= 0) {
1080 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1081 sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
1082
Yi Kong9b14ac62018-07-17 13:48:38 -07001083 if (windowHandle != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001084 const InputWindowInfo* info = windowHandle->getInfo();
1085 if (info) {
1086 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(info->displayId);
1087 if (stateIndex >= 0) {
1088 mTouchStatesByDisplay.editValueAt(stateIndex).removeWindow(
1089 windowHandle);
1090 }
1091 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092 }
1093
1094 if (connection->status == Connection::STATUS_NORMAL) {
1095 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1096 "application not responding");
1097 synthesizeCancelationEventsForConnectionLocked(connection, options);
1098 }
1099 }
1100 }
1101 }
1102}
1103
1104nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1105 nsecs_t currentTime) {
1106 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1107 return currentTime - mInputTargetWaitStartTime;
1108 }
1109 return 0;
1110}
1111
1112void InputDispatcher::resetANRTimeoutsLocked() {
1113#if DEBUG_FOCUS
1114 ALOGD("Resetting ANR timeouts.");
1115#endif
1116
1117 // Reset input target wait timeout.
1118 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1119 mInputTargetWaitApplicationHandle.clear();
1120}
1121
Tiger Huang721e26f2018-07-24 22:26:19 +08001122/**
1123 * Get the display id that the given event should go to. If this event specifies a valid display id,
1124 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1125 * Focused display is the display that the user most recently interacted with.
1126 */
1127int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1128 int32_t displayId;
1129 switch (entry->type) {
1130 case EventEntry::TYPE_KEY: {
1131 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1132 displayId = typedEntry->displayId;
1133 break;
1134 }
1135 case EventEntry::TYPE_MOTION: {
1136 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1137 displayId = typedEntry->displayId;
1138 break;
1139 }
1140 default: {
1141 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1142 return ADISPLAY_ID_NONE;
1143 }
1144 }
1145 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1146}
1147
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1149 const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
1150 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001151 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001152
Tiger Huang721e26f2018-07-24 22:26:19 +08001153 int32_t displayId = getTargetDisplayId(entry);
1154 sp<InputWindowHandle> focusedWindowHandle =
1155 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1156 sp<InputApplicationHandle> focusedApplicationHandle =
1157 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1158
Michael Wrightd02c5b62014-02-10 15:10:22 -08001159 // If there is no currently focused window and no focused application
1160 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001161 if (focusedWindowHandle == nullptr) {
1162 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001163 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001164 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001165 "Waiting because no window has focus but there is a "
1166 "focused application that may eventually add a window "
1167 "when it finishes starting up.");
1168 goto Unresponsive;
1169 }
1170
1171 ALOGI("Dropping event because there is no focused window or focused application.");
1172 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1173 goto Failed;
1174 }
1175
1176 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001177 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1179 goto Failed;
1180 }
1181
Jeff Brownffb49772014-10-10 19:01:34 -07001182 // Check whether the window is ready for more input.
1183 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001184 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001185 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001187 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001188 goto Unresponsive;
1189 }
1190
1191 // Success! Output targets.
1192 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001193 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001194 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1195 inputTargets);
1196
1197 // Done.
1198Failed:
1199Unresponsive:
1200 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1201 updateDispatchStatisticsLocked(currentTime, entry,
1202 injectionResult, timeSpentWaitingForApplication);
1203#if DEBUG_FOCUS
1204 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1205 "timeSpentWaitingForApplication=%0.1fms",
1206 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1207#endif
1208 return injectionResult;
1209}
1210
1211int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1212 const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
1213 bool* outConflictingPointerActions) {
1214 enum InjectionPermission {
1215 INJECTION_PERMISSION_UNKNOWN,
1216 INJECTION_PERMISSION_GRANTED,
1217 INJECTION_PERMISSION_DENIED
1218 };
1219
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 // For security reasons, we defer updating the touch state until we are sure that
1221 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001222 int32_t displayId = entry->displayId;
1223 int32_t action = entry->action;
1224 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1225
1226 // Update the touch state as needed based on the properties of the touch event.
1227 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1228 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1229 sp<InputWindowHandle> newHoverWindowHandle;
1230
Jeff Brownf086ddb2014-02-11 14:28:48 -08001231 // Copy current touch state into mTempTouchState.
1232 // This state is always reset at the end of this function, so if we don't find state
1233 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001234 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001235 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1236 if (oldStateIndex >= 0) {
1237 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1238 mTempTouchState.copyFrom(*oldState);
1239 }
1240
1241 bool isSplit = mTempTouchState.split;
1242 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1243 && (mTempTouchState.deviceId != entry->deviceId
1244 || mTempTouchState.source != entry->source
1245 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001246 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1247 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1248 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1249 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1250 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1251 || isHoverAction);
1252 bool wrongDevice = false;
1253 if (newGesture) {
1254 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001255 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256#if DEBUG_FOCUS
1257 ALOGD("Dropping event because a pointer for a different device is already down.");
1258#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001259 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1261 switchedDevice = false;
1262 wrongDevice = true;
1263 goto Failed;
1264 }
1265 mTempTouchState.reset();
1266 mTempTouchState.down = down;
1267 mTempTouchState.deviceId = entry->deviceId;
1268 mTempTouchState.source = entry->source;
1269 mTempTouchState.displayId = displayId;
1270 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001271 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1272#if DEBUG_FOCUS
1273 ALOGI("Dropping move event because a pointer for a different device is already active.");
1274#endif
1275 // TODO: test multiple simultaneous input streams.
1276 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1277 switchedDevice = false;
1278 wrongDevice = true;
1279 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001280 }
1281
1282 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1283 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1284
1285 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1286 int32_t x = int32_t(entry->pointerCoords[pointerIndex].
1287 getAxisValue(AMOTION_EVENT_AXIS_X));
1288 int32_t y = int32_t(entry->pointerCoords[pointerIndex].
1289 getAxisValue(AMOTION_EVENT_AXIS_Y));
1290 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 bool isTouchModal = false;
1292
1293 // Traverse windows from front to back to find touched window and outside targets.
Arthur Hungb92218b2018-08-14 12:00:21 +08001294 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1295 size_t numWindows = windowHandles.size();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001296 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001297 sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298 const InputWindowInfo* windowInfo = windowHandle->getInfo();
1299 if (windowInfo->displayId != displayId) {
1300 continue; // wrong display
1301 }
1302
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 int32_t flags = windowInfo->layoutParamsFlags;
1304 if (windowInfo->visible) {
1305 if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
1306 isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
1307 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
1308 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Jeff Browndc5992e2014-04-11 01:27:26 -07001309 newTouchedWindowHandle = windowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001310 break; // found touched window, exit window loop
1311 }
1312 }
1313
1314 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1315 && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001316 mTempTouchState.addOrUpdateWindow(
Michael Wright3b106102017-01-16 21:05:07 +00001317 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001318 }
1319 }
1320 }
1321
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001323 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001324 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1325 // New window supports splitting.
1326 isSplit = true;
1327 } else if (isSplit) {
1328 // New window does not support splitting but we have already split events.
1329 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001330 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331 }
1332
1333 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001334 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001335 // Try to assign the pointer to the first foreground window we find, if there is one.
1336 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Yi Kong9b14ac62018-07-17 13:48:38 -07001337 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001338 ALOGI("Dropping event because there is no touchable window at (%d, %d).", x, y);
1339 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1340 goto Failed;
1341 }
1342 }
1343
1344 // Set target flags.
1345 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1346 if (isSplit) {
1347 targetFlags |= InputTarget::FLAG_SPLIT;
1348 }
1349 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1350 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001351 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1352 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001353 }
1354
1355 // Update hover state.
1356 if (isHoverAction) {
1357 newHoverWindowHandle = newTouchedWindowHandle;
1358 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1359 newHoverWindowHandle = mLastHoverWindowHandle;
1360 }
1361
1362 // Update the temporary touch state.
1363 BitSet32 pointerIds;
1364 if (isSplit) {
1365 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1366 pointerIds.markBit(pointerId);
1367 }
1368 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1369 } else {
1370 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1371
1372 // If the pointer is not currently down, then ignore the event.
1373 if (! mTempTouchState.down) {
1374#if DEBUG_FOCUS
1375 ALOGD("Dropping event because the pointer is not down or we previously "
1376 "dropped the pointer down event.");
1377#endif
1378 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1379 goto Failed;
1380 }
1381
1382 // Check whether touches should slip outside of the current foreground window.
1383 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1384 && entry->pointerCount == 1
1385 && mTempTouchState.isSlippery()) {
1386 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1387 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1388
1389 sp<InputWindowHandle> oldTouchedWindowHandle =
1390 mTempTouchState.getFirstForegroundWindowHandle();
1391 sp<InputWindowHandle> newTouchedWindowHandle =
1392 findTouchedWindowAtLocked(displayId, x, y);
1393 if (oldTouchedWindowHandle != newTouchedWindowHandle
Yi Kong9b14ac62018-07-17 13:48:38 -07001394 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395#if DEBUG_FOCUS
1396 ALOGD("Touch is slipping out of window %s into window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001397 oldTouchedWindowHandle->getName().c_str(),
1398 newTouchedWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001399#endif
1400 // Make a slippery exit from the old window.
1401 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1402 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1403
1404 // Make a slippery entrance into the new window.
1405 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1406 isSplit = true;
1407 }
1408
1409 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1410 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1411 if (isSplit) {
1412 targetFlags |= InputTarget::FLAG_SPLIT;
1413 }
1414 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1415 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1416 }
1417
1418 BitSet32 pointerIds;
1419 if (isSplit) {
1420 pointerIds.markBit(entry->pointerProperties[0].id);
1421 }
1422 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1423 }
1424 }
1425 }
1426
1427 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1428 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001429 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001430#if DEBUG_HOVER
1431 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001432 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001433#endif
1434 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1435 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1436 }
1437
1438 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001439 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001440#if DEBUG_HOVER
1441 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001442 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001443#endif
1444 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1445 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1446 }
1447 }
1448
1449 // Check permission to inject into all touched foreground windows and ensure there
1450 // is at least one touched foreground window.
1451 {
1452 bool haveForegroundWindow = false;
1453 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1454 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1455 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1456 haveForegroundWindow = true;
1457 if (! checkInjectionPermission(touchedWindow.windowHandle,
1458 entry->injectionState)) {
1459 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1460 injectionPermission = INJECTION_PERMISSION_DENIED;
1461 goto Failed;
1462 }
1463 }
1464 }
1465 if (! haveForegroundWindow) {
1466#if DEBUG_FOCUS
1467 ALOGD("Dropping event because there is no touched foreground window to receive it.");
1468#endif
1469 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1470 goto Failed;
1471 }
1472
1473 // Permission granted to injection into all touched foreground windows.
1474 injectionPermission = INJECTION_PERMISSION_GRANTED;
1475 }
1476
1477 // Check whether windows listening for outside touches are owned by the same UID. If it is
1478 // set the policy flag that we will not reveal coordinate information to this window.
1479 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1480 sp<InputWindowHandle> foregroundWindowHandle =
1481 mTempTouchState.getFirstForegroundWindowHandle();
1482 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1483 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1484 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1485 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1486 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1487 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1488 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1489 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1490 }
1491 }
1492 }
1493 }
1494
1495 // Ensure all touched foreground windows are ready for new input.
1496 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1497 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1498 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001499 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001500 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001501 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001502 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001504 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001505 goto Unresponsive;
1506 }
1507 }
1508 }
1509
1510 // If this is the first pointer going down and the touched window has a wallpaper
1511 // then also add the touched wallpaper windows so they are locked in for the duration
1512 // of the touch gesture.
1513 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1514 // engine only supports touch events. We would need to add a mechanism similar
1515 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1516 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1517 sp<InputWindowHandle> foregroundWindowHandle =
1518 mTempTouchState.getFirstForegroundWindowHandle();
1519 if (foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001520 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1521 size_t numWindows = windowHandles.size();
1522 for (size_t i = 0; i < numWindows; i++) {
1523 sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524 const InputWindowInfo* info = windowHandle->getInfo();
1525 if (info->displayId == displayId
1526 && windowHandle->getInfo()->layoutParamsType
1527 == InputWindowInfo::TYPE_WALLPAPER) {
1528 mTempTouchState.addOrUpdateWindow(windowHandle,
1529 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001530 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001531 | InputTarget::FLAG_DISPATCH_AS_IS,
1532 BitSet32(0));
1533 }
1534 }
1535 }
1536 }
1537
1538 // Success! Output targets.
1539 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1540
1541 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1542 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1543 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1544 touchedWindow.pointerIds, inputTargets);
1545 }
1546
1547 // Drop the outside or hover touch windows since we will not care about them
1548 // in the next iteration.
1549 mTempTouchState.filterNonAsIsTouchWindows();
1550
1551Failed:
1552 // Check injection permission once and for all.
1553 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001554 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001555 injectionPermission = INJECTION_PERMISSION_GRANTED;
1556 } else {
1557 injectionPermission = INJECTION_PERMISSION_DENIED;
1558 }
1559 }
1560
1561 // Update final pieces of touch state if the injector had permission.
1562 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1563 if (!wrongDevice) {
1564 if (switchedDevice) {
1565#if DEBUG_FOCUS
1566 ALOGD("Conflicting pointer actions: Switched to a different device.");
1567#endif
1568 *outConflictingPointerActions = true;
1569 }
1570
1571 if (isHoverAction) {
1572 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001573 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001574#if DEBUG_FOCUS
1575 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1576#endif
1577 *outConflictingPointerActions = true;
1578 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001579 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001580 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1581 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001582 mTempTouchState.deviceId = entry->deviceId;
1583 mTempTouchState.source = entry->source;
1584 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001585 }
1586 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1587 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1588 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001589 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1591 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001592 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001593#if DEBUG_FOCUS
1594 ALOGD("Conflicting pointer actions: Down received while already down.");
1595#endif
1596 *outConflictingPointerActions = true;
1597 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001598 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1599 // One pointer went up.
1600 if (isSplit) {
1601 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1602 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1603
1604 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1605 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1606 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1607 touchedWindow.pointerIds.clearBit(pointerId);
1608 if (touchedWindow.pointerIds.isEmpty()) {
1609 mTempTouchState.windows.removeAt(i);
1610 continue;
1611 }
1612 }
1613 i += 1;
1614 }
1615 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001616 }
1617
1618 // Save changes unless the action was scroll in which case the temporary touch
1619 // state was only valid for this one action.
1620 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1621 if (mTempTouchState.displayId >= 0) {
1622 if (oldStateIndex >= 0) {
1623 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1624 } else {
1625 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1626 }
1627 } else if (oldStateIndex >= 0) {
1628 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1629 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001630 }
1631
1632 // Update hover state.
1633 mLastHoverWindowHandle = newHoverWindowHandle;
1634 }
1635 } else {
1636#if DEBUG_FOCUS
1637 ALOGD("Not updating touch focus because injection was denied.");
1638#endif
1639 }
1640
1641Unresponsive:
1642 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1643 mTempTouchState.reset();
1644
1645 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1646 updateDispatchStatisticsLocked(currentTime, entry,
1647 injectionResult, timeSpentWaitingForApplication);
1648#if DEBUG_FOCUS
1649 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1650 "timeSpentWaitingForApplication=%0.1fms",
1651 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1652#endif
1653 return injectionResult;
1654}
1655
1656void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
1657 int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
1658 inputTargets.push();
1659
1660 const InputWindowInfo* windowInfo = windowHandle->getInfo();
1661 InputTarget& target = inputTargets.editTop();
1662 target.inputChannel = windowInfo->inputChannel;
1663 target.flags = targetFlags;
1664 target.xOffset = - windowInfo->frameLeft;
1665 target.yOffset = - windowInfo->frameTop;
1666 target.scaleFactor = windowInfo->scaleFactor;
1667 target.pointerIds = pointerIds;
1668}
1669
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001670void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets,
1671 int32_t displayId) {
1672 std::unordered_map<int32_t, Vector<sp<InputChannel>>>::const_iterator it =
1673 mMonitoringChannelsByDisplay.find(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001675 if (it != mMonitoringChannelsByDisplay.end()) {
1676 const Vector<sp<InputChannel>>& monitoringChannels = it->second;
1677 const size_t numChannels = monitoringChannels.size();
1678 for (size_t i = 0; i < numChannels; i++) {
1679 inputTargets.push();
1680
1681 InputTarget& target = inputTargets.editTop();
1682 target.inputChannel = monitoringChannels[i];
1683 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1684 target.xOffset = 0;
1685 target.yOffset = 0;
1686 target.pointerIds.clear();
1687 target.scaleFactor = 1.0f;
1688 }
1689 } else {
1690 // If there is no monitor channel registered or all monitor channel unregistered,
1691 // the display can't detect the extra system gesture by a copy of input events.
1692 ALOGW("There is no monitor channel found in display=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001693 }
1694}
1695
1696bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1697 const InjectionState* injectionState) {
1698 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001699 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001700 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1701 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001702 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001703 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1704 "owned by uid %d",
1705 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001706 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001707 windowHandle->getInfo()->ownerUid);
1708 } else {
1709 ALOGW("Permission denied: injecting event from pid %d uid %d",
1710 injectionState->injectorPid, injectionState->injectorUid);
1711 }
1712 return false;
1713 }
1714 return true;
1715}
1716
1717bool InputDispatcher::isWindowObscuredAtPointLocked(
1718 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1719 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hungb92218b2018-08-14 12:00:21 +08001720 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1721 size_t numWindows = windowHandles.size();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001722 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001723 sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724 if (otherHandle == windowHandle) {
1725 break;
1726 }
1727
1728 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1729 if (otherInfo->displayId == displayId
1730 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1731 && otherInfo->frameContainsPoint(x, y)) {
1732 return true;
1733 }
1734 }
1735 return false;
1736}
1737
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001738
1739bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1740 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hungb92218b2018-08-14 12:00:21 +08001741 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001742 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hungb92218b2018-08-14 12:00:21 +08001743 size_t numWindows = windowHandles.size();
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001744 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001745 sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001746 if (otherHandle == windowHandle) {
1747 break;
1748 }
1749
1750 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1751 if (otherInfo->displayId == displayId
1752 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1753 && otherInfo->overlaps(windowInfo)) {
1754 return true;
1755 }
1756 }
1757 return false;
1758}
1759
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001760std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001761 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1762 const char* targetType) {
1763 // If the window is paused then keep waiting.
1764 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001765 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001766 }
1767
1768 // If the window's connection is not registered then keep waiting.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001769 ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
Jeff Brownffb49772014-10-10 19:01:34 -07001770 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001771 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001772 "registered with the input dispatcher. The window may be in the process "
1773 "of being removed.", targetType);
1774 }
1775
1776 // If the connection is dead then keep waiting.
1777 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1778 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001779 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001780 "The window may be in the process of being removed.", targetType,
1781 connection->getStatusLabel());
1782 }
1783
1784 // If the connection is backed up then keep waiting.
1785 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001786 return StringPrintf("Waiting because the %s window's input channel is full. "
Jeff Brownffb49772014-10-10 19:01:34 -07001787 "Outbound queue length: %d. Wait queue length: %d.",
1788 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
1789 }
1790
1791 // Ensure that the dispatch queues aren't too far backed up for this event.
1792 if (eventEntry->type == EventEntry::TYPE_KEY) {
1793 // If the event is a key event, then we must wait for all previous events to
1794 // complete before delivering it because previous events may have the
1795 // side-effect of transferring focus to a different window and we want to
1796 // ensure that the following keys are sent to the new window.
1797 //
1798 // Suppose the user touches a button in a window then immediately presses "A".
1799 // If the button causes a pop-up window to appear then we want to ensure that
1800 // the "A" key is delivered to the new pop-up window. This is because users
1801 // often anticipate pending UI changes when typing on a keyboard.
1802 // To obtain this behavior, we must serialize key events with respect to all
1803 // prior input events.
1804 if (!connection->outboundQueue.isEmpty() || !connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001805 return StringPrintf("Waiting to send key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001806 "finished processing all of the input events that were previously "
1807 "delivered to it. Outbound queue length: %d. Wait queue length: %d.",
1808 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001809 }
Jeff Brownffb49772014-10-10 19:01:34 -07001810 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811 // Touch events can always be sent to a window immediately because the user intended
1812 // to touch whatever was visible at the time. Even if focus changes or a new
1813 // window appears moments later, the touch event was meant to be delivered to
1814 // whatever window happened to be on screen at the time.
1815 //
1816 // Generic motion events, such as trackball or joystick events are a little trickier.
1817 // Like key events, generic motion events are delivered to the focused window.
1818 // Unlike key events, generic motion events don't tend to transfer focus to other
1819 // windows and it is not important for them to be serialized. So we prefer to deliver
1820 // generic motion events as soon as possible to improve efficiency and reduce lag
1821 // through batching.
1822 //
1823 // The one case where we pause input event delivery is when the wait queue is piling
1824 // up with lots of events because the application is not responding.
1825 // This condition ensures that ANRs are detected reliably.
1826 if (!connection->waitQueue.isEmpty()
1827 && currentTime >= connection->waitQueue.head->deliveryTime
1828 + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001829 return StringPrintf("Waiting to send non-key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001830 "finished processing certain input events that were delivered to it over "
1831 "%0.1fms ago. Wait queue length: %d. Wait queue head age: %0.1fms.",
1832 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1833 connection->waitQueue.count(),
1834 (currentTime - connection->waitQueue.head->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835 }
1836 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001837 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001838}
1839
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001840std::string InputDispatcher::getApplicationWindowLabelLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001841 const sp<InputApplicationHandle>& applicationHandle,
1842 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001843 if (applicationHandle != nullptr) {
1844 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001845 std::string label(applicationHandle->getName());
1846 label += " - ";
1847 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001848 return label;
1849 } else {
1850 return applicationHandle->getName();
1851 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001852 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001853 return windowHandle->getName();
1854 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001855 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001856 }
1857}
1858
1859void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001860 int32_t displayId = getTargetDisplayId(eventEntry);
1861 sp<InputWindowHandle> focusedWindowHandle =
1862 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1863 if (focusedWindowHandle != nullptr) {
1864 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001865 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1866#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001867 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001868#endif
1869 return;
1870 }
1871 }
1872
1873 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1874 switch (eventEntry->type) {
1875 case EventEntry::TYPE_MOTION: {
1876 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1877 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1878 return;
1879 }
1880
1881 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1882 eventType = USER_ACTIVITY_EVENT_TOUCH;
1883 }
1884 break;
1885 }
1886 case EventEntry::TYPE_KEY: {
1887 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1888 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1889 return;
1890 }
1891 eventType = USER_ACTIVITY_EVENT_BUTTON;
1892 break;
1893 }
1894 }
1895
1896 CommandEntry* commandEntry = postCommandLocked(
1897 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1898 commandEntry->eventTime = eventEntry->eventTime;
1899 commandEntry->userActivityEventType = eventType;
1900}
1901
1902void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1903 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1904#if DEBUG_DISPATCH_CYCLE
1905 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
1906 "xOffset=%f, yOffset=%f, scaleFactor=%f, "
1907 "pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001908 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 inputTarget->xOffset, inputTarget->yOffset,
1910 inputTarget->scaleFactor, inputTarget->pointerIds.value);
1911#endif
1912
1913 // Skip this event if the connection status is not normal.
1914 // We don't want to enqueue additional outbound events if the connection is broken.
1915 if (connection->status != Connection::STATUS_NORMAL) {
1916#if DEBUG_DISPATCH_CYCLE
1917 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001918 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001919#endif
1920 return;
1921 }
1922
1923 // Split a motion event if needed.
1924 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
1925 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
1926
1927 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1928 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1929 MotionEntry* splitMotionEntry = splitMotionEvent(
1930 originalMotionEntry, inputTarget->pointerIds);
1931 if (!splitMotionEntry) {
1932 return; // split event was dropped
1933 }
1934#if DEBUG_FOCUS
1935 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001936 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1938#endif
1939 enqueueDispatchEntriesLocked(currentTime, connection,
1940 splitMotionEntry, inputTarget);
1941 splitMotionEntry->release();
1942 return;
1943 }
1944 }
1945
1946 // Not splitting. Enqueue dispatch entries for the event as is.
1947 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
1948}
1949
1950void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
1951 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1952 bool wasEmpty = connection->outboundQueue.isEmpty();
1953
1954 // Enqueue dispatch entries for the requested modes.
1955 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1956 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
1957 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1958 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
1959 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1960 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
1961 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1962 InputTarget::FLAG_DISPATCH_AS_IS);
1963 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1964 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
1965 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1966 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
1967
1968 // If the outbound queue was previously empty, start the dispatch cycle going.
1969 if (wasEmpty && !connection->outboundQueue.isEmpty()) {
1970 startDispatchCycleLocked(currentTime, connection);
1971 }
1972}
1973
1974void InputDispatcher::enqueueDispatchEntryLocked(
1975 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
1976 int32_t dispatchMode) {
1977 int32_t inputTargetFlags = inputTarget->flags;
1978 if (!(inputTargetFlags & dispatchMode)) {
1979 return;
1980 }
1981 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
1982
1983 // This is a new event.
1984 // Enqueue a new dispatch entry onto the outbound queue for this connection.
1985 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
1986 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
1987 inputTarget->scaleFactor);
1988
1989 // Apply target flags and update the connection's input state.
1990 switch (eventEntry->type) {
1991 case EventEntry::TYPE_KEY: {
1992 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
1993 dispatchEntry->resolvedAction = keyEntry->action;
1994 dispatchEntry->resolvedFlags = keyEntry->flags;
1995
1996 if (!connection->inputState.trackKey(keyEntry,
1997 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
1998#if DEBUG_DISPATCH_CYCLE
1999 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002000 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001#endif
2002 delete dispatchEntry;
2003 return; // skip the inconsistent event
2004 }
2005 break;
2006 }
2007
2008 case EventEntry::TYPE_MOTION: {
2009 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2010 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2011 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2012 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2013 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2014 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2015 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2016 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2017 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2018 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2019 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2020 } else {
2021 dispatchEntry->resolvedAction = motionEntry->action;
2022 }
2023 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2024 && !connection->inputState.isHovering(
2025 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2026#if DEBUG_DISPATCH_CYCLE
2027 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002028 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002029#endif
2030 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2031 }
2032
2033 dispatchEntry->resolvedFlags = motionEntry->flags;
2034 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2035 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2036 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002037 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2038 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002040
2041 if (!connection->inputState.trackMotion(motionEntry,
2042 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2043#if DEBUG_DISPATCH_CYCLE
2044 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002045 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002046#endif
2047 delete dispatchEntry;
2048 return; // skip the inconsistent event
2049 }
2050 break;
2051 }
2052 }
2053
2054 // Remember that we are waiting for this dispatch to complete.
2055 if (dispatchEntry->hasForegroundTarget()) {
2056 incrementPendingForegroundDispatchesLocked(eventEntry);
2057 }
2058
2059 // Enqueue the dispatch entry.
2060 connection->outboundQueue.enqueueAtTail(dispatchEntry);
2061 traceOutboundQueueLengthLocked(connection);
2062}
2063
2064void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2065 const sp<Connection>& connection) {
2066#if DEBUG_DISPATCH_CYCLE
2067 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002068 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069#endif
2070
2071 while (connection->status == Connection::STATUS_NORMAL
2072 && !connection->outboundQueue.isEmpty()) {
2073 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
2074 dispatchEntry->deliveryTime = currentTime;
2075
2076 // Publish the event.
2077 status_t status;
2078 EventEntry* eventEntry = dispatchEntry->eventEntry;
2079 switch (eventEntry->type) {
2080 case EventEntry::TYPE_KEY: {
2081 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2082
2083 // Publish the key event.
2084 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002085 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2087 keyEntry->keyCode, keyEntry->scanCode,
2088 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2089 keyEntry->eventTime);
2090 break;
2091 }
2092
2093 case EventEntry::TYPE_MOTION: {
2094 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2095
2096 PointerCoords scaledCoords[MAX_POINTERS];
2097 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2098
2099 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002100 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002101 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2102 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002103 float scaleFactor = dispatchEntry->scaleFactor;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002104 xOffset = dispatchEntry->xOffset * scaleFactor;
2105 yOffset = dispatchEntry->yOffset * scaleFactor;
2106 if (scaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002107 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002108 scaledCoords[i] = motionEntry->pointerCoords[i];
2109 scaledCoords[i].scale(scaleFactor);
2110 }
2111 usingCoords = scaledCoords;
2112 }
2113 } else {
2114 xOffset = 0.0f;
2115 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002116
2117 // We don't want the dispatch target to know.
2118 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002119 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002120 scaledCoords[i].clear();
2121 }
2122 usingCoords = scaledCoords;
2123 }
2124 }
2125
2126 // Publish the motion event.
2127 status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
Tarandeep Singh58641502017-07-31 10:51:54 -07002128 motionEntry->deviceId, motionEntry->source, motionEntry->displayId,
Michael Wright7b159c92015-05-14 14:48:03 +01002129 dispatchEntry->resolvedAction, motionEntry->actionButton,
2130 dispatchEntry->resolvedFlags, motionEntry->edgeFlags,
2131 motionEntry->metaState, motionEntry->buttonState,
2132 xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133 motionEntry->downTime, motionEntry->eventTime,
2134 motionEntry->pointerCount, motionEntry->pointerProperties,
2135 usingCoords);
2136 break;
2137 }
2138
2139 default:
2140 ALOG_ASSERT(false);
2141 return;
2142 }
2143
2144 // Check the result.
2145 if (status) {
2146 if (status == WOULD_BLOCK) {
2147 if (connection->waitQueue.isEmpty()) {
2148 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2149 "This is unexpected because the wait queue is empty, so the pipe "
2150 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002151 "event to it, status=%d", connection->getInputChannelName().c_str(),
2152 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2154 } else {
2155 // Pipe is full and we are waiting for the app to finish process some events
2156 // before sending more events to it.
2157#if DEBUG_DISPATCH_CYCLE
2158 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2159 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002160 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161#endif
2162 connection->inputPublisherBlocked = true;
2163 }
2164 } else {
2165 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002166 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002167 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2168 }
2169 return;
2170 }
2171
2172 // Re-enqueue the event on the wait queue.
2173 connection->outboundQueue.dequeue(dispatchEntry);
2174 traceOutboundQueueLengthLocked(connection);
2175 connection->waitQueue.enqueueAtTail(dispatchEntry);
2176 traceWaitQueueLengthLocked(connection);
2177 }
2178}
2179
2180void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2181 const sp<Connection>& connection, uint32_t seq, bool handled) {
2182#if DEBUG_DISPATCH_CYCLE
2183 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002184 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002185#endif
2186
2187 connection->inputPublisherBlocked = false;
2188
2189 if (connection->status == Connection::STATUS_BROKEN
2190 || connection->status == Connection::STATUS_ZOMBIE) {
2191 return;
2192 }
2193
2194 // Notify other system components and prepare to start the next dispatch cycle.
2195 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2196}
2197
2198void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2199 const sp<Connection>& connection, bool notify) {
2200#if DEBUG_DISPATCH_CYCLE
2201 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002202 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002203#endif
2204
2205 // Clear the dispatch queues.
2206 drainDispatchQueueLocked(&connection->outboundQueue);
2207 traceOutboundQueueLengthLocked(connection);
2208 drainDispatchQueueLocked(&connection->waitQueue);
2209 traceWaitQueueLengthLocked(connection);
2210
2211 // The connection appears to be unrecoverably broken.
2212 // Ignore already broken or zombie connections.
2213 if (connection->status == Connection::STATUS_NORMAL) {
2214 connection->status = Connection::STATUS_BROKEN;
2215
2216 if (notify) {
2217 // Notify other system components.
2218 onDispatchCycleBrokenLocked(currentTime, connection);
2219 }
2220 }
2221}
2222
2223void InputDispatcher::drainDispatchQueueLocked(Queue<DispatchEntry>* queue) {
2224 while (!queue->isEmpty()) {
2225 DispatchEntry* dispatchEntry = queue->dequeueAtHead();
2226 releaseDispatchEntryLocked(dispatchEntry);
2227 }
2228}
2229
2230void InputDispatcher::releaseDispatchEntryLocked(DispatchEntry* dispatchEntry) {
2231 if (dispatchEntry->hasForegroundTarget()) {
2232 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
2233 }
2234 delete dispatchEntry;
2235}
2236
2237int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2238 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2239
2240 { // acquire lock
2241 AutoMutex _l(d->mLock);
2242
2243 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2244 if (connectionIndex < 0) {
2245 ALOGE("Received spurious receive callback for unknown input channel. "
2246 "fd=%d, events=0x%x", fd, events);
2247 return 0; // remove the callback
2248 }
2249
2250 bool notify;
2251 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2252 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2253 if (!(events & ALOOPER_EVENT_INPUT)) {
2254 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002255 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002256 return 1;
2257 }
2258
2259 nsecs_t currentTime = now();
2260 bool gotOne = false;
2261 status_t status;
2262 for (;;) {
2263 uint32_t seq;
2264 bool handled;
2265 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2266 if (status) {
2267 break;
2268 }
2269 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2270 gotOne = true;
2271 }
2272 if (gotOne) {
2273 d->runCommandsLockedInterruptible();
2274 if (status == WOULD_BLOCK) {
2275 return 1;
2276 }
2277 }
2278
2279 notify = status != DEAD_OBJECT || !connection->monitor;
2280 if (notify) {
2281 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002282 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002283 }
2284 } else {
2285 // Monitor channels are never explicitly unregistered.
2286 // We do it automatically when the remote endpoint is closed so don't warn
2287 // about them.
2288 notify = !connection->monitor;
2289 if (notify) {
2290 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002291 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002292 }
2293 }
2294
2295 // Unregister the channel.
2296 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2297 return 0; // remove the callback
2298 } // release lock
2299}
2300
2301void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2302 const CancelationOptions& options) {
2303 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2304 synthesizeCancelationEventsForConnectionLocked(
2305 mConnectionsByFd.valueAt(i), options);
2306 }
2307}
2308
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002309void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2310 const CancelationOptions& options) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002311 for (auto& it : mMonitoringChannelsByDisplay) {
2312 const Vector<sp<InputChannel>>& monitoringChannels = it.second;
2313 const size_t numChannels = monitoringChannels.size();
2314 for (size_t i = 0; i < numChannels; i++) {
2315 synthesizeCancelationEventsForInputChannelLocked(monitoringChannels[i], options);
2316 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002317 }
2318}
2319
Michael Wrightd02c5b62014-02-10 15:10:22 -08002320void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2321 const sp<InputChannel>& channel, const CancelationOptions& options) {
2322 ssize_t index = getConnectionIndexLocked(channel);
2323 if (index >= 0) {
2324 synthesizeCancelationEventsForConnectionLocked(
2325 mConnectionsByFd.valueAt(index), options);
2326 }
2327}
2328
2329void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2330 const sp<Connection>& connection, const CancelationOptions& options) {
2331 if (connection->status == Connection::STATUS_BROKEN) {
2332 return;
2333 }
2334
2335 nsecs_t currentTime = now();
2336
2337 Vector<EventEntry*> cancelationEvents;
2338 connection->inputState.synthesizeCancelationEvents(currentTime,
2339 cancelationEvents, options);
2340
2341 if (!cancelationEvents.isEmpty()) {
2342#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002343 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002345 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002346 options.reason, options.mode);
2347#endif
2348 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2349 EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
2350 switch (cancelationEventEntry->type) {
2351 case EventEntry::TYPE_KEY:
2352 logOutboundKeyDetailsLocked("cancel - ",
2353 static_cast<KeyEntry*>(cancelationEventEntry));
2354 break;
2355 case EventEntry::TYPE_MOTION:
2356 logOutboundMotionDetailsLocked("cancel - ",
2357 static_cast<MotionEntry*>(cancelationEventEntry));
2358 break;
2359 }
2360
2361 InputTarget target;
2362 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
Yi Kong9b14ac62018-07-17 13:48:38 -07002363 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002364 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2365 target.xOffset = -windowInfo->frameLeft;
2366 target.yOffset = -windowInfo->frameTop;
2367 target.scaleFactor = windowInfo->scaleFactor;
2368 } else {
2369 target.xOffset = 0;
2370 target.yOffset = 0;
2371 target.scaleFactor = 1.0f;
2372 }
2373 target.inputChannel = connection->inputChannel;
2374 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2375
2376 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2377 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2378
2379 cancelationEventEntry->release();
2380 }
2381
2382 startDispatchCycleLocked(currentTime, connection);
2383 }
2384}
2385
2386InputDispatcher::MotionEntry*
2387InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2388 ALOG_ASSERT(pointerIds.value != 0);
2389
2390 uint32_t splitPointerIndexMap[MAX_POINTERS];
2391 PointerProperties splitPointerProperties[MAX_POINTERS];
2392 PointerCoords splitPointerCoords[MAX_POINTERS];
2393
2394 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2395 uint32_t splitPointerCount = 0;
2396
2397 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2398 originalPointerIndex++) {
2399 const PointerProperties& pointerProperties =
2400 originalMotionEntry->pointerProperties[originalPointerIndex];
2401 uint32_t pointerId = uint32_t(pointerProperties.id);
2402 if (pointerIds.hasBit(pointerId)) {
2403 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2404 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2405 splitPointerCoords[splitPointerCount].copyFrom(
2406 originalMotionEntry->pointerCoords[originalPointerIndex]);
2407 splitPointerCount += 1;
2408 }
2409 }
2410
2411 if (splitPointerCount != pointerIds.count()) {
2412 // This is bad. We are missing some of the pointers that we expected to deliver.
2413 // Most likely this indicates that we received an ACTION_MOVE events that has
2414 // different pointer ids than we expected based on the previous ACTION_DOWN
2415 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2416 // in this way.
2417 ALOGW("Dropping split motion event because the pointer count is %d but "
2418 "we expected there to be %d pointers. This probably means we received "
2419 "a broken sequence of pointer ids from the input device.",
2420 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002421 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 }
2423
2424 int32_t action = originalMotionEntry->action;
2425 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2426 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2427 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2428 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2429 const PointerProperties& pointerProperties =
2430 originalMotionEntry->pointerProperties[originalPointerIndex];
2431 uint32_t pointerId = uint32_t(pointerProperties.id);
2432 if (pointerIds.hasBit(pointerId)) {
2433 if (pointerIds.count() == 1) {
2434 // The first/last pointer went down/up.
2435 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2436 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2437 } else {
2438 // A secondary pointer went down/up.
2439 uint32_t splitPointerIndex = 0;
2440 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2441 splitPointerIndex += 1;
2442 }
2443 action = maskedAction | (splitPointerIndex
2444 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2445 }
2446 } else {
2447 // An unrelated pointer changed.
2448 action = AMOTION_EVENT_ACTION_MOVE;
2449 }
2450 }
2451
2452 MotionEntry* splitMotionEntry = new MotionEntry(
2453 originalMotionEntry->eventTime,
2454 originalMotionEntry->deviceId,
2455 originalMotionEntry->source,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002456 originalMotionEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002457 originalMotionEntry->policyFlags,
2458 action,
Michael Wright7b159c92015-05-14 14:48:03 +01002459 originalMotionEntry->actionButton,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002460 originalMotionEntry->flags,
2461 originalMotionEntry->metaState,
2462 originalMotionEntry->buttonState,
2463 originalMotionEntry->edgeFlags,
2464 originalMotionEntry->xPrecision,
2465 originalMotionEntry->yPrecision,
2466 originalMotionEntry->downTime,
Jeff Brownf086ddb2014-02-11 14:28:48 -08002467 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002468
2469 if (originalMotionEntry->injectionState) {
2470 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2471 splitMotionEntry->injectionState->refCount += 1;
2472 }
2473
2474 return splitMotionEntry;
2475}
2476
2477void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2478#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002479 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002480#endif
2481
2482 bool needWake;
2483 { // acquire lock
2484 AutoMutex _l(mLock);
2485
2486 ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
2487 needWake = enqueueInboundEventLocked(newEntry);
2488 } // release lock
2489
2490 if (needWake) {
2491 mLooper->wake();
2492 }
2493}
2494
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002495/**
2496 * If one of the meta shortcuts is detected, process them here:
2497 * Meta + Backspace -> generate BACK
2498 * Meta + Enter -> generate HOME
2499 * This will potentially overwrite keyCode and metaState.
2500 */
2501void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2502 int32_t& keyCode, int32_t& metaState) {
2503 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2504 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2505 if (keyCode == AKEYCODE_DEL) {
2506 newKeyCode = AKEYCODE_BACK;
2507 } else if (keyCode == AKEYCODE_ENTER) {
2508 newKeyCode = AKEYCODE_HOME;
2509 }
2510 if (newKeyCode != AKEYCODE_UNKNOWN) {
2511 AutoMutex _l(mLock);
2512 struct KeyReplacement replacement = {keyCode, deviceId};
2513 mReplacedKeys.add(replacement, newKeyCode);
2514 keyCode = newKeyCode;
2515 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2516 }
2517 } else if (action == AKEY_EVENT_ACTION_UP) {
2518 // In order to maintain a consistent stream of up and down events, check to see if the key
2519 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2520 // even if the modifier was released between the down and the up events.
2521 AutoMutex _l(mLock);
2522 struct KeyReplacement replacement = {keyCode, deviceId};
2523 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2524 if (index >= 0) {
2525 keyCode = mReplacedKeys.valueAt(index);
2526 mReplacedKeys.removeItemsAt(index);
2527 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2528 }
2529 }
2530}
2531
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2533#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002534 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002535 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002536 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002537 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002538 args->action, args->flags, args->keyCode, args->scanCode,
2539 args->metaState, args->downTime);
2540#endif
2541 if (!validateKeyEvent(args->action)) {
2542 return;
2543 }
2544
2545 uint32_t policyFlags = args->policyFlags;
2546 int32_t flags = args->flags;
2547 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002548 // InputDispatcher tracks and generates key repeats on behalf of
2549 // whatever notifies it, so repeatCount should always be set to 0
2550 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002551 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2552 policyFlags |= POLICY_FLAG_VIRTUAL;
2553 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2554 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002555 if (policyFlags & POLICY_FLAG_FUNCTION) {
2556 metaState |= AMETA_FUNCTION_ON;
2557 }
2558
2559 policyFlags |= POLICY_FLAG_TRUSTED;
2560
Michael Wright78f24442014-08-06 15:55:28 -07002561 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002562 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002563
Michael Wrightd02c5b62014-02-10 15:10:22 -08002564 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002565 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002566 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002567 args->downTime, args->eventTime);
2568
Michael Wright2b3c3302018-03-02 17:19:13 +00002569 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002570 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002571 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2572 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2573 std::to_string(t.duration().count()).c_str());
2574 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002575
Michael Wrightd02c5b62014-02-10 15:10:22 -08002576 bool needWake;
2577 { // acquire lock
2578 mLock.lock();
2579
2580 if (shouldSendKeyToInputFilterLocked(args)) {
2581 mLock.unlock();
2582
2583 policyFlags |= POLICY_FLAG_FILTERED;
2584 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2585 return; // event was consumed by the filter
2586 }
2587
2588 mLock.lock();
2589 }
2590
Michael Wrightd02c5b62014-02-10 15:10:22 -08002591 KeyEntry* newEntry = new KeyEntry(args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002592 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002593 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002594 metaState, repeatCount, args->downTime);
2595
2596 needWake = enqueueInboundEventLocked(newEntry);
2597 mLock.unlock();
2598 } // release lock
2599
2600 if (needWake) {
2601 mLooper->wake();
2602 }
2603}
2604
2605bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2606 return mInputFilterEnabled;
2607}
2608
2609void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2610#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002611 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2612 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01002613 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x,"
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002614 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002615 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002616 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002617 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
2618 for (uint32_t i = 0; i < args->pointerCount; i++) {
2619 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2620 "x=%f, y=%f, pressure=%f, size=%f, "
2621 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2622 "orientation=%f",
2623 i, args->pointerProperties[i].id,
2624 args->pointerProperties[i].toolType,
2625 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2626 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2627 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2628 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2629 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2630 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2631 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2632 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2633 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2634 }
2635#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002636 if (!validateMotionEvent(args->action, args->actionButton,
2637 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002638 return;
2639 }
2640
2641 uint32_t policyFlags = args->policyFlags;
2642 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002643
2644 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002645 mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002646 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2647 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2648 std::to_string(t.duration().count()).c_str());
2649 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002650
2651 bool needWake;
2652 { // acquire lock
2653 mLock.lock();
2654
2655 if (shouldSendMotionToInputFilterLocked(args)) {
2656 mLock.unlock();
2657
2658 MotionEvent event;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002659 event.initialize(args->deviceId, args->source, args->displayId,
2660 args->action, args->actionButton,
Michael Wright7b159c92015-05-14 14:48:03 +01002661 args->flags, args->edgeFlags, args->metaState, args->buttonState,
2662 0, 0, args->xPrecision, args->yPrecision,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002663 args->downTime, args->eventTime,
2664 args->pointerCount, args->pointerProperties, args->pointerCoords);
2665
2666 policyFlags |= POLICY_FLAG_FILTERED;
2667 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2668 return; // event was consumed by the filter
2669 }
2670
2671 mLock.lock();
2672 }
2673
2674 // Just enqueue a new motion event.
2675 MotionEntry* newEntry = new MotionEntry(args->eventTime,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002676 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002677 args->action, args->actionButton, args->flags,
2678 args->metaState, args->buttonState,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002679 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
Jeff Brownf086ddb2014-02-11 14:28:48 -08002680 args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002681
2682 needWake = enqueueInboundEventLocked(newEntry);
2683 mLock.unlock();
2684 } // release lock
2685
2686 if (needWake) {
2687 mLooper->wake();
2688 }
2689}
2690
2691bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
2692 // TODO: support sending secondary display events to input filter
2693 return mInputFilterEnabled && isMainDisplay(args->displayId);
2694}
2695
2696void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2697#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002698 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2699 "switchMask=0x%08x",
2700 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002701#endif
2702
2703 uint32_t policyFlags = args->policyFlags;
2704 policyFlags |= POLICY_FLAG_TRUSTED;
2705 mPolicy->notifySwitch(args->eventTime,
2706 args->switchValues, args->switchMask, policyFlags);
2707}
2708
2709void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2710#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002711 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002712 args->eventTime, args->deviceId);
2713#endif
2714
2715 bool needWake;
2716 { // acquire lock
2717 AutoMutex _l(mLock);
2718
2719 DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
2720 needWake = enqueueInboundEventLocked(newEntry);
2721 } // release lock
2722
2723 if (needWake) {
2724 mLooper->wake();
2725 }
2726}
2727
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002728int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2730 uint32_t policyFlags) {
2731#if DEBUG_INBOUND_EVENT_DETAILS
2732 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002733 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2734 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735#endif
2736
2737 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2738
2739 policyFlags |= POLICY_FLAG_INJECTED;
2740 if (hasInjectionPermission(injectorPid, injectorUid)) {
2741 policyFlags |= POLICY_FLAG_TRUSTED;
2742 }
2743
2744 EventEntry* firstInjectedEntry;
2745 EventEntry* lastInjectedEntry;
2746 switch (event->getType()) {
2747 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002748 KeyEvent keyEvent;
2749 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2750 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002751 if (! validateKeyEvent(action)) {
2752 return INPUT_EVENT_INJECTION_FAILED;
2753 }
2754
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002755 int32_t flags = keyEvent.getFlags();
2756 int32_t keyCode = keyEvent.getKeyCode();
2757 int32_t metaState = keyEvent.getMetaState();
2758 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2759 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002760 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002761 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002762 keyEvent.getDownTime(), keyEvent.getEventTime());
2763
Michael Wrightd02c5b62014-02-10 15:10:22 -08002764 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2765 policyFlags |= POLICY_FLAG_VIRTUAL;
2766 }
2767
2768 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002769 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002770 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002771 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2772 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2773 std::to_string(t.duration().count()).c_str());
2774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775 }
2776
Michael Wrightd02c5b62014-02-10 15:10:22 -08002777 mLock.lock();
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002778 firstInjectedEntry = new KeyEntry(keyEvent.getEventTime(),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002779 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002780 policyFlags, action, flags,
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002781 keyEvent.getKeyCode(), keyEvent.getScanCode(), keyEvent.getMetaState(),
2782 keyEvent.getRepeatCount(), keyEvent.getDownTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002783 lastInjectedEntry = firstInjectedEntry;
2784 break;
2785 }
2786
2787 case AINPUT_EVENT_TYPE_MOTION: {
2788 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002789 int32_t action = motionEvent->getAction();
2790 size_t pointerCount = motionEvent->getPointerCount();
2791 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002792 int32_t actionButton = motionEvent->getActionButton();
2793 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794 return INPUT_EVENT_INJECTION_FAILED;
2795 }
2796
2797 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2798 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002799 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002800 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002801 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2802 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2803 std::to_string(t.duration().count()).c_str());
2804 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002805 }
2806
2807 mLock.lock();
2808 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2809 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2810 firstInjectedEntry = new MotionEntry(*sampleEventTimes,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002811 motionEvent->getDeviceId(), motionEvent->getSource(), motionEvent->getDisplayId(),
2812 policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002813 action, actionButton, motionEvent->getFlags(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814 motionEvent->getMetaState(), motionEvent->getButtonState(),
2815 motionEvent->getEdgeFlags(),
2816 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002817 motionEvent->getDownTime(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08002818 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2819 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002820 lastInjectedEntry = firstInjectedEntry;
2821 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2822 sampleEventTimes += 1;
2823 samplePointerCoords += pointerCount;
2824 MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002825 motionEvent->getDeviceId(), motionEvent->getSource(),
2826 motionEvent->getDisplayId(), policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002827 action, actionButton, motionEvent->getFlags(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828 motionEvent->getMetaState(), motionEvent->getButtonState(),
2829 motionEvent->getEdgeFlags(),
2830 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002831 motionEvent->getDownTime(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08002832 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2833 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002834 lastInjectedEntry->next = nextInjectedEntry;
2835 lastInjectedEntry = nextInjectedEntry;
2836 }
2837 break;
2838 }
2839
2840 default:
2841 ALOGW("Cannot inject event of type %d", event->getType());
2842 return INPUT_EVENT_INJECTION_FAILED;
2843 }
2844
2845 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
2846 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2847 injectionState->injectionIsAsync = true;
2848 }
2849
2850 injectionState->refCount += 1;
2851 lastInjectedEntry->injectionState = injectionState;
2852
2853 bool needWake = false;
Yi Kong9b14ac62018-07-17 13:48:38 -07002854 for (EventEntry* entry = firstInjectedEntry; entry != nullptr; ) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855 EventEntry* nextEntry = entry->next;
2856 needWake |= enqueueInboundEventLocked(entry);
2857 entry = nextEntry;
2858 }
2859
2860 mLock.unlock();
2861
2862 if (needWake) {
2863 mLooper->wake();
2864 }
2865
2866 int32_t injectionResult;
2867 { // acquire lock
2868 AutoMutex _l(mLock);
2869
2870 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2871 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2872 } else {
2873 for (;;) {
2874 injectionResult = injectionState->injectionResult;
2875 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2876 break;
2877 }
2878
2879 nsecs_t remainingTimeout = endTime - now();
2880 if (remainingTimeout <= 0) {
2881#if DEBUG_INJECTION
2882 ALOGD("injectInputEvent - Timed out waiting for injection result "
2883 "to become available.");
2884#endif
2885 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2886 break;
2887 }
2888
2889 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2890 }
2891
2892 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2893 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
2894 while (injectionState->pendingForegroundDispatches != 0) {
2895#if DEBUG_INJECTION
2896 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
2897 injectionState->pendingForegroundDispatches);
2898#endif
2899 nsecs_t remainingTimeout = endTime - now();
2900 if (remainingTimeout <= 0) {
2901#if DEBUG_INJECTION
2902 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
2903 "dispatches to finish.");
2904#endif
2905 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2906 break;
2907 }
2908
2909 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2910 }
2911 }
2912 }
2913
2914 injectionState->release();
2915 } // release lock
2916
2917#if DEBUG_INJECTION
2918 ALOGD("injectInputEvent - Finished with result %d. "
2919 "injectorPid=%d, injectorUid=%d",
2920 injectionResult, injectorPid, injectorUid);
2921#endif
2922
2923 return injectionResult;
2924}
2925
2926bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2927 return injectorUid == 0
2928 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2929}
2930
2931void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
2932 InjectionState* injectionState = entry->injectionState;
2933 if (injectionState) {
2934#if DEBUG_INJECTION
2935 ALOGD("Setting input event injection result to %d. "
2936 "injectorPid=%d, injectorUid=%d",
2937 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
2938#endif
2939
2940 if (injectionState->injectionIsAsync
2941 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
2942 // Log the outcome since the injector did not wait for the injection result.
2943 switch (injectionResult) {
2944 case INPUT_EVENT_INJECTION_SUCCEEDED:
2945 ALOGV("Asynchronous input event injection succeeded.");
2946 break;
2947 case INPUT_EVENT_INJECTION_FAILED:
2948 ALOGW("Asynchronous input event injection failed.");
2949 break;
2950 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2951 ALOGW("Asynchronous input event injection permission denied.");
2952 break;
2953 case INPUT_EVENT_INJECTION_TIMED_OUT:
2954 ALOGW("Asynchronous input event injection timed out.");
2955 break;
2956 }
2957 }
2958
2959 injectionState->injectionResult = injectionResult;
2960 mInjectionResultAvailableCondition.broadcast();
2961 }
2962}
2963
2964void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2965 InjectionState* injectionState = entry->injectionState;
2966 if (injectionState) {
2967 injectionState->pendingForegroundDispatches += 1;
2968 }
2969}
2970
2971void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2972 InjectionState* injectionState = entry->injectionState;
2973 if (injectionState) {
2974 injectionState->pendingForegroundDispatches -= 1;
2975
2976 if (injectionState->pendingForegroundDispatches == 0) {
2977 mInjectionSyncFinishedCondition.broadcast();
2978 }
2979 }
2980}
2981
Arthur Hungb92218b2018-08-14 12:00:21 +08002982Vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(int32_t displayId) const {
2983 std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>>::const_iterator it =
2984 mWindowHandlesByDisplay.find(displayId);
2985 if(it != mWindowHandlesByDisplay.end()) {
2986 return it->second;
2987 }
2988
2989 // Return an empty one if nothing found.
2990 return Vector<sp<InputWindowHandle>>();
2991}
2992
Michael Wrightd02c5b62014-02-10 15:10:22 -08002993sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
2994 const sp<InputChannel>& inputChannel) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08002995 for (auto& it : mWindowHandlesByDisplay) {
2996 const Vector<sp<InputWindowHandle>> windowHandles = it.second;
2997 size_t numWindows = windowHandles.size();
2998 for (size_t i = 0; i < numWindows; i++) {
2999 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
3000 if (windowHandle->getInputChannel() == inputChannel) {
3001 return windowHandle;
3002 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003003 }
3004 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003005 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003006}
3007
3008bool InputDispatcher::hasWindowHandleLocked(
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003009 const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003010 for (auto& it : mWindowHandlesByDisplay) {
3011 const Vector<sp<InputWindowHandle>> windowHandles = it.second;
3012 size_t numWindows = windowHandles.size();
3013 for (size_t i = 0; i < numWindows; i++) {
3014 if (windowHandles.itemAt(i) == windowHandle) {
3015 if (windowHandle->getInfo()->displayId != it.first) {
3016 ALOGE("Found window %s in display %d, but it should belong to display %d",
3017 windowHandle->getName().c_str(), it.first,
3018 windowHandle->getInfo()->displayId);
3019 }
3020 return true;
3021 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003022 }
3023 }
3024 return false;
3025}
3026
Arthur Hungb92218b2018-08-14 12:00:21 +08003027/**
3028 * Called from InputManagerService, update window handle list by displayId that can receive input.
3029 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3030 * If set an empty list, remove all handles from the specific display.
3031 * For focused handle, check if need to change and send a cancel event to previous one.
3032 * For removed handle, check if need to send a cancel event if already in touch.
3033 */
3034void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& inputWindowHandles,
3035 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003036#if DEBUG_FOCUS
3037 ALOGD("setInputWindows");
3038#endif
3039 { // acquire lock
3040 AutoMutex _l(mLock);
3041
Arthur Hungb92218b2018-08-14 12:00:21 +08003042 // Copy old handles for release if they are no longer present.
3043 const Vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003044
Tiger Huang721e26f2018-07-24 22:26:19 +08003045 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003046 bool foundHoveredWindow = false;
Arthur Hungb92218b2018-08-14 12:00:21 +08003047
3048 if (inputWindowHandles.isEmpty()) {
3049 // Remove all handles on a display if there are no windows left.
3050 mWindowHandlesByDisplay.erase(displayId);
3051 } else {
3052 size_t numWindows = inputWindowHandles.size();
3053 for (size_t i = 0; i < numWindows; i++) {
3054 const sp<InputWindowHandle>& windowHandle = inputWindowHandles.itemAt(i);
3055 if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == nullptr) {
3056 continue;
3057 }
3058
3059 if (windowHandle->getInfo()->displayId != displayId) {
3060 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3061 windowHandle->getName().c_str(), displayId,
3062 windowHandle->getInfo()->displayId);
3063 continue;
3064 }
3065
3066 if (windowHandle->getInfo()->hasFocus) {
3067 newFocusedWindowHandle = windowHandle;
3068 }
3069 if (windowHandle == mLastHoverWindowHandle) {
3070 foundHoveredWindow = true;
3071 }
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003072 }
Arthur Hungb92218b2018-08-14 12:00:21 +08003073
3074 // Insert or replace
3075 mWindowHandlesByDisplay[displayId] = inputWindowHandles;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003076 }
3077
3078 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003079 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003080 }
3081
Tiger Huang721e26f2018-07-24 22:26:19 +08003082 sp<InputWindowHandle> oldFocusedWindowHandle =
3083 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3084
3085 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3086 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003087#if DEBUG_FOCUS
3088 ALOGD("Focus left window: %s",
Tiger Huang721e26f2018-07-24 22:26:19 +08003089 oldFocusedWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003090#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003091 sp<InputChannel> focusedInputChannel = oldFocusedWindowHandle->getInputChannel();
Yi Kong9b14ac62018-07-17 13:48:38 -07003092 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003093 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3094 "focus left window");
3095 synthesizeCancelationEventsForInputChannelLocked(
3096 focusedInputChannel, options);
3097 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003098 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003099 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003100 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003101#if DEBUG_FOCUS
3102 ALOGD("Focus entered window: %s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003103 newFocusedWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003104#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003105 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003106 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107 }
3108
Arthur Hungb92218b2018-08-14 12:00:21 +08003109 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3110 if (stateIndex >= 0) {
3111 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003112 for (size_t i = 0; i < state.windows.size(); ) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003113 TouchedWindow& touchedWindow = state.windows.editItemAt(i);
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003114 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003115#if DEBUG_FOCUS
Jeff Brownf086ddb2014-02-11 14:28:48 -08003116 ALOGD("Touched window was removed: %s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003117 touchedWindow.windowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003118#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003119 sp<InputChannel> touchedInputChannel =
3120 touchedWindow.windowHandle->getInputChannel();
Yi Kong9b14ac62018-07-17 13:48:38 -07003121 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003122 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3123 "touched window was removed");
3124 synthesizeCancelationEventsForInputChannelLocked(
3125 touchedInputChannel, options);
3126 }
Ivan Lozano96f12992017-11-09 14:45:38 -08003127 state.windows.removeAt(i);
3128 } else {
3129 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003130 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003131 }
3132 }
3133
3134 // Release information for windows that are no longer present.
3135 // This ensures that unused input channels are released promptly.
3136 // Otherwise, they might stick around until the window handle is destroyed
3137 // which might not happen until the next GC.
Arthur Hungb92218b2018-08-14 12:00:21 +08003138 size_t numWindows = oldWindowHandles.size();
3139 for (size_t i = 0; i < numWindows; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003140 const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003141 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003142#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003143 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144#endif
3145 oldWindowHandle->releaseInfo();
3146 }
3147 }
3148 } // release lock
3149
3150 // Wake up poll loop since it may need to make new input dispatching choices.
3151 mLooper->wake();
3152}
3153
3154void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003155 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003156#if DEBUG_FOCUS
3157 ALOGD("setFocusedApplication");
3158#endif
3159 { // acquire lock
3160 AutoMutex _l(mLock);
3161
Tiger Huang721e26f2018-07-24 22:26:19 +08003162 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3163 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003164 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003165 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3166 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003168 oldFocusedApplicationHandle->releaseInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003170 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003171 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003172 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003173 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003174 oldFocusedApplicationHandle->releaseInfo();
3175 oldFocusedApplicationHandle.clear();
3176 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003177 }
3178
3179#if DEBUG_FOCUS
3180 //logDispatchStateLocked();
3181#endif
3182 } // release lock
3183
3184 // Wake up poll loop since it may need to make new input dispatching choices.
3185 mLooper->wake();
3186}
3187
Tiger Huang721e26f2018-07-24 22:26:19 +08003188/**
3189 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3190 * the display not specified.
3191 *
3192 * We track any unreleased events for each window. If a window loses the ability to receive the
3193 * released event, we will send a cancel event to it. So when the focused display is changed, we
3194 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3195 * display. The display-specified events won't be affected.
3196 */
3197void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3198#if DEBUG_FOCUS
3199 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3200#endif
3201 { // acquire lock
3202 AutoMutex _l(mLock);
3203
3204 if (mFocusedDisplayId != displayId) {
3205 sp<InputWindowHandle> oldFocusedWindowHandle =
3206 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3207 if (oldFocusedWindowHandle != nullptr) {
3208 sp<InputChannel> inputChannel = oldFocusedWindowHandle->getInputChannel();
3209 if (inputChannel != nullptr) {
3210 CancelationOptions options(
3211 CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS,
3212 "The display which contains this window no longer has focus.");
3213 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3214 }
3215 }
3216 mFocusedDisplayId = displayId;
3217
3218 // Sanity check
3219 sp<InputWindowHandle> newFocusedWindowHandle =
3220 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3221 if (newFocusedWindowHandle == nullptr) {
3222 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3223 if (!mFocusedWindowHandlesByDisplay.empty()) {
3224 ALOGE("But another display has a focused window:");
3225 for (auto& it : mFocusedWindowHandlesByDisplay) {
3226 const int32_t displayId = it.first;
3227 const sp<InputWindowHandle>& windowHandle = it.second;
3228 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3229 displayId, windowHandle->getName().c_str());
3230 }
3231 }
3232 }
3233 }
3234
3235#if DEBUG_FOCUS
3236 logDispatchStateLocked();
3237#endif
3238 } // release lock
3239
3240 // Wake up poll loop since it may need to make new input dispatching choices.
3241 mLooper->wake();
3242}
3243
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3245#if DEBUG_FOCUS
3246 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3247#endif
3248
3249 bool changed;
3250 { // acquire lock
3251 AutoMutex _l(mLock);
3252
3253 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3254 if (mDispatchFrozen && !frozen) {
3255 resetANRTimeoutsLocked();
3256 }
3257
3258 if (mDispatchEnabled && !enabled) {
3259 resetAndDropEverythingLocked("dispatcher is being disabled");
3260 }
3261
3262 mDispatchEnabled = enabled;
3263 mDispatchFrozen = frozen;
3264 changed = true;
3265 } else {
3266 changed = false;
3267 }
3268
3269#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003270 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271#endif
3272 } // release lock
3273
3274 if (changed) {
3275 // Wake up poll loop since it may need to make new input dispatching choices.
3276 mLooper->wake();
3277 }
3278}
3279
3280void InputDispatcher::setInputFilterEnabled(bool enabled) {
3281#if DEBUG_FOCUS
3282 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3283#endif
3284
3285 { // acquire lock
3286 AutoMutex _l(mLock);
3287
3288 if (mInputFilterEnabled == enabled) {
3289 return;
3290 }
3291
3292 mInputFilterEnabled = enabled;
3293 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3294 } // release lock
3295
3296 // Wake up poll loop since there might be work to do to drop everything.
3297 mLooper->wake();
3298}
3299
3300bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
3301 const sp<InputChannel>& toChannel) {
3302#if DEBUG_FOCUS
3303 ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003304 fromChannel->getName().c_str(), toChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305#endif
3306 { // acquire lock
3307 AutoMutex _l(mLock);
3308
3309 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
3310 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
Yi Kong9b14ac62018-07-17 13:48:38 -07003311 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312#if DEBUG_FOCUS
3313 ALOGD("Cannot transfer focus because from or to window not found.");
3314#endif
3315 return false;
3316 }
3317 if (fromWindowHandle == toWindowHandle) {
3318#if DEBUG_FOCUS
3319 ALOGD("Trivial transfer to same window.");
3320#endif
3321 return true;
3322 }
3323 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3324#if DEBUG_FOCUS
3325 ALOGD("Cannot transfer focus because windows are on different displays.");
3326#endif
3327 return false;
3328 }
3329
3330 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003331 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3332 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3333 for (size_t i = 0; i < state.windows.size(); i++) {
3334 const TouchedWindow& touchedWindow = state.windows[i];
3335 if (touchedWindow.windowHandle == fromWindowHandle) {
3336 int32_t oldTargetFlags = touchedWindow.targetFlags;
3337 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338
Jeff Brownf086ddb2014-02-11 14:28:48 -08003339 state.windows.removeAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003340
Jeff Brownf086ddb2014-02-11 14:28:48 -08003341 int32_t newTargetFlags = oldTargetFlags
3342 & (InputTarget::FLAG_FOREGROUND
3343 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3344 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003345
Jeff Brownf086ddb2014-02-11 14:28:48 -08003346 found = true;
3347 goto Found;
3348 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003349 }
3350 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003351Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352
3353 if (! found) {
3354#if DEBUG_FOCUS
3355 ALOGD("Focus transfer failed because from window did not have focus.");
3356#endif
3357 return false;
3358 }
3359
3360 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3361 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3362 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3363 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3364 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3365
3366 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3367 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3368 "transferring touch focus from this window to another window");
3369 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3370 }
3371
3372#if DEBUG_FOCUS
3373 logDispatchStateLocked();
3374#endif
3375 } // release lock
3376
3377 // Wake up poll loop since it may need to make new input dispatching choices.
3378 mLooper->wake();
3379 return true;
3380}
3381
3382void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3383#if DEBUG_FOCUS
3384 ALOGD("Resetting and dropping all events (%s).", reason);
3385#endif
3386
3387 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3388 synthesizeCancelationEventsForAllConnectionsLocked(options);
3389
3390 resetKeyRepeatLocked();
3391 releasePendingEventLocked();
3392 drainInboundQueueLocked();
3393 resetANRTimeoutsLocked();
3394
Jeff Brownf086ddb2014-02-11 14:28:48 -08003395 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003397 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398}
3399
3400void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003401 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003402 dumpDispatchStateLocked(dump);
3403
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003404 std::istringstream stream(dump);
3405 std::string line;
3406
3407 while (std::getline(stream, line, '\n')) {
3408 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003409 }
3410}
3411
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003412void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
3413 dump += StringPrintf(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
3414 dump += StringPrintf(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Tiger Huang721e26f2018-07-24 22:26:19 +08003415 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003416
Tiger Huang721e26f2018-07-24 22:26:19 +08003417 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3418 dump += StringPrintf(INDENT "FocusedApplications:\n");
3419 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3420 const int32_t displayId = it.first;
3421 const sp<InputApplicationHandle>& applicationHandle = it.second;
3422 dump += StringPrintf(
3423 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3424 displayId,
3425 applicationHandle->getName().c_str(),
3426 applicationHandle->getDispatchingTimeout(
3427 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3428 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003430 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003431 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003432
3433 if (!mFocusedWindowHandlesByDisplay.empty()) {
3434 dump += StringPrintf(INDENT "FocusedWindows:\n");
3435 for (auto& it : mFocusedWindowHandlesByDisplay) {
3436 const int32_t displayId = it.first;
3437 const sp<InputWindowHandle>& windowHandle = it.second;
3438 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3439 displayId, windowHandle->getName().c_str());
3440 }
3441 } else {
3442 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3443 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444
Jeff Brownf086ddb2014-02-11 14:28:48 -08003445 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003446 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003447 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3448 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003449 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003450 state.displayId, toString(state.down), toString(state.split),
3451 state.deviceId, state.source);
3452 if (!state.windows.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003453 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003454 for (size_t i = 0; i < state.windows.size(); i++) {
3455 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003456 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3457 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003458 touchedWindow.pointerIds.value,
3459 touchedWindow.targetFlags);
3460 }
3461 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003462 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003463 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003464 }
3465 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003466 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467 }
3468
Arthur Hungb92218b2018-08-14 12:00:21 +08003469 if (!mWindowHandlesByDisplay.empty()) {
3470 for (auto& it : mWindowHandlesByDisplay) {
3471 const Vector<sp<InputWindowHandle>> windowHandles = it.second;
3472 dump += StringPrintf(INDENT "Display: %d\n", it.first);
3473 if (!windowHandles.isEmpty()) {
3474 dump += INDENT2 "Windows:\n";
3475 for (size_t i = 0; i < windowHandles.size(); i++) {
3476 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
3477 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003478
Arthur Hungb92218b2018-08-14 12:00:21 +08003479 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
3480 "paused=%s, hasFocus=%s, hasWallpaper=%s, "
3481 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
3482 "frame=[%d,%d][%d,%d], scale=%f, "
3483 "touchableRegion=",
3484 i, windowInfo->name.c_str(), windowInfo->displayId,
3485 toString(windowInfo->paused),
3486 toString(windowInfo->hasFocus),
3487 toString(windowInfo->hasWallpaper),
3488 toString(windowInfo->visible),
3489 toString(windowInfo->canReceiveKeys),
3490 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3491 windowInfo->layer,
3492 windowInfo->frameLeft, windowInfo->frameTop,
3493 windowInfo->frameRight, windowInfo->frameBottom,
3494 windowInfo->scaleFactor);
3495 dumpRegion(dump, windowInfo->touchableRegion);
3496 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3497 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3498 windowInfo->ownerPid, windowInfo->ownerUid,
3499 windowInfo->dispatchingTimeout / 1000000.0);
3500 }
3501 } else {
3502 dump += INDENT2 "Windows: <none>\n";
3503 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003504 }
3505 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003506 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003507 }
3508
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003509 if (!mMonitoringChannelsByDisplay.empty()) {
3510 for (auto& it : mMonitoringChannelsByDisplay) {
3511 const Vector<sp<InputChannel>>& monitoringChannels = it.second;
3512 dump += INDENT "MonitoringChannels in Display %d:\n";
3513 const size_t numChannels = monitoringChannels.size();
3514 for (size_t i = 0; i < numChannels; i++) {
3515 const sp<InputChannel>& channel = monitoringChannels[i];
3516 dump += StringPrintf(INDENT2 "%zu: '%s'\n", i, channel->getName().c_str());
3517 }
3518 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003519 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003520 dump += INDENT "MonitoringChannels: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521 }
3522
3523 nsecs_t currentTime = now();
3524
3525 // Dump recently dispatched or dropped events from oldest to newest.
3526 if (!mRecentQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003527 dump += StringPrintf(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528 for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003529 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003531 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532 (currentTime - entry->eventTime) * 0.000001f);
3533 }
3534 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003535 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003536 }
3537
3538 // Dump event currently being dispatched.
3539 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003540 dump += INDENT "PendingEvent:\n";
3541 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003542 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003543 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3545 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003546 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547 }
3548
3549 // Dump inbound events from oldest to newest.
3550 if (!mInboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003551 dump += StringPrintf(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003553 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003555 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556 (currentTime - entry->eventTime) * 0.000001f);
3557 }
3558 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003559 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003560 }
3561
Michael Wright78f24442014-08-06 15:55:28 -07003562 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003563 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003564 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3565 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3566 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003567 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003568 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3569 }
3570 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003571 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003572 }
3573
Michael Wrightd02c5b62014-02-10 15:10:22 -08003574 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003575 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003576 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3577 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003578 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003580 i, connection->getInputChannelName().c_str(),
3581 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003582 connection->getStatusLabel(), toString(connection->monitor),
3583 toString(connection->inputPublisherBlocked));
3584
3585 if (!connection->outboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003586 dump += StringPrintf(INDENT3 "OutboundQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003587 connection->outboundQueue.count());
3588 for (DispatchEntry* entry = connection->outboundQueue.head; entry;
3589 entry = entry->next) {
3590 dump.append(INDENT4);
3591 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003592 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593 entry->targetFlags, entry->resolvedAction,
3594 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3595 }
3596 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003597 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598 }
3599
3600 if (!connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003601 dump += StringPrintf(INDENT3 "WaitQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003602 connection->waitQueue.count());
3603 for (DispatchEntry* entry = connection->waitQueue.head; entry;
3604 entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003605 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003607 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003608 "age=%0.1fms, wait=%0.1fms\n",
3609 entry->targetFlags, entry->resolvedAction,
3610 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3611 (currentTime - entry->deliveryTime) * 0.000001f);
3612 }
3613 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003614 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615 }
3616 }
3617 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003618 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619 }
3620
3621 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003622 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003623 (mAppSwitchDueTime - now()) / 1000000.0);
3624 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003625 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 }
3627
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003628 dump += INDENT "Configuration:\n";
3629 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003631 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003632 mConfig.keyRepeatTimeout * 0.000001f);
3633}
3634
3635status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003636 const sp<InputWindowHandle>& inputWindowHandle, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003637#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003638 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3639 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640#endif
3641
3642 { // acquire lock
3643 AutoMutex _l(mLock);
3644
3645 if (getConnectionIndexLocked(inputChannel) >= 0) {
3646 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003647 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648 return BAD_VALUE;
3649 }
3650
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003651 // If InputWindowHandle is null and displayId is not ADISPLAY_ID_NONE,
3652 // treat inputChannel as monitor channel for displayId.
3653 bool monitor = inputWindowHandle == nullptr && displayId != ADISPLAY_ID_NONE;
3654
Michael Wrightd02c5b62014-02-10 15:10:22 -08003655 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
3656
3657 int fd = inputChannel->getFd();
3658 mConnectionsByFd.add(fd, connection);
3659
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003660 // Store monitor channel by displayId.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003661 if (monitor) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003662 Vector<sp<InputChannel>>& monitoringChannels =
3663 mMonitoringChannelsByDisplay[displayId];
3664 monitoringChannels.push(inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003665 }
3666
3667 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3668 } // release lock
3669
3670 // Wake the looper because some connections have changed.
3671 mLooper->wake();
3672 return OK;
3673}
3674
3675status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3676#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003677 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003678#endif
3679
3680 { // acquire lock
3681 AutoMutex _l(mLock);
3682
3683 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3684 if (status) {
3685 return status;
3686 }
3687 } // release lock
3688
3689 // Wake the poll loop because removing the connection may have changed the current
3690 // synchronization state.
3691 mLooper->wake();
3692 return OK;
3693}
3694
3695status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3696 bool notify) {
3697 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3698 if (connectionIndex < 0) {
3699 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003700 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701 return BAD_VALUE;
3702 }
3703
3704 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3705 mConnectionsByFd.removeItemsAt(connectionIndex);
3706
3707 if (connection->monitor) {
3708 removeMonitorChannelLocked(inputChannel);
3709 }
3710
3711 mLooper->removeFd(inputChannel->getFd());
3712
3713 nsecs_t currentTime = now();
3714 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3715
3716 connection->status = Connection::STATUS_ZOMBIE;
3717 return OK;
3718}
3719
3720void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003721 for (auto it = mMonitoringChannelsByDisplay.begin();
3722 it != mMonitoringChannelsByDisplay.end(); ) {
3723 Vector<sp<InputChannel>>& monitoringChannels = it->second;
3724 const size_t numChannels = monitoringChannels.size();
3725 for (size_t i = 0; i < numChannels; i++) {
3726 if (monitoringChannels[i] == inputChannel) {
3727 monitoringChannels.removeAt(i);
3728 break;
3729 }
3730 }
3731 if (monitoringChannels.empty()) {
3732 it = mMonitoringChannelsByDisplay.erase(it);
3733 } else {
3734 ++it;
3735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 }
3737}
3738
3739ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
3740 ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
3741 if (connectionIndex >= 0) {
3742 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3743 if (connection->inputChannel.get() == inputChannel.get()) {
3744 return connectionIndex;
3745 }
3746 }
3747
3748 return -1;
3749}
3750
3751void InputDispatcher::onDispatchCycleFinishedLocked(
3752 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
3753 CommandEntry* commandEntry = postCommandLocked(
3754 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3755 commandEntry->connection = connection;
3756 commandEntry->eventTime = currentTime;
3757 commandEntry->seq = seq;
3758 commandEntry->handled = handled;
3759}
3760
3761void InputDispatcher::onDispatchCycleBrokenLocked(
3762 nsecs_t currentTime, const sp<Connection>& connection) {
3763 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003764 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765
3766 CommandEntry* commandEntry = postCommandLocked(
3767 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
3768 commandEntry->connection = connection;
3769}
3770
3771void InputDispatcher::onANRLocked(
3772 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
3773 const sp<InputWindowHandle>& windowHandle,
3774 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
3775 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
3776 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
3777 ALOGI("Application is not responding: %s. "
3778 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003779 getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 dispatchLatency, waitDuration, reason);
3781
3782 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07003783 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784 struct tm tm;
3785 localtime_r(&t, &tm);
3786 char timestr[64];
3787 strftime(timestr, sizeof(timestr), "%F %T", &tm);
3788 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003789 mLastANRState += INDENT "ANR:\n";
3790 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
3791 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
3792 getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str());
3793 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
3794 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
3795 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003796 dumpDispatchStateLocked(mLastANRState);
3797
3798 CommandEntry* commandEntry = postCommandLocked(
3799 & InputDispatcher::doNotifyANRLockedInterruptible);
3800 commandEntry->inputApplicationHandle = applicationHandle;
3801 commandEntry->inputWindowHandle = windowHandle;
3802 commandEntry->reason = reason;
3803}
3804
3805void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3806 CommandEntry* commandEntry) {
3807 mLock.unlock();
3808
3809 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3810
3811 mLock.lock();
3812}
3813
3814void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3815 CommandEntry* commandEntry) {
3816 sp<Connection> connection = commandEntry->connection;
3817
3818 if (connection->status != Connection::STATUS_ZOMBIE) {
3819 mLock.unlock();
3820
3821 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
3822
3823 mLock.lock();
3824 }
3825}
3826
3827void InputDispatcher::doNotifyANRLockedInterruptible(
3828 CommandEntry* commandEntry) {
3829 mLock.unlock();
3830
3831 nsecs_t newTimeout = mPolicy->notifyANR(
3832 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
3833 commandEntry->reason);
3834
3835 mLock.lock();
3836
3837 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Yi Kong9b14ac62018-07-17 13:48:38 -07003838 commandEntry->inputWindowHandle != nullptr
3839 ? commandEntry->inputWindowHandle->getInputChannel() : nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003840}
3841
3842void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3843 CommandEntry* commandEntry) {
3844 KeyEntry* entry = commandEntry->keyEntry;
3845
3846 KeyEvent event;
3847 initializeKeyEvent(&event, entry);
3848
3849 mLock.unlock();
3850
Michael Wright2b3c3302018-03-02 17:19:13 +00003851 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
3853 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003854 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3855 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
3856 std::to_string(t.duration().count()).c_str());
3857 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858
3859 mLock.lock();
3860
3861 if (delay < 0) {
3862 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3863 } else if (!delay) {
3864 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3865 } else {
3866 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3867 entry->interceptKeyWakeupTime = now() + delay;
3868 }
3869 entry->release();
3870}
3871
3872void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3873 CommandEntry* commandEntry) {
3874 sp<Connection> connection = commandEntry->connection;
3875 nsecs_t finishTime = commandEntry->eventTime;
3876 uint32_t seq = commandEntry->seq;
3877 bool handled = commandEntry->handled;
3878
3879 // Handle post-event policy actions.
3880 DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
3881 if (dispatchEntry) {
3882 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
3883 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003884 std::string msg =
3885 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003886 connection->getWindowName().c_str(), eventDuration * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887 dispatchEntry->eventEntry->appendDescription(msg);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003888 ALOGI("%s", msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889 }
3890
3891 bool restartEvent;
3892 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3893 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
3894 restartEvent = afterKeyEventLockedInterruptible(connection,
3895 dispatchEntry, keyEntry, handled);
3896 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
3897 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
3898 restartEvent = afterMotionEventLockedInterruptible(connection,
3899 dispatchEntry, motionEntry, handled);
3900 } else {
3901 restartEvent = false;
3902 }
3903
3904 // Dequeue the event and start the next cycle.
3905 // Note that because the lock might have been released, it is possible that the
3906 // contents of the wait queue to have been drained, so we need to double-check
3907 // a few things.
3908 if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
3909 connection->waitQueue.dequeue(dispatchEntry);
3910 traceWaitQueueLengthLocked(connection);
3911 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
3912 connection->outboundQueue.enqueueAtHead(dispatchEntry);
3913 traceOutboundQueueLengthLocked(connection);
3914 } else {
3915 releaseDispatchEntryLocked(dispatchEntry);
3916 }
3917 }
3918
3919 // Start the next dispatch cycle for this connection.
3920 startDispatchCycleLocked(now(), connection);
3921 }
3922}
3923
3924bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
3925 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
3926 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3927 // Get the fallback key state.
3928 // Clear it out after dispatching the UP.
3929 int32_t originalKeyCode = keyEntry->keyCode;
3930 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3931 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3932 connection->inputState.removeFallbackKey(originalKeyCode);
3933 }
3934
3935 if (handled || !dispatchEntry->hasForegroundTarget()) {
3936 // If the application handles the original key for which we previously
3937 // generated a fallback or if the window is not a foreground window,
3938 // then cancel the associated fallback key, if any.
3939 if (fallbackKeyCode != -1) {
3940 // Dispatch the unhandled key to the policy with the cancel flag.
3941#if DEBUG_OUTBOUND_EVENT_DETAILS
3942 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
3943 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
3944 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
3945 keyEntry->policyFlags);
3946#endif
3947 KeyEvent event;
3948 initializeKeyEvent(&event, keyEntry);
3949 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
3950
3951 mLock.unlock();
3952
3953 mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
3954 &event, keyEntry->policyFlags, &event);
3955
3956 mLock.lock();
3957
3958 // Cancel the fallback key.
3959 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3960 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3961 "application handled the original non-fallback key "
3962 "or is no longer a foreground target, "
3963 "canceling previously dispatched fallback key");
3964 options.keyCode = fallbackKeyCode;
3965 synthesizeCancelationEventsForConnectionLocked(connection, options);
3966 }
3967 connection->inputState.removeFallbackKey(originalKeyCode);
3968 }
3969 } else {
3970 // If the application did not handle a non-fallback key, first check
3971 // that we are in a good state to perform unhandled key event processing
3972 // Then ask the policy what to do with it.
3973 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3974 && keyEntry->repeatCount == 0;
3975 if (fallbackKeyCode == -1 && !initialDown) {
3976#if DEBUG_OUTBOUND_EVENT_DETAILS
3977 ALOGD("Unhandled key event: Skipping unhandled key event processing "
3978 "since this is not an initial down. "
3979 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
3980 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
3981 keyEntry->policyFlags);
3982#endif
3983 return false;
3984 }
3985
3986 // Dispatch the unhandled key to the policy.
3987#if DEBUG_OUTBOUND_EVENT_DETAILS
3988 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
3989 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
3990 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
3991 keyEntry->policyFlags);
3992#endif
3993 KeyEvent event;
3994 initializeKeyEvent(&event, keyEntry);
3995
3996 mLock.unlock();
3997
3998 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
3999 &event, keyEntry->policyFlags, &event);
4000
4001 mLock.lock();
4002
4003 if (connection->status != Connection::STATUS_NORMAL) {
4004 connection->inputState.removeFallbackKey(originalKeyCode);
4005 return false;
4006 }
4007
4008 // Latch the fallback keycode for this key on an initial down.
4009 // The fallback keycode cannot change at any other point in the lifecycle.
4010 if (initialDown) {
4011 if (fallback) {
4012 fallbackKeyCode = event.getKeyCode();
4013 } else {
4014 fallbackKeyCode = AKEYCODE_UNKNOWN;
4015 }
4016 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4017 }
4018
4019 ALOG_ASSERT(fallbackKeyCode != -1);
4020
4021 // Cancel the fallback key if the policy decides not to send it anymore.
4022 // We will continue to dispatch the key to the policy but we will no
4023 // longer dispatch a fallback key to the application.
4024 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4025 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4026#if DEBUG_OUTBOUND_EVENT_DETAILS
4027 if (fallback) {
4028 ALOGD("Unhandled key event: Policy requested to send key %d"
4029 "as a fallback for %d, but on the DOWN it had requested "
4030 "to send %d instead. Fallback canceled.",
4031 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4032 } else {
4033 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4034 "but on the DOWN it had requested to send %d. "
4035 "Fallback canceled.",
4036 originalKeyCode, fallbackKeyCode);
4037 }
4038#endif
4039
4040 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4041 "canceling fallback, policy no longer desires it");
4042 options.keyCode = fallbackKeyCode;
4043 synthesizeCancelationEventsForConnectionLocked(connection, options);
4044
4045 fallback = false;
4046 fallbackKeyCode = AKEYCODE_UNKNOWN;
4047 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4048 connection->inputState.setFallbackKey(originalKeyCode,
4049 fallbackKeyCode);
4050 }
4051 }
4052
4053#if DEBUG_OUTBOUND_EVENT_DETAILS
4054 {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004055 std::string msg;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004056 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4057 connection->inputState.getFallbackKeys();
4058 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004059 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004060 fallbackKeys.valueAt(i));
4061 }
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07004062 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004063 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064 }
4065#endif
4066
4067 if (fallback) {
4068 // Restart the dispatch cycle using the fallback key.
4069 keyEntry->eventTime = event.getEventTime();
4070 keyEntry->deviceId = event.getDeviceId();
4071 keyEntry->source = event.getSource();
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004072 keyEntry->displayId = event.getDisplayId();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4074 keyEntry->keyCode = fallbackKeyCode;
4075 keyEntry->scanCode = event.getScanCode();
4076 keyEntry->metaState = event.getMetaState();
4077 keyEntry->repeatCount = event.getRepeatCount();
4078 keyEntry->downTime = event.getDownTime();
4079 keyEntry->syntheticRepeat = false;
4080
4081#if DEBUG_OUTBOUND_EVENT_DETAILS
4082 ALOGD("Unhandled key event: Dispatching fallback key. "
4083 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4084 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4085#endif
4086 return true; // restart the event
4087 } else {
4088#if DEBUG_OUTBOUND_EVENT_DETAILS
4089 ALOGD("Unhandled key event: No fallback key.");
4090#endif
4091 }
4092 }
4093 }
4094 return false;
4095}
4096
4097bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4098 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4099 return false;
4100}
4101
4102void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4103 mLock.unlock();
4104
4105 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4106
4107 mLock.lock();
4108}
4109
4110void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004111 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004112 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4113 entry->downTime, entry->eventTime);
4114}
4115
4116void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
4117 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4118 // TODO Write some statistics about how long we spend waiting.
4119}
4120
4121void InputDispatcher::traceInboundQueueLengthLocked() {
4122 if (ATRACE_ENABLED()) {
4123 ATRACE_INT("iq", mInboundQueue.count());
4124 }
4125}
4126
4127void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
4128 if (ATRACE_ENABLED()) {
4129 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004130 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 ATRACE_INT(counterName, connection->outboundQueue.count());
4132 }
4133}
4134
4135void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
4136 if (ATRACE_ENABLED()) {
4137 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004138 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139 ATRACE_INT(counterName, connection->waitQueue.count());
4140 }
4141}
4142
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004143void InputDispatcher::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144 AutoMutex _l(mLock);
4145
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004146 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147 dumpDispatchStateLocked(dump);
4148
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004149 if (!mLastANRState.empty()) {
4150 dump += "\nInput Dispatcher State at time of last ANR:\n";
4151 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004152 }
4153}
4154
4155void InputDispatcher::monitor() {
4156 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
4157 mLock.lock();
4158 mLooper->wake();
4159 mDispatcherIsAliveCondition.wait(mLock);
4160 mLock.unlock();
4161}
4162
4163
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164// --- InputDispatcher::InjectionState ---
4165
4166InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4167 refCount(1),
4168 injectorPid(injectorPid), injectorUid(injectorUid),
4169 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4170 pendingForegroundDispatches(0) {
4171}
4172
4173InputDispatcher::InjectionState::~InjectionState() {
4174}
4175
4176void InputDispatcher::InjectionState::release() {
4177 refCount -= 1;
4178 if (refCount == 0) {
4179 delete this;
4180 } else {
4181 ALOG_ASSERT(refCount > 0);
4182 }
4183}
4184
4185
4186// --- InputDispatcher::EventEntry ---
4187
4188InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
4189 refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
Yi Kong9b14ac62018-07-17 13:48:38 -07004190 injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191}
4192
4193InputDispatcher::EventEntry::~EventEntry() {
4194 releaseInjectionState();
4195}
4196
4197void InputDispatcher::EventEntry::release() {
4198 refCount -= 1;
4199 if (refCount == 0) {
4200 delete this;
4201 } else {
4202 ALOG_ASSERT(refCount > 0);
4203 }
4204}
4205
4206void InputDispatcher::EventEntry::releaseInjectionState() {
4207 if (injectionState) {
4208 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004209 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004210 }
4211}
4212
4213
4214// --- InputDispatcher::ConfigurationChangedEntry ---
4215
4216InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
4217 EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
4218}
4219
4220InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4221}
4222
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004223void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4224 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225}
4226
4227
4228// --- InputDispatcher::DeviceResetEntry ---
4229
4230InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
4231 EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
4232 deviceId(deviceId) {
4233}
4234
4235InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4236}
4237
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004238void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4239 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004240 deviceId, policyFlags);
4241}
4242
4243
4244// --- InputDispatcher::KeyEntry ---
4245
4246InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004247 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4249 int32_t repeatCount, nsecs_t downTime) :
4250 EventEntry(TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004251 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004252 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4253 repeatCount(repeatCount), downTime(downTime),
4254 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4255 interceptKeyWakeupTime(0) {
4256}
4257
4258InputDispatcher::KeyEntry::~KeyEntry() {
4259}
4260
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004261void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004262 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004263 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4264 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004265 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004266 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004267}
4268
4269void InputDispatcher::KeyEntry::recycle() {
4270 releaseInjectionState();
4271
4272 dispatchInProgress = false;
4273 syntheticRepeat = false;
4274 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4275 interceptKeyWakeupTime = 0;
4276}
4277
4278
4279// --- InputDispatcher::MotionEntry ---
4280
Michael Wright7b159c92015-05-14 14:48:03 +01004281InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, int32_t deviceId,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004282 uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
4283 int32_t actionButton,
Michael Wright7b159c92015-05-14 14:48:03 +01004284 int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
4285 float xPrecision, float yPrecision, nsecs_t downTime,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004286 uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004287 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
4288 float xOffset, float yOffset) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289 EventEntry(TYPE_MOTION, eventTime, policyFlags),
4290 eventTime(eventTime),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004291 deviceId(deviceId), source(source), displayId(displayId), action(action),
4292 actionButton(actionButton), flags(flags), metaState(metaState), buttonState(buttonState),
Michael Wright7b159c92015-05-14 14:48:03 +01004293 edgeFlags(edgeFlags), xPrecision(xPrecision), yPrecision(yPrecision),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004294 downTime(downTime), pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295 for (uint32_t i = 0; i < pointerCount; i++) {
4296 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4297 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004298 if (xOffset || yOffset) {
4299 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4300 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301 }
4302}
4303
4304InputDispatcher::MotionEntry::~MotionEntry() {
4305}
4306
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004307void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004308 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004309 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004310 "edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[",
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004311 deviceId, source, displayId, motionActionToString(action).c_str(), actionButton, flags,
4312 metaState, buttonState, edgeFlags, xPrecision, yPrecision);
4313
Michael Wrightd02c5b62014-02-10 15:10:22 -08004314 for (uint32_t i = 0; i < pointerCount; i++) {
4315 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004316 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004318 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004319 pointerCoords[i].getX(), pointerCoords[i].getY());
4320 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004321 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004322}
4323
4324
4325// --- InputDispatcher::DispatchEntry ---
4326
4327volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4328
4329InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
4330 int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
4331 seq(nextSeq()),
4332 eventEntry(eventEntry), targetFlags(targetFlags),
4333 xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
4334 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4335 eventEntry->refCount += 1;
4336}
4337
4338InputDispatcher::DispatchEntry::~DispatchEntry() {
4339 eventEntry->release();
4340}
4341
4342uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4343 // Sequence number 0 is reserved and will never be returned.
4344 uint32_t seq;
4345 do {
4346 seq = android_atomic_inc(&sNextSeqAtomic);
4347 } while (!seq);
4348 return seq;
4349}
4350
4351
4352// --- InputDispatcher::InputState ---
4353
4354InputDispatcher::InputState::InputState() {
4355}
4356
4357InputDispatcher::InputState::~InputState() {
4358}
4359
4360bool InputDispatcher::InputState::isNeutral() const {
4361 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
4362}
4363
4364bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4365 int32_t displayId) const {
4366 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4367 const MotionMemento& memento = mMotionMementos.itemAt(i);
4368 if (memento.deviceId == deviceId
4369 && memento.source == source
4370 && memento.displayId == displayId
4371 && memento.hovering) {
4372 return true;
4373 }
4374 }
4375 return false;
4376}
4377
4378bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4379 int32_t action, int32_t flags) {
4380 switch (action) {
4381 case AKEY_EVENT_ACTION_UP: {
4382 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4383 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4384 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4385 mFallbackKeys.removeItemsAt(i);
4386 } else {
4387 i += 1;
4388 }
4389 }
4390 }
4391 ssize_t index = findKeyMemento(entry);
4392 if (index >= 0) {
4393 mKeyMementos.removeAt(index);
4394 return true;
4395 }
4396 /* FIXME: We can't just drop the key up event because that prevents creating
4397 * popup windows that are automatically shown when a key is held and then
4398 * dismissed when the key is released. The problem is that the popup will
4399 * not have received the original key down, so the key up will be considered
4400 * to be inconsistent with its observed state. We could perhaps handle this
4401 * by synthesizing a key down but that will cause other problems.
4402 *
4403 * So for now, allow inconsistent key up events to be dispatched.
4404 *
4405#if DEBUG_OUTBOUND_EVENT_DETAILS
4406 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4407 "keyCode=%d, scanCode=%d",
4408 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4409#endif
4410 return false;
4411 */
4412 return true;
4413 }
4414
4415 case AKEY_EVENT_ACTION_DOWN: {
4416 ssize_t index = findKeyMemento(entry);
4417 if (index >= 0) {
4418 mKeyMementos.removeAt(index);
4419 }
4420 addKeyMemento(entry, flags);
4421 return true;
4422 }
4423
4424 default:
4425 return true;
4426 }
4427}
4428
4429bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4430 int32_t action, int32_t flags) {
4431 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4432 switch (actionMasked) {
4433 case AMOTION_EVENT_ACTION_UP:
4434 case AMOTION_EVENT_ACTION_CANCEL: {
4435 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4436 if (index >= 0) {
4437 mMotionMementos.removeAt(index);
4438 return true;
4439 }
4440#if DEBUG_OUTBOUND_EVENT_DETAILS
4441 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004442 "displayId=%" PRId32 ", actionMasked=%d",
4443 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004444#endif
4445 return false;
4446 }
4447
4448 case AMOTION_EVENT_ACTION_DOWN: {
4449 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4450 if (index >= 0) {
4451 mMotionMementos.removeAt(index);
4452 }
4453 addMotionMemento(entry, flags, false /*hovering*/);
4454 return true;
4455 }
4456
4457 case AMOTION_EVENT_ACTION_POINTER_UP:
4458 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4459 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004460 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4461 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4462 // generate cancellation events for these since they're based in relative rather than
4463 // absolute units.
4464 return true;
4465 }
4466
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004468
4469 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4470 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4471 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4472 // other value and we need to track the motion so we can send cancellation events for
4473 // anything generating fallback events (e.g. DPad keys for joystick movements).
4474 if (index >= 0) {
4475 if (entry->pointerCoords[0].isEmpty()) {
4476 mMotionMementos.removeAt(index);
4477 } else {
4478 MotionMemento& memento = mMotionMementos.editItemAt(index);
4479 memento.setPointers(entry);
4480 }
4481 } else if (!entry->pointerCoords[0].isEmpty()) {
4482 addMotionMemento(entry, flags, false /*hovering*/);
4483 }
4484
4485 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4486 return true;
4487 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004488 if (index >= 0) {
4489 MotionMemento& memento = mMotionMementos.editItemAt(index);
4490 memento.setPointers(entry);
4491 return true;
4492 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493#if DEBUG_OUTBOUND_EVENT_DETAILS
4494 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004495 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4496 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004497#endif
4498 return false;
4499 }
4500
4501 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4502 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4503 if (index >= 0) {
4504 mMotionMementos.removeAt(index);
4505 return true;
4506 }
4507#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004508 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4509 "displayId=%" PRId32,
4510 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004511#endif
4512 return false;
4513 }
4514
4515 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4516 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4517 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4518 if (index >= 0) {
4519 mMotionMementos.removeAt(index);
4520 }
4521 addMotionMemento(entry, flags, true /*hovering*/);
4522 return true;
4523 }
4524
4525 default:
4526 return true;
4527 }
4528}
4529
4530ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4531 for (size_t i = 0; i < mKeyMementos.size(); i++) {
4532 const KeyMemento& memento = mKeyMementos.itemAt(i);
4533 if (memento.deviceId == entry->deviceId
4534 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004535 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004536 && memento.keyCode == entry->keyCode
4537 && memento.scanCode == entry->scanCode) {
4538 return i;
4539 }
4540 }
4541 return -1;
4542}
4543
4544ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4545 bool hovering) const {
4546 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4547 const MotionMemento& memento = mMotionMementos.itemAt(i);
4548 if (memento.deviceId == entry->deviceId
4549 && memento.source == entry->source
4550 && memento.displayId == entry->displayId
4551 && memento.hovering == hovering) {
4552 return i;
4553 }
4554 }
4555 return -1;
4556}
4557
4558void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
4559 mKeyMementos.push();
4560 KeyMemento& memento = mKeyMementos.editTop();
4561 memento.deviceId = entry->deviceId;
4562 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004563 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004564 memento.keyCode = entry->keyCode;
4565 memento.scanCode = entry->scanCode;
4566 memento.metaState = entry->metaState;
4567 memento.flags = flags;
4568 memento.downTime = entry->downTime;
4569 memento.policyFlags = entry->policyFlags;
4570}
4571
4572void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4573 int32_t flags, bool hovering) {
4574 mMotionMementos.push();
4575 MotionMemento& memento = mMotionMementos.editTop();
4576 memento.deviceId = entry->deviceId;
4577 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004578 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004579 memento.flags = flags;
4580 memento.xPrecision = entry->xPrecision;
4581 memento.yPrecision = entry->yPrecision;
4582 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004583 memento.setPointers(entry);
4584 memento.hovering = hovering;
4585 memento.policyFlags = entry->policyFlags;
4586}
4587
4588void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4589 pointerCount = entry->pointerCount;
4590 for (uint32_t i = 0; i < entry->pointerCount; i++) {
4591 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
4592 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
4593 }
4594}
4595
4596void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
4597 Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
4598 for (size_t i = 0; i < mKeyMementos.size(); i++) {
4599 const KeyMemento& memento = mKeyMementos.itemAt(i);
4600 if (shouldCancelKey(memento, options)) {
4601 outEvents.push(new KeyEntry(currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004602 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004603 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
4604 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
4605 }
4606 }
4607
4608 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4609 const MotionMemento& memento = mMotionMementos.itemAt(i);
4610 if (shouldCancelMotion(memento, options)) {
4611 outEvents.push(new MotionEntry(currentTime,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004612 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613 memento.hovering
4614 ? AMOTION_EVENT_ACTION_HOVER_EXIT
4615 : AMOTION_EVENT_ACTION_CANCEL,
Michael Wright7b159c92015-05-14 14:48:03 +01004616 memento.flags, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004617 memento.xPrecision, memento.yPrecision, memento.downTime,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004618 memento.pointerCount, memento.pointerProperties, memento.pointerCoords,
4619 0, 0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004620 }
4621 }
4622}
4623
4624void InputDispatcher::InputState::clear() {
4625 mKeyMementos.clear();
4626 mMotionMementos.clear();
4627 mFallbackKeys.clear();
4628}
4629
4630void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
4631 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4632 const MotionMemento& memento = mMotionMementos.itemAt(i);
4633 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
4634 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
4635 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
4636 if (memento.deviceId == otherMemento.deviceId
4637 && memento.source == otherMemento.source
4638 && memento.displayId == otherMemento.displayId) {
4639 other.mMotionMementos.removeAt(j);
4640 } else {
4641 j += 1;
4642 }
4643 }
4644 other.mMotionMementos.push(memento);
4645 }
4646 }
4647}
4648
4649int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
4650 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4651 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
4652}
4653
4654void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
4655 int32_t fallbackKeyCode) {
4656 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4657 if (index >= 0) {
4658 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
4659 } else {
4660 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
4661 }
4662}
4663
4664void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
4665 mFallbackKeys.removeItem(originalKeyCode);
4666}
4667
4668bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
4669 const CancelationOptions& options) {
4670 if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
4671 return false;
4672 }
4673
4674 if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
4675 return false;
4676 }
4677
4678 switch (options.mode) {
4679 case CancelationOptions::CANCEL_ALL_EVENTS:
4680 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
4681 return true;
4682 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
4683 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
Tiger Huang721e26f2018-07-24 22:26:19 +08004684 case CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS:
4685 return memento.displayId == ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004686 default:
4687 return false;
4688 }
4689}
4690
4691bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
4692 const CancelationOptions& options) {
4693 if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
4694 return false;
4695 }
4696
4697 switch (options.mode) {
4698 case CancelationOptions::CANCEL_ALL_EVENTS:
4699 return true;
4700 case CancelationOptions::CANCEL_POINTER_EVENTS:
4701 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
4702 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
4703 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
Tiger Huang721e26f2018-07-24 22:26:19 +08004704 case CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS:
4705 return memento.displayId == ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004706 default:
4707 return false;
4708 }
4709}
4710
4711
4712// --- InputDispatcher::Connection ---
4713
4714InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
4715 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
4716 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
4717 monitor(monitor),
4718 inputPublisher(inputChannel), inputPublisherBlocked(false) {
4719}
4720
4721InputDispatcher::Connection::~Connection() {
4722}
4723
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004724const std::string InputDispatcher::Connection::getWindowName() const {
Yi Kong9b14ac62018-07-17 13:48:38 -07004725 if (inputWindowHandle != nullptr) {
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004726 return inputWindowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004727 }
4728 if (monitor) {
4729 return "monitor";
4730 }
4731 return "?";
4732}
4733
4734const char* InputDispatcher::Connection::getStatusLabel() const {
4735 switch (status) {
4736 case STATUS_NORMAL:
4737 return "NORMAL";
4738
4739 case STATUS_BROKEN:
4740 return "BROKEN";
4741
4742 case STATUS_ZOMBIE:
4743 return "ZOMBIE";
4744
4745 default:
4746 return "UNKNOWN";
4747 }
4748}
4749
4750InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
Yi Kong9b14ac62018-07-17 13:48:38 -07004751 for (DispatchEntry* entry = waitQueue.head; entry != nullptr; entry = entry->next) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004752 if (entry->seq == seq) {
4753 return entry;
4754 }
4755 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004756 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004757}
4758
4759
4760// --- InputDispatcher::CommandEntry ---
4761
4762InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07004763 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004764 seq(0), handled(false) {
4765}
4766
4767InputDispatcher::CommandEntry::~CommandEntry() {
4768}
4769
4770
4771// --- InputDispatcher::TouchState ---
4772
4773InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004774 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775}
4776
4777InputDispatcher::TouchState::~TouchState() {
4778}
4779
4780void InputDispatcher::TouchState::reset() {
4781 down = false;
4782 split = false;
4783 deviceId = -1;
4784 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004785 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004786 windows.clear();
4787}
4788
4789void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
4790 down = other.down;
4791 split = other.split;
4792 deviceId = other.deviceId;
4793 source = other.source;
4794 displayId = other.displayId;
4795 windows = other.windows;
4796}
4797
4798void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
4799 int32_t targetFlags, BitSet32 pointerIds) {
4800 if (targetFlags & InputTarget::FLAG_SPLIT) {
4801 split = true;
4802 }
4803
4804 for (size_t i = 0; i < windows.size(); i++) {
4805 TouchedWindow& touchedWindow = windows.editItemAt(i);
4806 if (touchedWindow.windowHandle == windowHandle) {
4807 touchedWindow.targetFlags |= targetFlags;
4808 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
4809 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
4810 }
4811 touchedWindow.pointerIds.value |= pointerIds.value;
4812 return;
4813 }
4814 }
4815
4816 windows.push();
4817
4818 TouchedWindow& touchedWindow = windows.editTop();
4819 touchedWindow.windowHandle = windowHandle;
4820 touchedWindow.targetFlags = targetFlags;
4821 touchedWindow.pointerIds = pointerIds;
4822}
4823
4824void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
4825 for (size_t i = 0; i < windows.size(); i++) {
4826 if (windows.itemAt(i).windowHandle == windowHandle) {
4827 windows.removeAt(i);
4828 return;
4829 }
4830 }
4831}
4832
4833void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
4834 for (size_t i = 0 ; i < windows.size(); ) {
4835 TouchedWindow& window = windows.editItemAt(i);
4836 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
4837 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
4838 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
4839 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
4840 i += 1;
4841 } else {
4842 windows.removeAt(i);
4843 }
4844 }
4845}
4846
4847sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
4848 for (size_t i = 0; i < windows.size(); i++) {
4849 const TouchedWindow& window = windows.itemAt(i);
4850 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4851 return window.windowHandle;
4852 }
4853 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004854 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004855}
4856
4857bool InputDispatcher::TouchState::isSlippery() const {
4858 // Must have exactly one foreground window.
4859 bool haveSlipperyForegroundWindow = false;
4860 for (size_t i = 0; i < windows.size(); i++) {
4861 const TouchedWindow& window = windows.itemAt(i);
4862 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4863 if (haveSlipperyForegroundWindow
4864 || !(window.windowHandle->getInfo()->layoutParamsFlags
4865 & InputWindowInfo::FLAG_SLIPPERY)) {
4866 return false;
4867 }
4868 haveSlipperyForegroundWindow = true;
4869 }
4870 }
4871 return haveSlipperyForegroundWindow;
4872}
4873
4874
4875// --- InputDispatcherThread ---
4876
4877InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
4878 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
4879}
4880
4881InputDispatcherThread::~InputDispatcherThread() {
4882}
4883
4884bool InputDispatcherThread::threadLoop() {
4885 mDispatcher->dispatchOnce();
4886 return true;
4887}
4888
4889} // namespace android