blob: 37c65f517e19ccff0a2474e709250dd6b4daf033 [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>
Robert Carr4e670e52018-08-15 13:26:12 -070061#include <binder/Binder.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080062
63#define INDENT " "
64#define INDENT2 " "
65#define INDENT3 " "
66#define INDENT4 " "
67
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080068using android::base::StringPrintf;
69
Michael Wrightd02c5b62014-02-10 15:10:22 -080070namespace android {
71
72// Default input dispatching timeout if there is no focused application or paused window
73// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000074constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Amount of time to allow for all pending events to be processed when an app switch
77// key is on the way. This is used to preempt input dispatch and drop input events
78// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000079constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080080
81// Amount of time to allow for an event to be dispatched (measured since its eventTime)
82// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow touch events to be streamed out to a connection before requiring
86// that the first event be finished. This value extends the ANR timeout by the specified
87// amount. For example, if streaming is allowed to get ahead by one second relative to the
88// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000089constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000092constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
93
94// Log a warning when an interception call takes longer than this to process.
95constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
99
Prabir Pradhan42611e02018-11-27 14:04:02 -0800100// Sequence number for synthesized or injected events.
101constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
102
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800112static std::string motionActionToString(int32_t action) {
113 // Convert MotionEvent action to string
114 switch(action & AMOTION_EVENT_ACTION_MASK) {
115 case AMOTION_EVENT_ACTION_DOWN:
116 return "DOWN";
117 case AMOTION_EVENT_ACTION_MOVE:
118 return "MOVE";
119 case AMOTION_EVENT_ACTION_UP:
120 return "UP";
121 case AMOTION_EVENT_ACTION_POINTER_DOWN:
122 return "POINTER_DOWN";
123 case AMOTION_EVENT_ACTION_POINTER_UP:
124 return "POINTER_UP";
125 }
126 return StringPrintf("%" PRId32, action);
127}
128
129static std::string keyActionToString(int32_t action) {
130 // Convert KeyEvent action to string
131 switch(action) {
132 case AKEY_EVENT_ACTION_DOWN:
133 return "DOWN";
134 case AKEY_EVENT_ACTION_UP:
135 return "UP";
136 case AKEY_EVENT_ACTION_MULTIPLE:
137 return "MULTIPLE";
138 }
139 return StringPrintf("%" PRId32, action);
140}
141
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
143 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
144 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
145}
146
147static bool isValidKeyAction(int32_t action) {
148 switch (action) {
149 case AKEY_EVENT_ACTION_DOWN:
150 case AKEY_EVENT_ACTION_UP:
151 return true;
152 default:
153 return false;
154 }
155}
156
157static bool validateKeyEvent(int32_t action) {
158 if (! isValidKeyAction(action)) {
159 ALOGE("Key event has invalid action code 0x%x", action);
160 return false;
161 }
162 return true;
163}
164
Michael Wright7b159c92015-05-14 14:48:03 +0100165static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166 switch (action & AMOTION_EVENT_ACTION_MASK) {
167 case AMOTION_EVENT_ACTION_DOWN:
168 case AMOTION_EVENT_ACTION_UP:
169 case AMOTION_EVENT_ACTION_CANCEL:
170 case AMOTION_EVENT_ACTION_MOVE:
171 case AMOTION_EVENT_ACTION_OUTSIDE:
172 case AMOTION_EVENT_ACTION_HOVER_ENTER:
173 case AMOTION_EVENT_ACTION_HOVER_MOVE:
174 case AMOTION_EVENT_ACTION_HOVER_EXIT:
175 case AMOTION_EVENT_ACTION_SCROLL:
176 return true;
177 case AMOTION_EVENT_ACTION_POINTER_DOWN:
178 case AMOTION_EVENT_ACTION_POINTER_UP: {
179 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800180 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 }
Michael Wright7b159c92015-05-14 14:48:03 +0100182 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
183 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
184 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 default:
186 return false;
187 }
188}
189
Michael Wright7b159c92015-05-14 14:48:03 +0100190static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100192 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193 ALOGE("Motion event has invalid action code 0x%x", action);
194 return false;
195 }
196 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000197 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800198 pointerCount, MAX_POINTERS);
199 return false;
200 }
201 BitSet32 pointerIdBits;
202 for (size_t i = 0; i < pointerCount; i++) {
203 int32_t id = pointerProperties[i].id;
204 if (id < 0 || id > MAX_POINTER_ID) {
205 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
206 id, MAX_POINTER_ID);
207 return false;
208 }
209 if (pointerIdBits.hasBit(id)) {
210 ALOGE("Motion event has duplicate pointer id %d", id);
211 return false;
212 }
213 pointerIdBits.markBit(id);
214 }
215 return true;
216}
217
218static bool isMainDisplay(int32_t displayId) {
219 return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
220}
221
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800222static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800224 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 return;
226 }
227
228 bool first = true;
229 Region::const_iterator cur = region.begin();
230 Region::const_iterator const tail = region.end();
231 while (cur != tail) {
232 if (first) {
233 first = false;
234 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800235 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800237 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 cur++;
239 }
240}
241
Tiger Huang721e26f2018-07-24 22:26:19 +0800242template<typename T, typename U>
243static T getValueByKey(std::unordered_map<U, T>& map, U key) {
244 typename std::unordered_map<U, T>::const_iterator it = map.find(key);
245 return it != map.end() ? it->second : T{};
246}
247
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248
249// --- InputDispatcher ---
250
251InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
252 mPolicy(policy),
Yi Kong9b14ac62018-07-17 13:48:38 -0700253 mPendingEvent(nullptr), mLastDropReason(DROP_REASON_NOT_DROPPED),
Michael Wright3a981722015-06-10 15:26:13 +0100254 mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
Yi Kong9b14ac62018-07-17 13:48:38 -0700255 mNextUnblockedEvent(nullptr),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256 mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
Tiger Huang721e26f2018-07-24 22:26:19 +0800257 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
259 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800260 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261
Yi Kong9b14ac62018-07-17 13:48:38 -0700262 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263
264 policy->getDispatcherConfiguration(&mConfig);
265}
266
267InputDispatcher::~InputDispatcher() {
268 { // acquire lock
269 AutoMutex _l(mLock);
270
271 resetKeyRepeatLocked();
272 releasePendingEventLocked();
273 drainInboundQueueLocked();
274 }
275
276 while (mConnectionsByFd.size() != 0) {
277 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
278 }
279}
280
281void InputDispatcher::dispatchOnce() {
282 nsecs_t nextWakeupTime = LONG_LONG_MAX;
283 { // acquire lock
284 AutoMutex _l(mLock);
285 mDispatcherIsAliveCondition.broadcast();
286
287 // Run a dispatch loop if there are no pending commands.
288 // The dispatch loop might enqueue commands to run afterwards.
289 if (!haveCommandsLocked()) {
290 dispatchOnceInnerLocked(&nextWakeupTime);
291 }
292
293 // Run all pending commands if there are any.
294 // If any commands were run then force the next poll to wake up immediately.
295 if (runCommandsLockedInterruptible()) {
296 nextWakeupTime = LONG_LONG_MIN;
297 }
298 } // release lock
299
300 // Wait for callback or timeout or wake. (make sure we round up, not down)
301 nsecs_t currentTime = now();
302 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
303 mLooper->pollOnce(timeoutMillis);
304}
305
306void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
307 nsecs_t currentTime = now();
308
Jeff Browndc5992e2014-04-11 01:27:26 -0700309 // Reset the key repeat timer whenever normal dispatch is suspended while the
310 // device is in a non-interactive state. This is to ensure that we abort a key
311 // repeat if the device is just coming out of sleep.
312 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800313 resetKeyRepeatLocked();
314 }
315
316 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
317 if (mDispatchFrozen) {
318#if DEBUG_FOCUS
319 ALOGD("Dispatch frozen. Waiting some more.");
320#endif
321 return;
322 }
323
324 // Optimize latency of app switches.
325 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
326 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
327 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
328 if (mAppSwitchDueTime < *nextWakeupTime) {
329 *nextWakeupTime = mAppSwitchDueTime;
330 }
331
332 // Ready to start a new event.
333 // If we don't already have a pending event, go grab one.
334 if (! mPendingEvent) {
335 if (mInboundQueue.isEmpty()) {
336 if (isAppSwitchDue) {
337 // The inbound queue is empty so the app switch key we were waiting
338 // for will never arrive. Stop waiting for it.
339 resetPendingAppSwitchLocked(false);
340 isAppSwitchDue = false;
341 }
342
343 // Synthesize a key repeat if appropriate.
344 if (mKeyRepeatState.lastKeyEntry) {
345 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
346 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
347 } else {
348 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
349 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
350 }
351 }
352 }
353
354 // Nothing to do if there is no pending event.
355 if (!mPendingEvent) {
356 return;
357 }
358 } else {
359 // Inbound queue has at least one entry.
360 mPendingEvent = mInboundQueue.dequeueAtHead();
361 traceInboundQueueLengthLocked();
362 }
363
364 // Poke user activity for this event.
365 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
366 pokeUserActivityLocked(mPendingEvent);
367 }
368
369 // Get ready to dispatch the event.
370 resetANRTimeoutsLocked();
371 }
372
373 // Now we have an event to dispatch.
374 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700375 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800376 bool done = false;
377 DropReason dropReason = DROP_REASON_NOT_DROPPED;
378 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
379 dropReason = DROP_REASON_POLICY;
380 } else if (!mDispatchEnabled) {
381 dropReason = DROP_REASON_DISABLED;
382 }
383
384 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700385 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800386 }
387
388 switch (mPendingEvent->type) {
389 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
390 ConfigurationChangedEntry* typedEntry =
391 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
392 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
393 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
394 break;
395 }
396
397 case EventEntry::TYPE_DEVICE_RESET: {
398 DeviceResetEntry* typedEntry =
399 static_cast<DeviceResetEntry*>(mPendingEvent);
400 done = dispatchDeviceResetLocked(currentTime, typedEntry);
401 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
402 break;
403 }
404
405 case EventEntry::TYPE_KEY: {
406 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
407 if (isAppSwitchDue) {
408 if (isAppSwitchKeyEventLocked(typedEntry)) {
409 resetPendingAppSwitchLocked(true);
410 isAppSwitchDue = false;
411 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
412 dropReason = DROP_REASON_APP_SWITCH;
413 }
414 }
415 if (dropReason == DROP_REASON_NOT_DROPPED
416 && isStaleEventLocked(currentTime, typedEntry)) {
417 dropReason = DROP_REASON_STALE;
418 }
419 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
420 dropReason = DROP_REASON_BLOCKED;
421 }
422 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
423 break;
424 }
425
426 case EventEntry::TYPE_MOTION: {
427 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
428 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
429 dropReason = DROP_REASON_APP_SWITCH;
430 }
431 if (dropReason == DROP_REASON_NOT_DROPPED
432 && isStaleEventLocked(currentTime, typedEntry)) {
433 dropReason = DROP_REASON_STALE;
434 }
435 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
436 dropReason = DROP_REASON_BLOCKED;
437 }
438 done = dispatchMotionLocked(currentTime, typedEntry,
439 &dropReason, nextWakeupTime);
440 break;
441 }
442
443 default:
444 ALOG_ASSERT(false);
445 break;
446 }
447
448 if (done) {
449 if (dropReason != DROP_REASON_NOT_DROPPED) {
450 dropInboundEventLocked(mPendingEvent, dropReason);
451 }
Michael Wright3a981722015-06-10 15:26:13 +0100452 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800453
454 releasePendingEventLocked();
455 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
456 }
457}
458
459bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
460 bool needWake = mInboundQueue.isEmpty();
461 mInboundQueue.enqueueAtTail(entry);
462 traceInboundQueueLengthLocked();
463
464 switch (entry->type) {
465 case EventEntry::TYPE_KEY: {
466 // Optimize app switch latency.
467 // If the application takes too long to catch up then we drop all events preceding
468 // the app switch key.
469 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
470 if (isAppSwitchKeyEventLocked(keyEntry)) {
471 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
472 mAppSwitchSawKeyDown = true;
473 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
474 if (mAppSwitchSawKeyDown) {
475#if DEBUG_APP_SWITCH
476 ALOGD("App switch is pending!");
477#endif
478 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
479 mAppSwitchSawKeyDown = false;
480 needWake = true;
481 }
482 }
483 }
484 break;
485 }
486
487 case EventEntry::TYPE_MOTION: {
488 // Optimize case where the current application is unresponsive and the user
489 // decides to touch a window in a different application.
490 // If the application takes too long to catch up then we drop all events preceding
491 // the touch into the other window.
492 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
493 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
494 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
495 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700496 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800497 int32_t displayId = motionEntry->displayId;
498 int32_t x = int32_t(motionEntry->pointerCoords[0].
499 getAxisValue(AMOTION_EVENT_AXIS_X));
500 int32_t y = int32_t(motionEntry->pointerCoords[0].
501 getAxisValue(AMOTION_EVENT_AXIS_Y));
502 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700503 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700504 && touchedWindowHandle->getApplicationToken()
505 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800506 // User touched a different application than the one we are waiting on.
507 // Flag the event, and start pruning the input queue.
508 mNextUnblockedEvent = motionEntry;
509 needWake = true;
510 }
511 }
512 break;
513 }
514 }
515
516 return needWake;
517}
518
519void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
520 entry->refCount += 1;
521 mRecentQueue.enqueueAtTail(entry);
522 if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
523 mRecentQueue.dequeueAtHead()->release();
524 }
525}
526
527sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800528 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800529 // Traverse windows from front to back to find touched window.
Arthur Hungb92218b2018-08-14 12:00:21 +0800530 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
531 size_t numWindows = windowHandles.size();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800533 sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800534 const InputWindowInfo* windowInfo = windowHandle->getInfo();
535 if (windowInfo->displayId == displayId) {
536 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800537
538 if (windowInfo->visible) {
539 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
540 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
541 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
542 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800543 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
544 if (portalToDisplayId != ADISPLAY_ID_NONE
545 && portalToDisplayId != displayId) {
546 if (addPortalWindows) {
547 // For the monitoring channels of the display.
548 mTempTouchState.addPortalWindow(windowHandle);
549 }
550 return findTouchedWindowAtLocked(
551 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
552 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800553 // Found window.
554 return windowHandle;
555 }
556 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800557
558 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
559 mTempTouchState.addOrUpdateWindow(
560 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
561 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800562 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800563 }
564 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700565 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566}
567
568void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
569 const char* reason;
570 switch (dropReason) {
571 case DROP_REASON_POLICY:
572#if DEBUG_INBOUND_EVENT_DETAILS
573 ALOGD("Dropped event because policy consumed it.");
574#endif
575 reason = "inbound event was dropped because the policy consumed it";
576 break;
577 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100578 if (mLastDropReason != DROP_REASON_DISABLED) {
579 ALOGI("Dropped event because input dispatch is disabled.");
580 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800581 reason = "inbound event was dropped because input dispatch is disabled";
582 break;
583 case DROP_REASON_APP_SWITCH:
584 ALOGI("Dropped event because of pending overdue app switch.");
585 reason = "inbound event was dropped because of pending overdue app switch";
586 break;
587 case DROP_REASON_BLOCKED:
588 ALOGI("Dropped event because the current application is not responding and the user "
589 "has started interacting with a different application.");
590 reason = "inbound event was dropped because the current application is not responding "
591 "and the user has started interacting with a different application";
592 break;
593 case DROP_REASON_STALE:
594 ALOGI("Dropped event because it is stale.");
595 reason = "inbound event was dropped because it is stale";
596 break;
597 default:
598 ALOG_ASSERT(false);
599 return;
600 }
601
602 switch (entry->type) {
603 case EventEntry::TYPE_KEY: {
604 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
605 synthesizeCancelationEventsForAllConnectionsLocked(options);
606 break;
607 }
608 case EventEntry::TYPE_MOTION: {
609 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
610 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
611 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
612 synthesizeCancelationEventsForAllConnectionsLocked(options);
613 } else {
614 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
615 synthesizeCancelationEventsForAllConnectionsLocked(options);
616 }
617 break;
618 }
619 }
620}
621
622bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
623 return keyCode == AKEYCODE_HOME
624 || keyCode == AKEYCODE_ENDCALL
625 || keyCode == AKEYCODE_APP_SWITCH;
626}
627
628bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
629 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
630 && isAppSwitchKeyCode(keyEntry->keyCode)
631 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
632 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
633}
634
635bool InputDispatcher::isAppSwitchPendingLocked() {
636 return mAppSwitchDueTime != LONG_LONG_MAX;
637}
638
639void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
640 mAppSwitchDueTime = LONG_LONG_MAX;
641
642#if DEBUG_APP_SWITCH
643 if (handled) {
644 ALOGD("App switch has arrived.");
645 } else {
646 ALOGD("App switch was abandoned.");
647 }
648#endif
649}
650
651bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
652 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
653}
654
655bool InputDispatcher::haveCommandsLocked() const {
656 return !mCommandQueue.isEmpty();
657}
658
659bool InputDispatcher::runCommandsLockedInterruptible() {
660 if (mCommandQueue.isEmpty()) {
661 return false;
662 }
663
664 do {
665 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
666
667 Command command = commandEntry->command;
668 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
669
670 commandEntry->connection.clear();
671 delete commandEntry;
672 } while (! mCommandQueue.isEmpty());
673 return true;
674}
675
676InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
677 CommandEntry* commandEntry = new CommandEntry(command);
678 mCommandQueue.enqueueAtTail(commandEntry);
679 return commandEntry;
680}
681
682void InputDispatcher::drainInboundQueueLocked() {
683 while (! mInboundQueue.isEmpty()) {
684 EventEntry* entry = mInboundQueue.dequeueAtHead();
685 releaseInboundEventLocked(entry);
686 }
687 traceInboundQueueLengthLocked();
688}
689
690void InputDispatcher::releasePendingEventLocked() {
691 if (mPendingEvent) {
692 resetANRTimeoutsLocked();
693 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700694 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800695 }
696}
697
698void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
699 InjectionState* injectionState = entry->injectionState;
700 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
701#if DEBUG_DISPATCH_CYCLE
702 ALOGD("Injected inbound event was dropped.");
703#endif
704 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
705 }
706 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700707 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708 }
709 addRecentEventLocked(entry);
710 entry->release();
711}
712
713void InputDispatcher::resetKeyRepeatLocked() {
714 if (mKeyRepeatState.lastKeyEntry) {
715 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700716 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800717 }
718}
719
720InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
721 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
722
723 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700724 uint32_t policyFlags = entry->policyFlags &
725 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800726 if (entry->refCount == 1) {
727 entry->recycle();
728 entry->eventTime = currentTime;
729 entry->policyFlags = policyFlags;
730 entry->repeatCount += 1;
731 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800732 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100733 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800734 entry->action, entry->flags, entry->keyCode, entry->scanCode,
735 entry->metaState, entry->repeatCount + 1, entry->downTime);
736
737 mKeyRepeatState.lastKeyEntry = newEntry;
738 entry->release();
739
740 entry = newEntry;
741 }
742 entry->syntheticRepeat = true;
743
744 // Increment reference count since we keep a reference to the event in
745 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
746 entry->refCount += 1;
747
748 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
749 return entry;
750}
751
752bool InputDispatcher::dispatchConfigurationChangedLocked(
753 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
754#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700755 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800756#endif
757
758 // Reset key repeating in case a keyboard device was added or removed or something.
759 resetKeyRepeatLocked();
760
761 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
762 CommandEntry* commandEntry = postCommandLocked(
763 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
764 commandEntry->eventTime = entry->eventTime;
765 return true;
766}
767
768bool InputDispatcher::dispatchDeviceResetLocked(
769 nsecs_t currentTime, DeviceResetEntry* entry) {
770#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700771 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
772 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773#endif
774
775 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
776 "device was reset");
777 options.deviceId = entry->deviceId;
778 synthesizeCancelationEventsForAllConnectionsLocked(options);
779 return true;
780}
781
782bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
783 DropReason* dropReason, nsecs_t* nextWakeupTime) {
784 // Preprocessing.
785 if (! entry->dispatchInProgress) {
786 if (entry->repeatCount == 0
787 && entry->action == AKEY_EVENT_ACTION_DOWN
788 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
789 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
790 if (mKeyRepeatState.lastKeyEntry
791 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
792 // We have seen two identical key downs in a row which indicates that the device
793 // driver is automatically generating key repeats itself. We take note of the
794 // repeat here, but we disable our own next key repeat timer since it is clear that
795 // we will not need to synthesize key repeats ourselves.
796 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
797 resetKeyRepeatLocked();
798 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
799 } else {
800 // Not a repeat. Save key down state in case we do see a repeat later.
801 resetKeyRepeatLocked();
802 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
803 }
804 mKeyRepeatState.lastKeyEntry = entry;
805 entry->refCount += 1;
806 } else if (! entry->syntheticRepeat) {
807 resetKeyRepeatLocked();
808 }
809
810 if (entry->repeatCount == 1) {
811 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
812 } else {
813 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
814 }
815
816 entry->dispatchInProgress = true;
817
818 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
819 }
820
821 // Handle case where the policy asked us to try again later last time.
822 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
823 if (currentTime < entry->interceptKeyWakeupTime) {
824 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
825 *nextWakeupTime = entry->interceptKeyWakeupTime;
826 }
827 return false; // wait until next wakeup
828 }
829 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
830 entry->interceptKeyWakeupTime = 0;
831 }
832
833 // Give the policy a chance to intercept the key.
834 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
835 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
836 CommandEntry* commandEntry = postCommandLocked(
837 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800838 sp<InputWindowHandle> focusedWindowHandle =
839 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
840 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700841 commandEntry->inputChannel =
842 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843 }
844 commandEntry->keyEntry = entry;
845 entry->refCount += 1;
846 return false; // wait for the command to run
847 } else {
848 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
849 }
850 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
851 if (*dropReason == DROP_REASON_NOT_DROPPED) {
852 *dropReason = DROP_REASON_POLICY;
853 }
854 }
855
856 // Clean up if dropping the event.
857 if (*dropReason != DROP_REASON_NOT_DROPPED) {
858 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
859 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800860 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800861 return true;
862 }
863
864 // Identify targets.
865 Vector<InputTarget> inputTargets;
866 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
867 entry, inputTargets, nextWakeupTime);
868 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
869 return false;
870 }
871
872 setInjectionResultLocked(entry, injectionResult);
873 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
874 return true;
875 }
876
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800877 // Add monitor channels from event's or focused display.
878 addMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800879
880 // Dispatch the key.
881 dispatchEventLocked(currentTime, entry, inputTargets);
882 return true;
883}
884
885void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
886#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100887 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
888 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800889 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800890 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100891 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800893 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894#endif
895}
896
897bool InputDispatcher::dispatchMotionLocked(
898 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
899 // Preprocessing.
900 if (! entry->dispatchInProgress) {
901 entry->dispatchInProgress = true;
902
903 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
904 }
905
906 // Clean up if dropping the event.
907 if (*dropReason != DROP_REASON_NOT_DROPPED) {
908 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
909 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
910 return true;
911 }
912
913 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
914
915 // Identify targets.
916 Vector<InputTarget> inputTargets;
917
918 bool conflictingPointerActions = false;
919 int32_t injectionResult;
920 if (isPointerEvent) {
921 // Pointer event. (eg. touchscreen)
922 injectionResult = findTouchedWindowTargetsLocked(currentTime,
923 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
924 } else {
925 // Non touch event. (eg. trackball)
926 injectionResult = findFocusedWindowTargetsLocked(currentTime,
927 entry, inputTargets, nextWakeupTime);
928 }
929 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
930 return false;
931 }
932
933 setInjectionResultLocked(entry, injectionResult);
934 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100935 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
936 CancelationOptions::Mode mode(isPointerEvent ?
937 CancelationOptions::CANCEL_POINTER_EVENTS :
938 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
939 CancelationOptions options(mode, "input event injection failed");
940 synthesizeCancelationEventsForMonitorsLocked(options);
941 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 return true;
943 }
944
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800945 // Add monitor channels from event's or focused display.
946 addMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800947
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800948 if (isPointerEvent) {
949 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
950 if (stateIndex >= 0) {
951 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
952 if (!state.portalWindows.isEmpty()) {
953 // The event has gone through these portal windows, so we add monitoring targets of
954 // the corresponding displays as well.
955 for (size_t i = 0; i < state.portalWindows.size(); i++) {
956 const InputWindowInfo* windowInfo = state.portalWindows.itemAt(i)->getInfo();
957 addMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
958 -windowInfo->frameLeft, -windowInfo->frameTop);
959 }
960 }
961 }
962 }
963
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 // Dispatch the motion.
965 if (conflictingPointerActions) {
966 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
967 "conflicting pointer actions");
968 synthesizeCancelationEventsForAllConnectionsLocked(options);
969 }
970 dispatchEventLocked(currentTime, entry, inputTargets);
971 return true;
972}
973
974
975void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
976#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800977 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
978 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +0100979 "action=0x%x, actionButton=0x%x, flags=0x%x, "
980 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +0800981 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800982 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800983 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100984 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 entry->metaState, entry->buttonState,
986 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800987 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800988
989 for (uint32_t i = 0; i < entry->pointerCount; i++) {
990 ALOGD(" Pointer %d: id=%d, toolType=%d, "
991 "x=%f, y=%f, pressure=%f, size=%f, "
992 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -0800993 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800994 i, entry->pointerProperties[i].id,
995 entry->pointerProperties[i].toolType,
996 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
997 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
998 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
999 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1000 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1001 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1002 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1003 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001004 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005 }
1006#endif
1007}
1008
1009void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1010 EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
1011#if DEBUG_DISPATCH_CYCLE
1012 ALOGD("dispatchEventToCurrentInputTargets");
1013#endif
1014
1015 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1016
1017 pokeUserActivityLocked(eventEntry);
1018
1019 for (size_t i = 0; i < inputTargets.size(); i++) {
1020 const InputTarget& inputTarget = inputTargets.itemAt(i);
1021
1022 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1023 if (connectionIndex >= 0) {
1024 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1025 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1026 } else {
1027#if DEBUG_FOCUS
1028 ALOGD("Dropping event delivery to target with channel '%s' because it "
1029 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001030 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001031#endif
1032 }
1033 }
1034}
1035
1036int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1037 const EventEntry* entry,
1038 const sp<InputApplicationHandle>& applicationHandle,
1039 const sp<InputWindowHandle>& windowHandle,
1040 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001041 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001042 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1043#if DEBUG_FOCUS
1044 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1045#endif
1046 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1047 mInputTargetWaitStartTime = currentTime;
1048 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1049 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001050 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001051 }
1052 } else {
1053 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1054#if DEBUG_FOCUS
1055 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001056 getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057 reason);
1058#endif
1059 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001060 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001061 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001062 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063 timeout = applicationHandle->getDispatchingTimeout(
1064 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1065 } else {
1066 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1067 }
1068
1069 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1070 mInputTargetWaitStartTime = currentTime;
1071 mInputTargetWaitTimeoutTime = currentTime + timeout;
1072 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001073 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001074
Yi Kong9b14ac62018-07-17 13:48:38 -07001075 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001076 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001077 }
Robert Carr740167f2018-10-11 19:03:41 -07001078 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1079 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080 }
1081 }
1082 }
1083
1084 if (mInputTargetWaitTimeoutExpired) {
1085 return INPUT_EVENT_INJECTION_TIMED_OUT;
1086 }
1087
1088 if (currentTime >= mInputTargetWaitTimeoutTime) {
1089 onANRLocked(currentTime, applicationHandle, windowHandle,
1090 entry->eventTime, mInputTargetWaitStartTime, reason);
1091
1092 // Force poll loop to wake up immediately on next iteration once we get the
1093 // ANR response back from the policy.
1094 *nextWakeupTime = LONG_LONG_MIN;
1095 return INPUT_EVENT_INJECTION_PENDING;
1096 } else {
1097 // Force poll loop to wake up when timeout is due.
1098 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1099 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1100 }
1101 return INPUT_EVENT_INJECTION_PENDING;
1102 }
1103}
1104
Robert Carr803535b2018-08-02 16:38:15 -07001105void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1106 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1107 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1108 state.removeWindowByToken(token);
1109 }
1110}
1111
Michael Wrightd02c5b62014-02-10 15:10:22 -08001112void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1113 const sp<InputChannel>& inputChannel) {
1114 if (newTimeout > 0) {
1115 // Extend the timeout.
1116 mInputTargetWaitTimeoutTime = now() + newTimeout;
1117 } else {
1118 // Give up.
1119 mInputTargetWaitTimeoutExpired = true;
1120
1121 // Input state will not be realistic. Mark it out of sync.
1122 if (inputChannel.get()) {
1123 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1124 if (connectionIndex >= 0) {
1125 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
Robert Carr803535b2018-08-02 16:38:15 -07001126 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127
Robert Carr803535b2018-08-02 16:38:15 -07001128 if (token != nullptr) {
1129 removeWindowByTokenLocked(token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 }
1131
1132 if (connection->status == Connection::STATUS_NORMAL) {
1133 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1134 "application not responding");
1135 synthesizeCancelationEventsForConnectionLocked(connection, options);
1136 }
1137 }
1138 }
1139 }
1140}
1141
1142nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1143 nsecs_t currentTime) {
1144 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1145 return currentTime - mInputTargetWaitStartTime;
1146 }
1147 return 0;
1148}
1149
1150void InputDispatcher::resetANRTimeoutsLocked() {
1151#if DEBUG_FOCUS
1152 ALOGD("Resetting ANR timeouts.");
1153#endif
1154
1155 // Reset input target wait timeout.
1156 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001157 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001158}
1159
Tiger Huang721e26f2018-07-24 22:26:19 +08001160/**
1161 * Get the display id that the given event should go to. If this event specifies a valid display id,
1162 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1163 * Focused display is the display that the user most recently interacted with.
1164 */
1165int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1166 int32_t displayId;
1167 switch (entry->type) {
1168 case EventEntry::TYPE_KEY: {
1169 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1170 displayId = typedEntry->displayId;
1171 break;
1172 }
1173 case EventEntry::TYPE_MOTION: {
1174 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1175 displayId = typedEntry->displayId;
1176 break;
1177 }
1178 default: {
1179 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1180 return ADISPLAY_ID_NONE;
1181 }
1182 }
1183 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1184}
1185
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1187 const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
1188 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001189 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001190
Tiger Huang721e26f2018-07-24 22:26:19 +08001191 int32_t displayId = getTargetDisplayId(entry);
1192 sp<InputWindowHandle> focusedWindowHandle =
1193 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1194 sp<InputApplicationHandle> focusedApplicationHandle =
1195 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1196
Michael Wrightd02c5b62014-02-10 15:10:22 -08001197 // If there is no currently focused window and no focused application
1198 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001199 if (focusedWindowHandle == nullptr) {
1200 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001202 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001203 "Waiting because no window has focus but there is a "
1204 "focused application that may eventually add a window "
1205 "when it finishes starting up.");
1206 goto Unresponsive;
1207 }
1208
Arthur Hung3b413f22018-10-26 18:05:34 +08001209 ALOGI("Dropping event because there is no focused window or focused application in display "
1210 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1212 goto Failed;
1213 }
1214
1215 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001216 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001217 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1218 goto Failed;
1219 }
1220
Jeff Brownffb49772014-10-10 19:01:34 -07001221 // Check whether the window is ready for more input.
1222 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001223 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001224 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001225 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001226 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001227 goto Unresponsive;
1228 }
1229
1230 // Success! Output targets.
1231 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001232 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001233 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1234 inputTargets);
1235
1236 // Done.
1237Failed:
1238Unresponsive:
1239 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1240 updateDispatchStatisticsLocked(currentTime, entry,
1241 injectionResult, timeSpentWaitingForApplication);
1242#if DEBUG_FOCUS
1243 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1244 "timeSpentWaitingForApplication=%0.1fms",
1245 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1246#endif
1247 return injectionResult;
1248}
1249
1250int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1251 const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
1252 bool* outConflictingPointerActions) {
1253 enum InjectionPermission {
1254 INJECTION_PERMISSION_UNKNOWN,
1255 INJECTION_PERMISSION_GRANTED,
1256 INJECTION_PERMISSION_DENIED
1257 };
1258
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 // For security reasons, we defer updating the touch state until we are sure that
1260 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261 int32_t displayId = entry->displayId;
1262 int32_t action = entry->action;
1263 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1264
1265 // Update the touch state as needed based on the properties of the touch event.
1266 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1267 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1268 sp<InputWindowHandle> newHoverWindowHandle;
1269
Jeff Brownf086ddb2014-02-11 14:28:48 -08001270 // Copy current touch state into mTempTouchState.
1271 // This state is always reset at the end of this function, so if we don't find state
1272 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001273 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001274 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1275 if (oldStateIndex >= 0) {
1276 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1277 mTempTouchState.copyFrom(*oldState);
1278 }
1279
1280 bool isSplit = mTempTouchState.split;
1281 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1282 && (mTempTouchState.deviceId != entry->deviceId
1283 || mTempTouchState.source != entry->source
1284 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001285 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1286 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1287 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1288 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1289 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1290 || isHoverAction);
1291 bool wrongDevice = false;
1292 if (newGesture) {
1293 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001294 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001295#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001296 ALOGD("Dropping event because a pointer for a different device is already down "
1297 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001299 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001300 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1301 switchedDevice = false;
1302 wrongDevice = true;
1303 goto Failed;
1304 }
1305 mTempTouchState.reset();
1306 mTempTouchState.down = down;
1307 mTempTouchState.deviceId = entry->deviceId;
1308 mTempTouchState.source = entry->source;
1309 mTempTouchState.displayId = displayId;
1310 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001311 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1312#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001313 ALOGI("Dropping move event because a pointer for a different device is already active "
1314 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001315#endif
1316 // TODO: test multiple simultaneous input streams.
1317 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1318 switchedDevice = false;
1319 wrongDevice = true;
1320 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321 }
1322
1323 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1324 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1325
1326 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1327 int32_t x = int32_t(entry->pointerCoords[pointerIndex].
1328 getAxisValue(AMOTION_EVENT_AXIS_X));
1329 int32_t y = int32_t(entry->pointerCoords[pointerIndex].
1330 getAxisValue(AMOTION_EVENT_AXIS_Y));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001331 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
1332 displayId, x, y, maskedAction == AMOTION_EVENT_ACTION_DOWN, true);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333
Michael Wrightd02c5b62014-02-10 15:10:22 -08001334 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001335 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001336 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1337 // New window supports splitting.
1338 isSplit = true;
1339 } else if (isSplit) {
1340 // New window does not support splitting but we have already split events.
1341 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001342 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001343 }
1344
1345 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001346 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001347 // Try to assign the pointer to the first foreground window we find, if there is one.
1348 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Yi Kong9b14ac62018-07-17 13:48:38 -07001349 if (newTouchedWindowHandle == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08001350 ALOGI("Dropping event because there is no touchable window at (%d, %d) in display "
1351 "%" PRId32 ".", x, y, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001352 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1353 goto Failed;
1354 }
1355 }
1356
1357 // Set target flags.
1358 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1359 if (isSplit) {
1360 targetFlags |= InputTarget::FLAG_SPLIT;
1361 }
1362 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1363 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001364 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1365 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001366 }
1367
1368 // Update hover state.
1369 if (isHoverAction) {
1370 newHoverWindowHandle = newTouchedWindowHandle;
1371 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1372 newHoverWindowHandle = mLastHoverWindowHandle;
1373 }
1374
1375 // Update the temporary touch state.
1376 BitSet32 pointerIds;
1377 if (isSplit) {
1378 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1379 pointerIds.markBit(pointerId);
1380 }
1381 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1382 } else {
1383 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1384
1385 // If the pointer is not currently down, then ignore the event.
1386 if (! mTempTouchState.down) {
1387#if DEBUG_FOCUS
1388 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001389 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390#endif
1391 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1392 goto Failed;
1393 }
1394
1395 // Check whether touches should slip outside of the current foreground window.
1396 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1397 && entry->pointerCount == 1
1398 && mTempTouchState.isSlippery()) {
1399 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1400 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1401
1402 sp<InputWindowHandle> oldTouchedWindowHandle =
1403 mTempTouchState.getFirstForegroundWindowHandle();
1404 sp<InputWindowHandle> newTouchedWindowHandle =
1405 findTouchedWindowAtLocked(displayId, x, y);
1406 if (oldTouchedWindowHandle != newTouchedWindowHandle
Yi Kong9b14ac62018-07-17 13:48:38 -07001407 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001408#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001409 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001410 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001411 newTouchedWindowHandle->getName().c_str(),
1412 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001413#endif
1414 // Make a slippery exit from the old window.
1415 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1416 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1417
1418 // Make a slippery entrance into the new window.
1419 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1420 isSplit = true;
1421 }
1422
1423 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1424 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1425 if (isSplit) {
1426 targetFlags |= InputTarget::FLAG_SPLIT;
1427 }
1428 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1429 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1430 }
1431
1432 BitSet32 pointerIds;
1433 if (isSplit) {
1434 pointerIds.markBit(entry->pointerProperties[0].id);
1435 }
1436 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1437 }
1438 }
1439 }
1440
1441 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1442 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001443 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001444#if DEBUG_HOVER
1445 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001446 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001447#endif
1448 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1449 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1450 }
1451
1452 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001453 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001454#if DEBUG_HOVER
1455 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001456 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457#endif
1458 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1459 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1460 }
1461 }
1462
1463 // Check permission to inject into all touched foreground windows and ensure there
1464 // is at least one touched foreground window.
1465 {
1466 bool haveForegroundWindow = false;
1467 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1468 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1469 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1470 haveForegroundWindow = true;
1471 if (! checkInjectionPermission(touchedWindow.windowHandle,
1472 entry->injectionState)) {
1473 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1474 injectionPermission = INJECTION_PERMISSION_DENIED;
1475 goto Failed;
1476 }
1477 }
1478 }
1479 if (! haveForegroundWindow) {
1480#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001481 ALOGD("Dropping event because there is no touched foreground window in display %" PRId32
1482 " to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483#endif
1484 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1485 goto Failed;
1486 }
1487
1488 // Permission granted to injection into all touched foreground windows.
1489 injectionPermission = INJECTION_PERMISSION_GRANTED;
1490 }
1491
1492 // Check whether windows listening for outside touches are owned by the same UID. If it is
1493 // set the policy flag that we will not reveal coordinate information to this window.
1494 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1495 sp<InputWindowHandle> foregroundWindowHandle =
1496 mTempTouchState.getFirstForegroundWindowHandle();
1497 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1498 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1499 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1500 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1501 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1502 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1503 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1504 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1505 }
1506 }
1507 }
1508 }
1509
1510 // Ensure all touched foreground windows are ready for new input.
1511 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1512 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1513 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001514 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001515 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001516 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001517 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001518 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001519 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001520 goto Unresponsive;
1521 }
1522 }
1523 }
1524
1525 // If this is the first pointer going down and the touched window has a wallpaper
1526 // then also add the touched wallpaper windows so they are locked in for the duration
1527 // of the touch gesture.
1528 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1529 // engine only supports touch events. We would need to add a mechanism similar
1530 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1531 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1532 sp<InputWindowHandle> foregroundWindowHandle =
1533 mTempTouchState.getFirstForegroundWindowHandle();
1534 if (foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001535 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1536 size_t numWindows = windowHandles.size();
1537 for (size_t i = 0; i < numWindows; i++) {
1538 sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001539 const InputWindowInfo* info = windowHandle->getInfo();
1540 if (info->displayId == displayId
1541 && windowHandle->getInfo()->layoutParamsType
1542 == InputWindowInfo::TYPE_WALLPAPER) {
1543 mTempTouchState.addOrUpdateWindow(windowHandle,
1544 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001545 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546 | InputTarget::FLAG_DISPATCH_AS_IS,
1547 BitSet32(0));
1548 }
1549 }
1550 }
1551 }
1552
1553 // Success! Output targets.
1554 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1555
1556 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1557 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1558 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1559 touchedWindow.pointerIds, inputTargets);
1560 }
1561
1562 // Drop the outside or hover touch windows since we will not care about them
1563 // in the next iteration.
1564 mTempTouchState.filterNonAsIsTouchWindows();
1565
1566Failed:
1567 // Check injection permission once and for all.
1568 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001569 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001570 injectionPermission = INJECTION_PERMISSION_GRANTED;
1571 } else {
1572 injectionPermission = INJECTION_PERMISSION_DENIED;
1573 }
1574 }
1575
1576 // Update final pieces of touch state if the injector had permission.
1577 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1578 if (!wrongDevice) {
1579 if (switchedDevice) {
1580#if DEBUG_FOCUS
1581 ALOGD("Conflicting pointer actions: Switched to a different device.");
1582#endif
1583 *outConflictingPointerActions = true;
1584 }
1585
1586 if (isHoverAction) {
1587 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001588 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001589#if DEBUG_FOCUS
1590 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1591#endif
1592 *outConflictingPointerActions = true;
1593 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001594 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001595 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1596 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001597 mTempTouchState.deviceId = entry->deviceId;
1598 mTempTouchState.source = entry->source;
1599 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001600 }
1601 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1602 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1603 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001604 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1606 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001607 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001608#if DEBUG_FOCUS
1609 ALOGD("Conflicting pointer actions: Down received while already down.");
1610#endif
1611 *outConflictingPointerActions = true;
1612 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1614 // One pointer went up.
1615 if (isSplit) {
1616 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1617 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1618
1619 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1620 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1621 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1622 touchedWindow.pointerIds.clearBit(pointerId);
1623 if (touchedWindow.pointerIds.isEmpty()) {
1624 mTempTouchState.windows.removeAt(i);
1625 continue;
1626 }
1627 }
1628 i += 1;
1629 }
1630 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001631 }
1632
1633 // Save changes unless the action was scroll in which case the temporary touch
1634 // state was only valid for this one action.
1635 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1636 if (mTempTouchState.displayId >= 0) {
1637 if (oldStateIndex >= 0) {
1638 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1639 } else {
1640 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1641 }
1642 } else if (oldStateIndex >= 0) {
1643 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1644 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645 }
1646
1647 // Update hover state.
1648 mLastHoverWindowHandle = newHoverWindowHandle;
1649 }
1650 } else {
1651#if DEBUG_FOCUS
1652 ALOGD("Not updating touch focus because injection was denied.");
1653#endif
1654 }
1655
1656Unresponsive:
1657 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1658 mTempTouchState.reset();
1659
1660 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1661 updateDispatchStatisticsLocked(currentTime, entry,
1662 injectionResult, timeSpentWaitingForApplication);
1663#if DEBUG_FOCUS
1664 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1665 "timeSpentWaitingForApplication=%0.1fms",
1666 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1667#endif
1668 return injectionResult;
1669}
1670
1671void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
1672 int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001673 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1674 if (inputChannel == nullptr) {
1675 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1676 return;
1677 }
1678
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679 inputTargets.push();
1680
1681 const InputWindowInfo* windowInfo = windowHandle->getInfo();
1682 InputTarget& target = inputTargets.editTop();
Arthur Hungceeb5d72018-12-05 16:14:18 +08001683 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001684 target.flags = targetFlags;
1685 target.xOffset = - windowInfo->frameLeft;
1686 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001687 target.globalScaleFactor = windowInfo->globalScaleFactor;
1688 target.windowXScale = windowInfo->windowXScale;
1689 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001690 target.pointerIds = pointerIds;
1691}
1692
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001693void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001694 int32_t displayId, float xOffset, float yOffset) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001695 std::unordered_map<int32_t, Vector<sp<InputChannel>>>::const_iterator it =
1696 mMonitoringChannelsByDisplay.find(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001697
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001698 if (it != mMonitoringChannelsByDisplay.end()) {
1699 const Vector<sp<InputChannel>>& monitoringChannels = it->second;
1700 const size_t numChannels = monitoringChannels.size();
1701 for (size_t i = 0; i < numChannels; i++) {
1702 inputTargets.push();
1703
1704 InputTarget& target = inputTargets.editTop();
1705 target.inputChannel = monitoringChannels[i];
1706 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001707 target.xOffset = xOffset;
1708 target.yOffset = yOffset;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001709 target.pointerIds.clear();
Robert Carre07e1032018-11-26 12:55:53 -08001710 target.globalScaleFactor = 1.0f;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001711 }
1712 } else {
1713 // If there is no monitor channel registered or all monitor channel unregistered,
1714 // the display can't detect the extra system gesture by a copy of input events.
Arthur Hung3b413f22018-10-26 18:05:34 +08001715 ALOGW("There is no monitor channel found in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001716 }
1717}
1718
1719bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1720 const InjectionState* injectionState) {
1721 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001722 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001723 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1724 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001725 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001726 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1727 "owned by uid %d",
1728 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001729 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730 windowHandle->getInfo()->ownerUid);
1731 } else {
1732 ALOGW("Permission denied: injecting event from pid %d uid %d",
1733 injectionState->injectorPid, injectionState->injectorUid);
1734 }
1735 return false;
1736 }
1737 return true;
1738}
1739
1740bool InputDispatcher::isWindowObscuredAtPointLocked(
1741 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1742 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hungb92218b2018-08-14 12:00:21 +08001743 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1744 size_t numWindows = windowHandles.size();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001745 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001746 sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001747 if (otherHandle == windowHandle) {
1748 break;
1749 }
1750
1751 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1752 if (otherInfo->displayId == displayId
1753 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1754 && otherInfo->frameContainsPoint(x, y)) {
1755 return true;
1756 }
1757 }
1758 return false;
1759}
1760
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001761
1762bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1763 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hungb92218b2018-08-14 12:00:21 +08001764 const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001765 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hungb92218b2018-08-14 12:00:21 +08001766 size_t numWindows = windowHandles.size();
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001767 for (size_t i = 0; i < numWindows; i++) {
Arthur Hungb92218b2018-08-14 12:00:21 +08001768 sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001769 if (otherHandle == windowHandle) {
1770 break;
1771 }
1772
1773 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1774 if (otherInfo->displayId == displayId
1775 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1776 && otherInfo->overlaps(windowInfo)) {
1777 return true;
1778 }
1779 }
1780 return false;
1781}
1782
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001783std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001784 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1785 const char* targetType) {
1786 // If the window is paused then keep waiting.
1787 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001788 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001789 }
1790
1791 // If the window's connection is not registered then keep waiting.
Robert Carr5c8a0262018-10-03 16:30:44 -07001792 ssize_t connectionIndex = getConnectionIndexLocked(
1793 getInputChannelLocked(windowHandle->getToken()));
Jeff Brownffb49772014-10-10 19:01:34 -07001794 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001795 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001796 "registered with the input dispatcher. The window may be in the process "
1797 "of being removed.", targetType);
1798 }
1799
1800 // If the connection is dead then keep waiting.
1801 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1802 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001803 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001804 "The window may be in the process of being removed.", targetType,
1805 connection->getStatusLabel());
1806 }
1807
1808 // If the connection is backed up then keep waiting.
1809 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001810 return StringPrintf("Waiting because the %s window's input channel is full. "
Jeff Brownffb49772014-10-10 19:01:34 -07001811 "Outbound queue length: %d. Wait queue length: %d.",
1812 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
1813 }
1814
1815 // Ensure that the dispatch queues aren't too far backed up for this event.
1816 if (eventEntry->type == EventEntry::TYPE_KEY) {
1817 // If the event is a key event, then we must wait for all previous events to
1818 // complete before delivering it because previous events may have the
1819 // side-effect of transferring focus to a different window and we want to
1820 // ensure that the following keys are sent to the new window.
1821 //
1822 // Suppose the user touches a button in a window then immediately presses "A".
1823 // If the button causes a pop-up window to appear then we want to ensure that
1824 // the "A" key is delivered to the new pop-up window. This is because users
1825 // often anticipate pending UI changes when typing on a keyboard.
1826 // To obtain this behavior, we must serialize key events with respect to all
1827 // prior input events.
1828 if (!connection->outboundQueue.isEmpty() || !connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001829 return StringPrintf("Waiting to send key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001830 "finished processing all of the input events that were previously "
1831 "delivered to it. Outbound queue length: %d. Wait queue length: %d.",
1832 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001833 }
Jeff Brownffb49772014-10-10 19:01:34 -07001834 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835 // Touch events can always be sent to a window immediately because the user intended
1836 // to touch whatever was visible at the time. Even if focus changes or a new
1837 // window appears moments later, the touch event was meant to be delivered to
1838 // whatever window happened to be on screen at the time.
1839 //
1840 // Generic motion events, such as trackball or joystick events are a little trickier.
1841 // Like key events, generic motion events are delivered to the focused window.
1842 // Unlike key events, generic motion events don't tend to transfer focus to other
1843 // windows and it is not important for them to be serialized. So we prefer to deliver
1844 // generic motion events as soon as possible to improve efficiency and reduce lag
1845 // through batching.
1846 //
1847 // The one case where we pause input event delivery is when the wait queue is piling
1848 // up with lots of events because the application is not responding.
1849 // This condition ensures that ANRs are detected reliably.
1850 if (!connection->waitQueue.isEmpty()
1851 && currentTime >= connection->waitQueue.head->deliveryTime
1852 + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001853 return StringPrintf("Waiting to send non-key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001854 "finished processing certain input events that were delivered to it over "
1855 "%0.1fms ago. Wait queue length: %d. Wait queue head age: %0.1fms.",
1856 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1857 connection->waitQueue.count(),
1858 (currentTime - connection->waitQueue.head->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859 }
1860 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001861 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862}
1863
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001864std::string InputDispatcher::getApplicationWindowLabelLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001865 const sp<InputApplicationHandle>& applicationHandle,
1866 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001867 if (applicationHandle != nullptr) {
1868 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001869 std::string label(applicationHandle->getName());
1870 label += " - ";
1871 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001872 return label;
1873 } else {
1874 return applicationHandle->getName();
1875 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001876 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001877 return windowHandle->getName();
1878 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001879 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001880 }
1881}
1882
1883void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001884 int32_t displayId = getTargetDisplayId(eventEntry);
1885 sp<InputWindowHandle> focusedWindowHandle =
1886 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1887 if (focusedWindowHandle != nullptr) {
1888 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001889 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1890#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001891 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892#endif
1893 return;
1894 }
1895 }
1896
1897 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1898 switch (eventEntry->type) {
1899 case EventEntry::TYPE_MOTION: {
1900 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1901 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1902 return;
1903 }
1904
1905 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1906 eventType = USER_ACTIVITY_EVENT_TOUCH;
1907 }
1908 break;
1909 }
1910 case EventEntry::TYPE_KEY: {
1911 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1912 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1913 return;
1914 }
1915 eventType = USER_ACTIVITY_EVENT_BUTTON;
1916 break;
1917 }
1918 }
1919
1920 CommandEntry* commandEntry = postCommandLocked(
1921 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1922 commandEntry->eventTime = eventEntry->eventTime;
1923 commandEntry->userActivityEventType = eventType;
1924}
1925
1926void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1927 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1928#if DEBUG_DISPATCH_CYCLE
1929 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08001930 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
1931 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001932 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08001934 inputTarget->globalScaleFactor,
1935 inputTarget->windowXScale, inputTarget->windowYScale,
1936 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937#endif
1938
1939 // Skip this event if the connection status is not normal.
1940 // We don't want to enqueue additional outbound events if the connection is broken.
1941 if (connection->status != Connection::STATUS_NORMAL) {
1942#if DEBUG_DISPATCH_CYCLE
1943 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001944 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001945#endif
1946 return;
1947 }
1948
1949 // Split a motion event if needed.
1950 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
1951 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
1952
1953 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1954 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1955 MotionEntry* splitMotionEntry = splitMotionEvent(
1956 originalMotionEntry, inputTarget->pointerIds);
1957 if (!splitMotionEntry) {
1958 return; // split event was dropped
1959 }
1960#if DEBUG_FOCUS
1961 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08001962 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001963 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1964#endif
1965 enqueueDispatchEntriesLocked(currentTime, connection,
1966 splitMotionEntry, inputTarget);
1967 splitMotionEntry->release();
1968 return;
1969 }
1970 }
1971
1972 // Not splitting. Enqueue dispatch entries for the event as is.
1973 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
1974}
1975
1976void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
1977 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1978 bool wasEmpty = connection->outboundQueue.isEmpty();
1979
1980 // Enqueue dispatch entries for the requested modes.
1981 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1982 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
1983 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1984 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
1985 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1986 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
1987 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1988 InputTarget::FLAG_DISPATCH_AS_IS);
1989 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1990 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
1991 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1992 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
1993
1994 // If the outbound queue was previously empty, start the dispatch cycle going.
1995 if (wasEmpty && !connection->outboundQueue.isEmpty()) {
1996 startDispatchCycleLocked(currentTime, connection);
1997 }
1998}
1999
2000void InputDispatcher::enqueueDispatchEntryLocked(
2001 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2002 int32_t dispatchMode) {
2003 int32_t inputTargetFlags = inputTarget->flags;
2004 if (!(inputTargetFlags & dispatchMode)) {
2005 return;
2006 }
2007 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2008
2009 // This is a new event.
2010 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2011 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2012 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002013 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2014 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002015
2016 // Apply target flags and update the connection's input state.
2017 switch (eventEntry->type) {
2018 case EventEntry::TYPE_KEY: {
2019 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2020 dispatchEntry->resolvedAction = keyEntry->action;
2021 dispatchEntry->resolvedFlags = keyEntry->flags;
2022
2023 if (!connection->inputState.trackKey(keyEntry,
2024 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2025#if DEBUG_DISPATCH_CYCLE
2026 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002027 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002028#endif
2029 delete dispatchEntry;
2030 return; // skip the inconsistent event
2031 }
2032 break;
2033 }
2034
2035 case EventEntry::TYPE_MOTION: {
2036 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2037 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2038 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2039 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2040 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2041 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2042 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2043 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2044 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2045 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2046 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2047 } else {
2048 dispatchEntry->resolvedAction = motionEntry->action;
2049 }
2050 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2051 && !connection->inputState.isHovering(
2052 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2053#if DEBUG_DISPATCH_CYCLE
2054 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002055 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056#endif
2057 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2058 }
2059
2060 dispatchEntry->resolvedFlags = motionEntry->flags;
2061 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2062 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2063 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002064 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2065 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067
2068 if (!connection->inputState.trackMotion(motionEntry,
2069 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2070#if DEBUG_DISPATCH_CYCLE
2071 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002072 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002073#endif
2074 delete dispatchEntry;
2075 return; // skip the inconsistent event
2076 }
2077 break;
2078 }
2079 }
2080
2081 // Remember that we are waiting for this dispatch to complete.
2082 if (dispatchEntry->hasForegroundTarget()) {
2083 incrementPendingForegroundDispatchesLocked(eventEntry);
2084 }
2085
2086 // Enqueue the dispatch entry.
2087 connection->outboundQueue.enqueueAtTail(dispatchEntry);
2088 traceOutboundQueueLengthLocked(connection);
2089}
2090
2091void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2092 const sp<Connection>& connection) {
2093#if DEBUG_DISPATCH_CYCLE
2094 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002095 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002096#endif
2097
2098 while (connection->status == Connection::STATUS_NORMAL
2099 && !connection->outboundQueue.isEmpty()) {
2100 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
2101 dispatchEntry->deliveryTime = currentTime;
2102
2103 // Publish the event.
2104 status_t status;
2105 EventEntry* eventEntry = dispatchEntry->eventEntry;
2106 switch (eventEntry->type) {
2107 case EventEntry::TYPE_KEY: {
2108 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2109
2110 // Publish the key event.
2111 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002112 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002113 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2114 keyEntry->keyCode, keyEntry->scanCode,
2115 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2116 keyEntry->eventTime);
2117 break;
2118 }
2119
2120 case EventEntry::TYPE_MOTION: {
2121 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2122
2123 PointerCoords scaledCoords[MAX_POINTERS];
2124 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2125
2126 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002127 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002128 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2129 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002130 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2131 float wxs = dispatchEntry->windowXScale;
2132 float wys = dispatchEntry->windowYScale;
2133 xOffset = dispatchEntry->xOffset * wxs;
2134 yOffset = dispatchEntry->yOffset * wys;
2135 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002136 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002137 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002138 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139 }
2140 usingCoords = scaledCoords;
2141 }
2142 } else {
2143 xOffset = 0.0f;
2144 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145
2146 // We don't want the dispatch target to know.
2147 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002148 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149 scaledCoords[i].clear();
2150 }
2151 usingCoords = scaledCoords;
2152 }
2153 }
2154
2155 // Publish the motion event.
2156 status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
Tarandeep Singh58641502017-07-31 10:51:54 -07002157 motionEntry->deviceId, motionEntry->source, motionEntry->displayId,
Michael Wright7b159c92015-05-14 14:48:03 +01002158 dispatchEntry->resolvedAction, motionEntry->actionButton,
2159 dispatchEntry->resolvedFlags, motionEntry->edgeFlags,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08002160 motionEntry->metaState, motionEntry->buttonState, motionEntry->classification,
Michael Wright7b159c92015-05-14 14:48:03 +01002161 xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162 motionEntry->downTime, motionEntry->eventTime,
2163 motionEntry->pointerCount, motionEntry->pointerProperties,
2164 usingCoords);
2165 break;
2166 }
2167
2168 default:
2169 ALOG_ASSERT(false);
2170 return;
2171 }
2172
2173 // Check the result.
2174 if (status) {
2175 if (status == WOULD_BLOCK) {
2176 if (connection->waitQueue.isEmpty()) {
2177 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2178 "This is unexpected because the wait queue is empty, so the pipe "
2179 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002180 "event to it, status=%d", connection->getInputChannelName().c_str(),
2181 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002182 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2183 } else {
2184 // Pipe is full and we are waiting for the app to finish process some events
2185 // before sending more events to it.
2186#if DEBUG_DISPATCH_CYCLE
2187 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2188 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002189 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002190#endif
2191 connection->inputPublisherBlocked = true;
2192 }
2193 } else {
2194 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002195 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002196 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2197 }
2198 return;
2199 }
2200
2201 // Re-enqueue the event on the wait queue.
2202 connection->outboundQueue.dequeue(dispatchEntry);
2203 traceOutboundQueueLengthLocked(connection);
2204 connection->waitQueue.enqueueAtTail(dispatchEntry);
2205 traceWaitQueueLengthLocked(connection);
2206 }
2207}
2208
2209void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2210 const sp<Connection>& connection, uint32_t seq, bool handled) {
2211#if DEBUG_DISPATCH_CYCLE
2212 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002213 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214#endif
2215
2216 connection->inputPublisherBlocked = false;
2217
2218 if (connection->status == Connection::STATUS_BROKEN
2219 || connection->status == Connection::STATUS_ZOMBIE) {
2220 return;
2221 }
2222
2223 // Notify other system components and prepare to start the next dispatch cycle.
2224 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2225}
2226
2227void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2228 const sp<Connection>& connection, bool notify) {
2229#if DEBUG_DISPATCH_CYCLE
2230 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002231 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002232#endif
2233
2234 // Clear the dispatch queues.
2235 drainDispatchQueueLocked(&connection->outboundQueue);
2236 traceOutboundQueueLengthLocked(connection);
2237 drainDispatchQueueLocked(&connection->waitQueue);
2238 traceWaitQueueLengthLocked(connection);
2239
2240 // The connection appears to be unrecoverably broken.
2241 // Ignore already broken or zombie connections.
2242 if (connection->status == Connection::STATUS_NORMAL) {
2243 connection->status = Connection::STATUS_BROKEN;
2244
2245 if (notify) {
2246 // Notify other system components.
2247 onDispatchCycleBrokenLocked(currentTime, connection);
2248 }
2249 }
2250}
2251
2252void InputDispatcher::drainDispatchQueueLocked(Queue<DispatchEntry>* queue) {
2253 while (!queue->isEmpty()) {
2254 DispatchEntry* dispatchEntry = queue->dequeueAtHead();
2255 releaseDispatchEntryLocked(dispatchEntry);
2256 }
2257}
2258
2259void InputDispatcher::releaseDispatchEntryLocked(DispatchEntry* dispatchEntry) {
2260 if (dispatchEntry->hasForegroundTarget()) {
2261 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
2262 }
2263 delete dispatchEntry;
2264}
2265
2266int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2267 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2268
2269 { // acquire lock
2270 AutoMutex _l(d->mLock);
2271
2272 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2273 if (connectionIndex < 0) {
2274 ALOGE("Received spurious receive callback for unknown input channel. "
2275 "fd=%d, events=0x%x", fd, events);
2276 return 0; // remove the callback
2277 }
2278
2279 bool notify;
2280 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2281 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2282 if (!(events & ALOOPER_EVENT_INPUT)) {
2283 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002284 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002285 return 1;
2286 }
2287
2288 nsecs_t currentTime = now();
2289 bool gotOne = false;
2290 status_t status;
2291 for (;;) {
2292 uint32_t seq;
2293 bool handled;
2294 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2295 if (status) {
2296 break;
2297 }
2298 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2299 gotOne = true;
2300 }
2301 if (gotOne) {
2302 d->runCommandsLockedInterruptible();
2303 if (status == WOULD_BLOCK) {
2304 return 1;
2305 }
2306 }
2307
2308 notify = status != DEAD_OBJECT || !connection->monitor;
2309 if (notify) {
2310 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002311 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002312 }
2313 } else {
2314 // Monitor channels are never explicitly unregistered.
2315 // We do it automatically when the remote endpoint is closed so don't warn
2316 // about them.
2317 notify = !connection->monitor;
2318 if (notify) {
2319 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002320 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002321 }
2322 }
2323
2324 // Unregister the channel.
2325 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2326 return 0; // remove the callback
2327 } // release lock
2328}
2329
2330void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2331 const CancelationOptions& options) {
2332 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2333 synthesizeCancelationEventsForConnectionLocked(
2334 mConnectionsByFd.valueAt(i), options);
2335 }
2336}
2337
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002338void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2339 const CancelationOptions& options) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002340 for (auto& it : mMonitoringChannelsByDisplay) {
2341 const Vector<sp<InputChannel>>& monitoringChannels = it.second;
2342 const size_t numChannels = monitoringChannels.size();
2343 for (size_t i = 0; i < numChannels; i++) {
2344 synthesizeCancelationEventsForInputChannelLocked(monitoringChannels[i], options);
2345 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002346 }
2347}
2348
Michael Wrightd02c5b62014-02-10 15:10:22 -08002349void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2350 const sp<InputChannel>& channel, const CancelationOptions& options) {
2351 ssize_t index = getConnectionIndexLocked(channel);
2352 if (index >= 0) {
2353 synthesizeCancelationEventsForConnectionLocked(
2354 mConnectionsByFd.valueAt(index), options);
2355 }
2356}
2357
2358void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2359 const sp<Connection>& connection, const CancelationOptions& options) {
2360 if (connection->status == Connection::STATUS_BROKEN) {
2361 return;
2362 }
2363
2364 nsecs_t currentTime = now();
2365
2366 Vector<EventEntry*> cancelationEvents;
2367 connection->inputState.synthesizeCancelationEvents(currentTime,
2368 cancelationEvents, options);
2369
2370 if (!cancelationEvents.isEmpty()) {
2371#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002372 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002373 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002374 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002375 options.reason, options.mode);
2376#endif
2377 for (size_t i = 0; i < cancelationEvents.size(); i++) {
2378 EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
2379 switch (cancelationEventEntry->type) {
2380 case EventEntry::TYPE_KEY:
2381 logOutboundKeyDetailsLocked("cancel - ",
2382 static_cast<KeyEntry*>(cancelationEventEntry));
2383 break;
2384 case EventEntry::TYPE_MOTION:
2385 logOutboundMotionDetailsLocked("cancel - ",
2386 static_cast<MotionEntry*>(cancelationEventEntry));
2387 break;
2388 }
2389
2390 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002391 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2392 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002393 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002394 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2395 target.xOffset = -windowInfo->frameLeft;
2396 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002397 target.globalScaleFactor = windowInfo->globalScaleFactor;
2398 target.windowXScale = windowInfo->windowXScale;
2399 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002400 } else {
2401 target.xOffset = 0;
2402 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002403 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002404 }
2405 target.inputChannel = connection->inputChannel;
2406 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2407
2408 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2409 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2410
2411 cancelationEventEntry->release();
2412 }
2413
2414 startDispatchCycleLocked(currentTime, connection);
2415 }
2416}
2417
2418InputDispatcher::MotionEntry*
2419InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2420 ALOG_ASSERT(pointerIds.value != 0);
2421
2422 uint32_t splitPointerIndexMap[MAX_POINTERS];
2423 PointerProperties splitPointerProperties[MAX_POINTERS];
2424 PointerCoords splitPointerCoords[MAX_POINTERS];
2425
2426 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2427 uint32_t splitPointerCount = 0;
2428
2429 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2430 originalPointerIndex++) {
2431 const PointerProperties& pointerProperties =
2432 originalMotionEntry->pointerProperties[originalPointerIndex];
2433 uint32_t pointerId = uint32_t(pointerProperties.id);
2434 if (pointerIds.hasBit(pointerId)) {
2435 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2436 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2437 splitPointerCoords[splitPointerCount].copyFrom(
2438 originalMotionEntry->pointerCoords[originalPointerIndex]);
2439 splitPointerCount += 1;
2440 }
2441 }
2442
2443 if (splitPointerCount != pointerIds.count()) {
2444 // This is bad. We are missing some of the pointers that we expected to deliver.
2445 // Most likely this indicates that we received an ACTION_MOVE events that has
2446 // different pointer ids than we expected based on the previous ACTION_DOWN
2447 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2448 // in this way.
2449 ALOGW("Dropping split motion event because the pointer count is %d but "
2450 "we expected there to be %d pointers. This probably means we received "
2451 "a broken sequence of pointer ids from the input device.",
2452 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002453 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002454 }
2455
2456 int32_t action = originalMotionEntry->action;
2457 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2458 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2459 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2460 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2461 const PointerProperties& pointerProperties =
2462 originalMotionEntry->pointerProperties[originalPointerIndex];
2463 uint32_t pointerId = uint32_t(pointerProperties.id);
2464 if (pointerIds.hasBit(pointerId)) {
2465 if (pointerIds.count() == 1) {
2466 // The first/last pointer went down/up.
2467 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2468 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2469 } else {
2470 // A secondary pointer went down/up.
2471 uint32_t splitPointerIndex = 0;
2472 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2473 splitPointerIndex += 1;
2474 }
2475 action = maskedAction | (splitPointerIndex
2476 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2477 }
2478 } else {
2479 // An unrelated pointer changed.
2480 action = AMOTION_EVENT_ACTION_MOVE;
2481 }
2482 }
2483
2484 MotionEntry* splitMotionEntry = new MotionEntry(
Prabir Pradhan42611e02018-11-27 14:04:02 -08002485 originalMotionEntry->sequenceNum,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002486 originalMotionEntry->eventTime,
2487 originalMotionEntry->deviceId,
2488 originalMotionEntry->source,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002489 originalMotionEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002490 originalMotionEntry->policyFlags,
2491 action,
Michael Wright7b159c92015-05-14 14:48:03 +01002492 originalMotionEntry->actionButton,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002493 originalMotionEntry->flags,
2494 originalMotionEntry->metaState,
2495 originalMotionEntry->buttonState,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08002496 originalMotionEntry->classification,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497 originalMotionEntry->edgeFlags,
2498 originalMotionEntry->xPrecision,
2499 originalMotionEntry->yPrecision,
2500 originalMotionEntry->downTime,
Jeff Brownf086ddb2014-02-11 14:28:48 -08002501 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002502
2503 if (originalMotionEntry->injectionState) {
2504 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2505 splitMotionEntry->injectionState->refCount += 1;
2506 }
2507
2508 return splitMotionEntry;
2509}
2510
2511void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2512#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002513 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002514#endif
2515
2516 bool needWake;
2517 { // acquire lock
2518 AutoMutex _l(mLock);
2519
Prabir Pradhan42611e02018-11-27 14:04:02 -08002520 ConfigurationChangedEntry* newEntry =
2521 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002522 needWake = enqueueInboundEventLocked(newEntry);
2523 } // release lock
2524
2525 if (needWake) {
2526 mLooper->wake();
2527 }
2528}
2529
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002530/**
2531 * If one of the meta shortcuts is detected, process them here:
2532 * Meta + Backspace -> generate BACK
2533 * Meta + Enter -> generate HOME
2534 * This will potentially overwrite keyCode and metaState.
2535 */
2536void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2537 int32_t& keyCode, int32_t& metaState) {
2538 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2539 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2540 if (keyCode == AKEYCODE_DEL) {
2541 newKeyCode = AKEYCODE_BACK;
2542 } else if (keyCode == AKEYCODE_ENTER) {
2543 newKeyCode = AKEYCODE_HOME;
2544 }
2545 if (newKeyCode != AKEYCODE_UNKNOWN) {
2546 AutoMutex _l(mLock);
2547 struct KeyReplacement replacement = {keyCode, deviceId};
2548 mReplacedKeys.add(replacement, newKeyCode);
2549 keyCode = newKeyCode;
2550 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2551 }
2552 } else if (action == AKEY_EVENT_ACTION_UP) {
2553 // In order to maintain a consistent stream of up and down events, check to see if the key
2554 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2555 // even if the modifier was released between the down and the up events.
2556 AutoMutex _l(mLock);
2557 struct KeyReplacement replacement = {keyCode, deviceId};
2558 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2559 if (index >= 0) {
2560 keyCode = mReplacedKeys.valueAt(index);
2561 mReplacedKeys.removeItemsAt(index);
2562 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2563 }
2564 }
2565}
2566
Michael Wrightd02c5b62014-02-10 15:10:22 -08002567void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2568#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002569 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002570 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002571 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002572 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002573 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002574 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002575#endif
2576 if (!validateKeyEvent(args->action)) {
2577 return;
2578 }
2579
2580 uint32_t policyFlags = args->policyFlags;
2581 int32_t flags = args->flags;
2582 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002583 // InputDispatcher tracks and generates key repeats on behalf of
2584 // whatever notifies it, so repeatCount should always be set to 0
2585 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2587 policyFlags |= POLICY_FLAG_VIRTUAL;
2588 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2589 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002590 if (policyFlags & POLICY_FLAG_FUNCTION) {
2591 metaState |= AMETA_FUNCTION_ON;
2592 }
2593
2594 policyFlags |= POLICY_FLAG_TRUSTED;
2595
Michael Wright78f24442014-08-06 15:55:28 -07002596 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002597 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002598
Michael Wrightd02c5b62014-02-10 15:10:22 -08002599 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002600 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002601 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002602 args->downTime, args->eventTime);
2603
Michael Wright2b3c3302018-03-02 17:19:13 +00002604 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002605 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002606 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2607 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2608 std::to_string(t.duration().count()).c_str());
2609 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002610
Michael Wrightd02c5b62014-02-10 15:10:22 -08002611 bool needWake;
2612 { // acquire lock
2613 mLock.lock();
2614
2615 if (shouldSendKeyToInputFilterLocked(args)) {
2616 mLock.unlock();
2617
2618 policyFlags |= POLICY_FLAG_FILTERED;
2619 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2620 return; // event was consumed by the filter
2621 }
2622
2623 mLock.lock();
2624 }
2625
Prabir Pradhan42611e02018-11-27 14:04:02 -08002626 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002627 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002628 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629 metaState, repeatCount, args->downTime);
2630
2631 needWake = enqueueInboundEventLocked(newEntry);
2632 mLock.unlock();
2633 } // release lock
2634
2635 if (needWake) {
2636 mLooper->wake();
2637 }
2638}
2639
2640bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2641 return mInputFilterEnabled;
2642}
2643
2644void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2645#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002646 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2647 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01002648 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08002649 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
2650 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002651 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002652 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002653 for (uint32_t i = 0; i < args->pointerCount; i++) {
2654 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2655 "x=%f, y=%f, pressure=%f, size=%f, "
2656 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2657 "orientation=%f",
2658 i, args->pointerProperties[i].id,
2659 args->pointerProperties[i].toolType,
2660 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2661 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2662 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2663 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2664 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2665 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2666 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2667 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2668 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2669 }
2670#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002671 if (!validateMotionEvent(args->action, args->actionButton,
2672 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002673 return;
2674 }
2675
2676 uint32_t policyFlags = args->policyFlags;
2677 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002678
2679 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002680 mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002681 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2682 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2683 std::to_string(t.duration().count()).c_str());
2684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685
2686 bool needWake;
2687 { // acquire lock
2688 mLock.lock();
2689
2690 if (shouldSendMotionToInputFilterLocked(args)) {
2691 mLock.unlock();
2692
2693 MotionEvent event;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002694 event.initialize(args->deviceId, args->source, args->displayId,
2695 args->action, args->actionButton,
Michael Wright7b159c92015-05-14 14:48:03 +01002696 args->flags, args->edgeFlags, args->metaState, args->buttonState,
Siarhei Vishniakouae478d32019-01-03 14:45:18 -08002697 args->classification, 0, 0, args->xPrecision, args->yPrecision,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698 args->downTime, args->eventTime,
2699 args->pointerCount, args->pointerProperties, args->pointerCoords);
2700
2701 policyFlags |= POLICY_FLAG_FILTERED;
2702 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2703 return; // event was consumed by the filter
2704 }
2705
2706 mLock.lock();
2707 }
2708
2709 // Just enqueue a new motion event.
Prabir Pradhan42611e02018-11-27 14:04:02 -08002710 MotionEntry* newEntry = new MotionEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002711 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002712 args->action, args->actionButton, args->flags,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08002713 args->metaState, args->buttonState, args->classification,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002714 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
Jeff Brownf086ddb2014-02-11 14:28:48 -08002715 args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002716
2717 needWake = enqueueInboundEventLocked(newEntry);
2718 mLock.unlock();
2719 } // release lock
2720
2721 if (needWake) {
2722 mLooper->wake();
2723 }
2724}
2725
2726bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
2727 // TODO: support sending secondary display events to input filter
2728 return mInputFilterEnabled && isMainDisplay(args->displayId);
2729}
2730
2731void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2732#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002733 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2734 "switchMask=0x%08x",
2735 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002736#endif
2737
2738 uint32_t policyFlags = args->policyFlags;
2739 policyFlags |= POLICY_FLAG_TRUSTED;
2740 mPolicy->notifySwitch(args->eventTime,
2741 args->switchValues, args->switchMask, policyFlags);
2742}
2743
2744void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2745#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002746 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002747 args->eventTime, args->deviceId);
2748#endif
2749
2750 bool needWake;
2751 { // acquire lock
2752 AutoMutex _l(mLock);
2753
Prabir Pradhan42611e02018-11-27 14:04:02 -08002754 DeviceResetEntry* newEntry =
2755 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002756 needWake = enqueueInboundEventLocked(newEntry);
2757 } // release lock
2758
2759 if (needWake) {
2760 mLooper->wake();
2761 }
2762}
2763
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002764int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2766 uint32_t policyFlags) {
2767#if DEBUG_INBOUND_EVENT_DETAILS
2768 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002769 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2770 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002771#endif
2772
2773 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2774
2775 policyFlags |= POLICY_FLAG_INJECTED;
2776 if (hasInjectionPermission(injectorPid, injectorUid)) {
2777 policyFlags |= POLICY_FLAG_TRUSTED;
2778 }
2779
2780 EventEntry* firstInjectedEntry;
2781 EventEntry* lastInjectedEntry;
2782 switch (event->getType()) {
2783 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002784 KeyEvent keyEvent;
2785 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2786 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002787 if (! validateKeyEvent(action)) {
2788 return INPUT_EVENT_INJECTION_FAILED;
2789 }
2790
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002791 int32_t flags = keyEvent.getFlags();
2792 int32_t keyCode = keyEvent.getKeyCode();
2793 int32_t metaState = keyEvent.getMetaState();
2794 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2795 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002796 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002797 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002798 keyEvent.getDownTime(), keyEvent.getEventTime());
2799
Michael Wrightd02c5b62014-02-10 15:10:22 -08002800 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2801 policyFlags |= POLICY_FLAG_VIRTUAL;
2802 }
2803
2804 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002805 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002806 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002807 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2808 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2809 std::to_string(t.duration().count()).c_str());
2810 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002811 }
2812
Michael Wrightd02c5b62014-02-10 15:10:22 -08002813 mLock.lock();
Prabir Pradhan42611e02018-11-27 14:04:02 -08002814 firstInjectedEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002815 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002816 policyFlags, action, flags,
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002817 keyEvent.getKeyCode(), keyEvent.getScanCode(), keyEvent.getMetaState(),
2818 keyEvent.getRepeatCount(), keyEvent.getDownTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819 lastInjectedEntry = firstInjectedEntry;
2820 break;
2821 }
2822
2823 case AINPUT_EVENT_TYPE_MOTION: {
2824 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002825 int32_t action = motionEvent->getAction();
2826 size_t pointerCount = motionEvent->getPointerCount();
2827 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002828 int32_t actionButton = motionEvent->getActionButton();
2829 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830 return INPUT_EVENT_INJECTION_FAILED;
2831 }
2832
2833 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2834 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002835 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002836 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002837 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2838 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2839 std::to_string(t.duration().count()).c_str());
2840 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841 }
2842
2843 mLock.lock();
2844 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2845 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Prabir Pradhan42611e02018-11-27 14:04:02 -08002846 firstInjectedEntry = new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002847 motionEvent->getDeviceId(), motionEvent->getSource(), motionEvent->getDisplayId(),
2848 policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002849 action, actionButton, motionEvent->getFlags(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002850 motionEvent->getMetaState(), motionEvent->getButtonState(),
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08002851 motionEvent->getClassification(), motionEvent->getEdgeFlags(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002852 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002853 motionEvent->getDownTime(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08002854 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2855 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002856 lastInjectedEntry = firstInjectedEntry;
2857 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2858 sampleEventTimes += 1;
2859 samplePointerCoords += pointerCount;
Prabir Pradhan42611e02018-11-27 14:04:02 -08002860 MotionEntry* nextInjectedEntry = new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM,
2861 *sampleEventTimes,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002862 motionEvent->getDeviceId(), motionEvent->getSource(),
2863 motionEvent->getDisplayId(), policyFlags,
Michael Wright7b159c92015-05-14 14:48:03 +01002864 action, actionButton, motionEvent->getFlags(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002865 motionEvent->getMetaState(), motionEvent->getButtonState(),
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08002866 motionEvent->getClassification(), motionEvent->getEdgeFlags(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002867 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002868 motionEvent->getDownTime(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08002869 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2870 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002871 lastInjectedEntry->next = nextInjectedEntry;
2872 lastInjectedEntry = nextInjectedEntry;
2873 }
2874 break;
2875 }
2876
2877 default:
2878 ALOGW("Cannot inject event of type %d", event->getType());
2879 return INPUT_EVENT_INJECTION_FAILED;
2880 }
2881
2882 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
2883 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2884 injectionState->injectionIsAsync = true;
2885 }
2886
2887 injectionState->refCount += 1;
2888 lastInjectedEntry->injectionState = injectionState;
2889
2890 bool needWake = false;
Yi Kong9b14ac62018-07-17 13:48:38 -07002891 for (EventEntry* entry = firstInjectedEntry; entry != nullptr; ) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002892 EventEntry* nextEntry = entry->next;
2893 needWake |= enqueueInboundEventLocked(entry);
2894 entry = nextEntry;
2895 }
2896
2897 mLock.unlock();
2898
2899 if (needWake) {
2900 mLooper->wake();
2901 }
2902
2903 int32_t injectionResult;
2904 { // acquire lock
2905 AutoMutex _l(mLock);
2906
2907 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2908 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2909 } else {
2910 for (;;) {
2911 injectionResult = injectionState->injectionResult;
2912 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2913 break;
2914 }
2915
2916 nsecs_t remainingTimeout = endTime - now();
2917 if (remainingTimeout <= 0) {
2918#if DEBUG_INJECTION
2919 ALOGD("injectInputEvent - Timed out waiting for injection result "
2920 "to become available.");
2921#endif
2922 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2923 break;
2924 }
2925
2926 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2927 }
2928
2929 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2930 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
2931 while (injectionState->pendingForegroundDispatches != 0) {
2932#if DEBUG_INJECTION
2933 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
2934 injectionState->pendingForegroundDispatches);
2935#endif
2936 nsecs_t remainingTimeout = endTime - now();
2937 if (remainingTimeout <= 0) {
2938#if DEBUG_INJECTION
2939 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
2940 "dispatches to finish.");
2941#endif
2942 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2943 break;
2944 }
2945
2946 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2947 }
2948 }
2949 }
2950
2951 injectionState->release();
2952 } // release lock
2953
2954#if DEBUG_INJECTION
2955 ALOGD("injectInputEvent - Finished with result %d. "
2956 "injectorPid=%d, injectorUid=%d",
2957 injectionResult, injectorPid, injectorUid);
2958#endif
2959
2960 return injectionResult;
2961}
2962
2963bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2964 return injectorUid == 0
2965 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2966}
2967
2968void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
2969 InjectionState* injectionState = entry->injectionState;
2970 if (injectionState) {
2971#if DEBUG_INJECTION
2972 ALOGD("Setting input event injection result to %d. "
2973 "injectorPid=%d, injectorUid=%d",
2974 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
2975#endif
2976
2977 if (injectionState->injectionIsAsync
2978 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
2979 // Log the outcome since the injector did not wait for the injection result.
2980 switch (injectionResult) {
2981 case INPUT_EVENT_INJECTION_SUCCEEDED:
2982 ALOGV("Asynchronous input event injection succeeded.");
2983 break;
2984 case INPUT_EVENT_INJECTION_FAILED:
2985 ALOGW("Asynchronous input event injection failed.");
2986 break;
2987 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2988 ALOGW("Asynchronous input event injection permission denied.");
2989 break;
2990 case INPUT_EVENT_INJECTION_TIMED_OUT:
2991 ALOGW("Asynchronous input event injection timed out.");
2992 break;
2993 }
2994 }
2995
2996 injectionState->injectionResult = injectionResult;
2997 mInjectionResultAvailableCondition.broadcast();
2998 }
2999}
3000
3001void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
3002 InjectionState* injectionState = entry->injectionState;
3003 if (injectionState) {
3004 injectionState->pendingForegroundDispatches += 1;
3005 }
3006}
3007
3008void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
3009 InjectionState* injectionState = entry->injectionState;
3010 if (injectionState) {
3011 injectionState->pendingForegroundDispatches -= 1;
3012
3013 if (injectionState->pendingForegroundDispatches == 0) {
3014 mInjectionSyncFinishedCondition.broadcast();
3015 }
3016 }
3017}
3018
Arthur Hungb92218b2018-08-14 12:00:21 +08003019Vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(int32_t displayId) const {
3020 std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>>::const_iterator it =
3021 mWindowHandlesByDisplay.find(displayId);
3022 if(it != mWindowHandlesByDisplay.end()) {
3023 return it->second;
3024 }
3025
3026 // Return an empty one if nothing found.
3027 return Vector<sp<InputWindowHandle>>();
3028}
3029
Michael Wrightd02c5b62014-02-10 15:10:22 -08003030sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003031 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003032 for (auto& it : mWindowHandlesByDisplay) {
3033 const Vector<sp<InputWindowHandle>> windowHandles = it.second;
3034 size_t numWindows = windowHandles.size();
3035 for (size_t i = 0; i < numWindows; i++) {
3036 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
chaviwfbe5d9c2018-12-26 12:23:37 -08003037 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003038 return windowHandle;
3039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003040 }
3041 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003042 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043}
3044
3045bool InputDispatcher::hasWindowHandleLocked(
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003046 const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003047 for (auto& it : mWindowHandlesByDisplay) {
3048 const Vector<sp<InputWindowHandle>> windowHandles = it.second;
3049 size_t numWindows = windowHandles.size();
3050 for (size_t i = 0; i < numWindows; i++) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003051 if (windowHandles.itemAt(i)->getToken()
3052 == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003053 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003054 ALOGE("Found window %s in display %" PRId32
3055 ", but it should belong to display %" PRId32,
3056 windowHandle->getName().c_str(), it.first,
3057 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003058 }
3059 return true;
3060 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003061 }
3062 }
3063 return false;
3064}
3065
Robert Carr5c8a0262018-10-03 16:30:44 -07003066sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3067 size_t count = mInputChannelsByToken.count(token);
3068 if (count == 0) {
3069 return nullptr;
3070 }
3071 return mInputChannelsByToken.at(token);
3072}
3073
Arthur Hungb92218b2018-08-14 12:00:21 +08003074/**
3075 * Called from InputManagerService, update window handle list by displayId that can receive input.
3076 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3077 * If set an empty list, remove all handles from the specific display.
3078 * For focused handle, check if need to change and send a cancel event to previous one.
3079 * For removed handle, check if need to send a cancel event if already in touch.
3080 */
3081void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& inputWindowHandles,
3082 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003083#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003084 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003085#endif
3086 { // acquire lock
3087 AutoMutex _l(mLock);
3088
Arthur Hungb92218b2018-08-14 12:00:21 +08003089 // Copy old handles for release if they are no longer present.
3090 const Vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003091
Tiger Huang721e26f2018-07-24 22:26:19 +08003092 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003093 bool foundHoveredWindow = false;
Arthur Hungb92218b2018-08-14 12:00:21 +08003094
3095 if (inputWindowHandles.isEmpty()) {
3096 // Remove all handles on a display if there are no windows left.
3097 mWindowHandlesByDisplay.erase(displayId);
3098 } else {
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003099 // Since we compare the pointer of input window handles across window updates, we need
3100 // to make sure the handle object for the same window stays unchanged across updates.
3101 const Vector<sp<InputWindowHandle>>& oldHandles = mWindowHandlesByDisplay[displayId];
3102 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3103 for (size_t i = 0; i < oldHandles.size(); i++) {
3104 const sp<InputWindowHandle>& handle = oldHandles.itemAt(i);
3105 oldHandlesByTokens[handle->getToken()] = handle;
3106 }
3107
3108 const size_t numWindows = inputWindowHandles.size();
3109 Vector<sp<InputWindowHandle>> newHandles;
Arthur Hungb92218b2018-08-14 12:00:21 +08003110 for (size_t i = 0; i < numWindows; i++) {
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003111 const sp<InputWindowHandle>& handle = inputWindowHandles.itemAt(i);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003112 if (!handle->updateInfo() || (getInputChannelLocked(handle->getToken()) == nullptr
3113 && handle->getInfo()->portalToDisplayId == ADISPLAY_ID_NONE)) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003114 ALOGE("Window handle %s has no registered input channel",
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003115 handle->getName().c_str());
Arthur Hungb92218b2018-08-14 12:00:21 +08003116 continue;
3117 }
3118
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003119 if (handle->getInfo()->displayId != displayId) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003120 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003121 handle->getName().c_str(), displayId,
3122 handle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003123 continue;
3124 }
3125
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003126 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3127 const sp<InputWindowHandle> oldHandle =
3128 oldHandlesByTokens.at(handle->getToken());
3129 oldHandle->updateFrom(handle);
3130 newHandles.push_back(oldHandle);
3131 } else {
3132 newHandles.push_back(handle);
3133 }
3134 }
3135
3136 for (size_t i = 0; i < newHandles.size(); i++) {
3137 const sp<InputWindowHandle>& windowHandle = newHandles.itemAt(i);
Arthur Hung7ab76b12019-01-09 19:17:20 +08003138 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3139 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus
3140 && windowHandle->getInfo()->visible) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003141 newFocusedWindowHandle = windowHandle;
3142 }
3143 if (windowHandle == mLastHoverWindowHandle) {
3144 foundHoveredWindow = true;
3145 }
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003146 }
Arthur Hungb92218b2018-08-14 12:00:21 +08003147
3148 // Insert or replace
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003149 mWindowHandlesByDisplay[displayId] = newHandles;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003150 }
3151
3152 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003153 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154 }
3155
Tiger Huang721e26f2018-07-24 22:26:19 +08003156 sp<InputWindowHandle> oldFocusedWindowHandle =
3157 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3158
3159 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3160 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003162 ALOGD("Focus left window: %s in display %" PRId32,
3163 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003164#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003165 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3166 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003167 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3169 "focus left window");
3170 synthesizeCancelationEventsForInputChannelLocked(
3171 focusedInputChannel, options);
3172 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003173 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003174 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003175 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003177 ALOGD("Focus entered window: %s in display %" PRId32,
3178 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003179#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003180 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181 }
Robert Carrf759f162018-11-13 12:57:11 -08003182
3183 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003184 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003185 }
3186
Michael Wrightd02c5b62014-02-10 15:10:22 -08003187 }
3188
Arthur Hungb92218b2018-08-14 12:00:21 +08003189 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3190 if (stateIndex >= 0) {
3191 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003192 for (size_t i = 0; i < state.windows.size(); ) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003193 TouchedWindow& touchedWindow = state.windows.editItemAt(i);
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003194 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003195#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003196 ALOGD("Touched window was removed: %s in display %" PRId32,
3197 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003198#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003199 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003200 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003201 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003202 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3203 "touched window was removed");
3204 synthesizeCancelationEventsForInputChannelLocked(
3205 touchedInputChannel, options);
3206 }
Ivan Lozano96f12992017-11-09 14:45:38 -08003207 state.windows.removeAt(i);
3208 } else {
3209 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003210 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003211 }
3212 }
3213
3214 // Release information for windows that are no longer present.
3215 // This ensures that unused input channels are released promptly.
3216 // Otherwise, they might stick around until the window handle is destroyed
3217 // which might not happen until the next GC.
Arthur Hungb92218b2018-08-14 12:00:21 +08003218 size_t numWindows = oldWindowHandles.size();
3219 for (size_t i = 0; i < numWindows; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003220 const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003221 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003223 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003225 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003226 }
3227 }
3228 } // release lock
3229
3230 // Wake up poll loop since it may need to make new input dispatching choices.
3231 mLooper->wake();
3232}
3233
3234void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003235 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003236#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003237 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238#endif
3239 { // acquire lock
3240 AutoMutex _l(mLock);
3241
Tiger Huang721e26f2018-07-24 22:26:19 +08003242 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3243 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003244 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003245 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3246 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003248 oldFocusedApplicationHandle->releaseInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003249 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003250 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003251 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003252 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003253 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003254 oldFocusedApplicationHandle->releaseInfo();
3255 oldFocusedApplicationHandle.clear();
3256 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257 }
3258
3259#if DEBUG_FOCUS
3260 //logDispatchStateLocked();
3261#endif
3262 } // release lock
3263
3264 // Wake up poll loop since it may need to make new input dispatching choices.
3265 mLooper->wake();
3266}
3267
Tiger Huang721e26f2018-07-24 22:26:19 +08003268/**
3269 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3270 * the display not specified.
3271 *
3272 * We track any unreleased events for each window. If a window loses the ability to receive the
3273 * released event, we will send a cancel event to it. So when the focused display is changed, we
3274 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3275 * display. The display-specified events won't be affected.
3276 */
3277void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3278#if DEBUG_FOCUS
3279 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3280#endif
3281 { // acquire lock
3282 AutoMutex _l(mLock);
3283
3284 if (mFocusedDisplayId != displayId) {
3285 sp<InputWindowHandle> oldFocusedWindowHandle =
3286 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3287 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003288 sp<InputChannel> inputChannel =
3289 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003290 if (inputChannel != nullptr) {
3291 CancelationOptions options(
3292 CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS,
3293 "The display which contains this window no longer has focus.");
3294 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3295 }
3296 }
3297 mFocusedDisplayId = displayId;
3298
3299 // Sanity check
3300 sp<InputWindowHandle> newFocusedWindowHandle =
3301 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003302 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003303
Tiger Huang721e26f2018-07-24 22:26:19 +08003304 if (newFocusedWindowHandle == nullptr) {
3305 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3306 if (!mFocusedWindowHandlesByDisplay.empty()) {
3307 ALOGE("But another display has a focused window:");
3308 for (auto& it : mFocusedWindowHandlesByDisplay) {
3309 const int32_t displayId = it.first;
3310 const sp<InputWindowHandle>& windowHandle = it.second;
3311 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3312 displayId, windowHandle->getName().c_str());
3313 }
3314 }
3315 }
3316 }
3317
3318#if DEBUG_FOCUS
3319 logDispatchStateLocked();
3320#endif
3321 } // release lock
3322
3323 // Wake up poll loop since it may need to make new input dispatching choices.
3324 mLooper->wake();
3325}
3326
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3328#if DEBUG_FOCUS
3329 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3330#endif
3331
3332 bool changed;
3333 { // acquire lock
3334 AutoMutex _l(mLock);
3335
3336 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3337 if (mDispatchFrozen && !frozen) {
3338 resetANRTimeoutsLocked();
3339 }
3340
3341 if (mDispatchEnabled && !enabled) {
3342 resetAndDropEverythingLocked("dispatcher is being disabled");
3343 }
3344
3345 mDispatchEnabled = enabled;
3346 mDispatchFrozen = frozen;
3347 changed = true;
3348 } else {
3349 changed = false;
3350 }
3351
3352#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003353 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003354#endif
3355 } // release lock
3356
3357 if (changed) {
3358 // Wake up poll loop since it may need to make new input dispatching choices.
3359 mLooper->wake();
3360 }
3361}
3362
3363void InputDispatcher::setInputFilterEnabled(bool enabled) {
3364#if DEBUG_FOCUS
3365 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3366#endif
3367
3368 { // acquire lock
3369 AutoMutex _l(mLock);
3370
3371 if (mInputFilterEnabled == enabled) {
3372 return;
3373 }
3374
3375 mInputFilterEnabled = enabled;
3376 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3377 } // release lock
3378
3379 // Wake up poll loop since there might be work to do to drop everything.
3380 mLooper->wake();
3381}
3382
chaviwfbe5d9c2018-12-26 12:23:37 -08003383bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3384 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003385#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003386 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003388 return true;
3389 }
3390
Michael Wrightd02c5b62014-02-10 15:10:22 -08003391 { // acquire lock
3392 AutoMutex _l(mLock);
3393
chaviwfbe5d9c2018-12-26 12:23:37 -08003394 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3395 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003396 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003397 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398 return false;
3399 }
chaviw4f2dd402018-12-26 15:30:27 -08003400#if DEBUG_FOCUS
3401 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3402 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3403#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003404 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3405#if DEBUG_FOCUS
3406 ALOGD("Cannot transfer focus because windows are on different displays.");
3407#endif
3408 return false;
3409 }
3410
3411 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003412 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3413 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3414 for (size_t i = 0; i < state.windows.size(); i++) {
3415 const TouchedWindow& touchedWindow = state.windows[i];
3416 if (touchedWindow.windowHandle == fromWindowHandle) {
3417 int32_t oldTargetFlags = touchedWindow.targetFlags;
3418 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003419
Jeff Brownf086ddb2014-02-11 14:28:48 -08003420 state.windows.removeAt(i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003421
Jeff Brownf086ddb2014-02-11 14:28:48 -08003422 int32_t newTargetFlags = oldTargetFlags
3423 & (InputTarget::FLAG_FOREGROUND
3424 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3425 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003426
Jeff Brownf086ddb2014-02-11 14:28:48 -08003427 found = true;
3428 goto Found;
3429 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003430 }
3431 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003432Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003433
3434 if (! found) {
3435#if DEBUG_FOCUS
3436 ALOGD("Focus transfer failed because from window did not have focus.");
3437#endif
3438 return false;
3439 }
3440
chaviwfbe5d9c2018-12-26 12:23:37 -08003441
3442 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3443 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3445 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3446 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3447 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3448 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3449
3450 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3451 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3452 "transferring touch focus from this window to another window");
3453 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3454 }
3455
3456#if DEBUG_FOCUS
3457 logDispatchStateLocked();
3458#endif
3459 } // release lock
3460
3461 // Wake up poll loop since it may need to make new input dispatching choices.
3462 mLooper->wake();
3463 return true;
3464}
3465
3466void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3467#if DEBUG_FOCUS
3468 ALOGD("Resetting and dropping all events (%s).", reason);
3469#endif
3470
3471 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3472 synthesizeCancelationEventsForAllConnectionsLocked(options);
3473
3474 resetKeyRepeatLocked();
3475 releasePendingEventLocked();
3476 drainInboundQueueLocked();
3477 resetANRTimeoutsLocked();
3478
Jeff Brownf086ddb2014-02-11 14:28:48 -08003479 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003480 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003481 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003482}
3483
3484void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003485 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003486 dumpDispatchStateLocked(dump);
3487
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003488 std::istringstream stream(dump);
3489 std::string line;
3490
3491 while (std::getline(stream, line, '\n')) {
3492 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003493 }
3494}
3495
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003496void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
3497 dump += StringPrintf(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
3498 dump += StringPrintf(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Tiger Huang721e26f2018-07-24 22:26:19 +08003499 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003500
Tiger Huang721e26f2018-07-24 22:26:19 +08003501 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3502 dump += StringPrintf(INDENT "FocusedApplications:\n");
3503 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3504 const int32_t displayId = it.first;
3505 const sp<InputApplicationHandle>& applicationHandle = it.second;
3506 dump += StringPrintf(
3507 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3508 displayId,
3509 applicationHandle->getName().c_str(),
3510 applicationHandle->getDispatchingTimeout(
3511 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3512 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003514 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003516
3517 if (!mFocusedWindowHandlesByDisplay.empty()) {
3518 dump += StringPrintf(INDENT "FocusedWindows:\n");
3519 for (auto& it : mFocusedWindowHandlesByDisplay) {
3520 const int32_t displayId = it.first;
3521 const sp<InputWindowHandle>& windowHandle = it.second;
3522 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3523 displayId, windowHandle->getName().c_str());
3524 }
3525 } else {
3526 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3527 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528
Jeff Brownf086ddb2014-02-11 14:28:48 -08003529 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003530 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003531 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3532 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003533 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003534 state.displayId, toString(state.down), toString(state.split),
3535 state.deviceId, state.source);
3536 if (!state.windows.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003537 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003538 for (size_t i = 0; i < state.windows.size(); i++) {
3539 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003540 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3541 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003542 touchedWindow.pointerIds.value,
3543 touchedWindow.targetFlags);
3544 }
3545 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003546 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003547 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003548 if (!state.portalWindows.isEmpty()) {
3549 dump += INDENT3 "Portal windows:\n";
3550 for (size_t i = 0; i < state.portalWindows.size(); i++) {
3551 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows.itemAt(i);
3552 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3553 i, portalWindowHandle->getName().c_str());
3554 }
3555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556 }
3557 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003558 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559 }
3560
Arthur Hungb92218b2018-08-14 12:00:21 +08003561 if (!mWindowHandlesByDisplay.empty()) {
3562 for (auto& it : mWindowHandlesByDisplay) {
3563 const Vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003564 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hungb92218b2018-08-14 12:00:21 +08003565 if (!windowHandles.isEmpty()) {
3566 dump += INDENT2 "Windows:\n";
3567 for (size_t i = 0; i < windowHandles.size(); i++) {
3568 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
3569 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003570
Arthur Hungb92218b2018-08-14 12:00:21 +08003571 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003572 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003573 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003574 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003575 "touchableRegion=",
3576 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003577 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003578 toString(windowInfo->paused),
3579 toString(windowInfo->hasFocus),
3580 toString(windowInfo->hasWallpaper),
3581 toString(windowInfo->visible),
3582 toString(windowInfo->canReceiveKeys),
3583 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3584 windowInfo->layer,
3585 windowInfo->frameLeft, windowInfo->frameTop,
3586 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003587 windowInfo->globalScaleFactor,
3588 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003589 dumpRegion(dump, windowInfo->touchableRegion);
3590 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3591 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3592 windowInfo->ownerPid, windowInfo->ownerUid,
3593 windowInfo->dispatchingTimeout / 1000000.0);
3594 }
3595 } else {
3596 dump += INDENT2 "Windows: <none>\n";
3597 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598 }
3599 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003600 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601 }
3602
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003603 if (!mMonitoringChannelsByDisplay.empty()) {
3604 for (auto& it : mMonitoringChannelsByDisplay) {
3605 const Vector<sp<InputChannel>>& monitoringChannels = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003606 dump += StringPrintf(INDENT "MonitoringChannels in display %" PRId32 ":\n", it.first);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003607 const size_t numChannels = monitoringChannels.size();
3608 for (size_t i = 0; i < numChannels; i++) {
3609 const sp<InputChannel>& channel = monitoringChannels[i];
3610 dump += StringPrintf(INDENT2 "%zu: '%s'\n", i, channel->getName().c_str());
3611 }
3612 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003614 dump += INDENT "MonitoringChannels: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615 }
3616
3617 nsecs_t currentTime = now();
3618
3619 // Dump recently dispatched or dropped events from oldest to newest.
3620 if (!mRecentQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003621 dump += StringPrintf(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622 for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003623 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003624 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003625 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 (currentTime - entry->eventTime) * 0.000001f);
3627 }
3628 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003629 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630 }
3631
3632 // Dump event currently being dispatched.
3633 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003634 dump += INDENT "PendingEvent:\n";
3635 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003637 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003638 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3639 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003640 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003641 }
3642
3643 // Dump inbound events from oldest to newest.
3644 if (!mInboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003645 dump += StringPrintf(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003646 for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003647 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003649 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003650 (currentTime - entry->eventTime) * 0.000001f);
3651 }
3652 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003653 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003654 }
3655
Michael Wright78f24442014-08-06 15:55:28 -07003656 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003657 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003658 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3659 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3660 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003661 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003662 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3663 }
3664 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003665 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003666 }
3667
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003669 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003670 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3671 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003672 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003673 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003674 i, connection->getInputChannelName().c_str(),
3675 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676 connection->getStatusLabel(), toString(connection->monitor),
3677 toString(connection->inputPublisherBlocked));
3678
3679 if (!connection->outboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003680 dump += StringPrintf(INDENT3 "OutboundQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003681 connection->outboundQueue.count());
3682 for (DispatchEntry* entry = connection->outboundQueue.head; entry;
3683 entry = entry->next) {
3684 dump.append(INDENT4);
3685 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003686 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687 entry->targetFlags, entry->resolvedAction,
3688 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3689 }
3690 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003691 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692 }
3693
3694 if (!connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003695 dump += StringPrintf(INDENT3 "WaitQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696 connection->waitQueue.count());
3697 for (DispatchEntry* entry = connection->waitQueue.head; entry;
3698 entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003699 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003701 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003702 "age=%0.1fms, wait=%0.1fms\n",
3703 entry->targetFlags, entry->resolvedAction,
3704 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3705 (currentTime - entry->deliveryTime) * 0.000001f);
3706 }
3707 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003708 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003709 }
3710 }
3711 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003712 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003713 }
3714
3715 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003716 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003717 (mAppSwitchDueTime - now()) / 1000000.0);
3718 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003719 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003720 }
3721
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003722 dump += INDENT "Configuration:\n";
3723 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003725 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726 mConfig.keyRepeatTimeout * 0.000001f);
3727}
3728
Robert Carr803535b2018-08-02 16:38:15 -07003729status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003730#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003731 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3732 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733#endif
3734
3735 { // acquire lock
3736 AutoMutex _l(mLock);
3737
Robert Carr4e670e52018-08-15 13:26:12 -07003738 // If InputWindowHandle is null and displayId is not ADISPLAY_ID_NONE,
3739 // treat inputChannel as monitor channel for displayId.
3740 bool monitor = inputChannel->getToken() == nullptr && displayId != ADISPLAY_ID_NONE;
3741 if (monitor) {
3742 inputChannel->setToken(new BBinder());
3743 }
3744
Michael Wrightd02c5b62014-02-10 15:10:22 -08003745 if (getConnectionIndexLocked(inputChannel) >= 0) {
3746 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003747 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748 return BAD_VALUE;
3749 }
3750
Robert Carr803535b2018-08-02 16:38:15 -07003751 sp<Connection> connection = new Connection(inputChannel, monitor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003752
3753 int fd = inputChannel->getFd();
3754 mConnectionsByFd.add(fd, connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07003755 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003756
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003757 // Store monitor channel by displayId.
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758 if (monitor) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003759 Vector<sp<InputChannel>>& monitoringChannels =
3760 mMonitoringChannelsByDisplay[displayId];
3761 monitoringChannels.push(inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003762 }
3763
3764 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3765 } // release lock
3766
3767 // Wake the looper because some connections have changed.
3768 mLooper->wake();
3769 return OK;
3770}
3771
3772status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3773#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003774 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775#endif
3776
3777 { // acquire lock
3778 AutoMutex _l(mLock);
3779
3780 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3781 if (status) {
3782 return status;
3783 }
3784 } // release lock
3785
3786 // Wake the poll loop because removing the connection may have changed the current
3787 // synchronization state.
3788 mLooper->wake();
3789 return OK;
3790}
3791
3792status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3793 bool notify) {
3794 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3795 if (connectionIndex < 0) {
3796 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003797 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003798 return BAD_VALUE;
3799 }
3800
3801 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3802 mConnectionsByFd.removeItemsAt(connectionIndex);
3803
Robert Carr5c8a0262018-10-03 16:30:44 -07003804 mInputChannelsByToken.erase(inputChannel->getToken());
3805
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806 if (connection->monitor) {
3807 removeMonitorChannelLocked(inputChannel);
3808 }
3809
3810 mLooper->removeFd(inputChannel->getFd());
3811
3812 nsecs_t currentTime = now();
3813 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3814
3815 connection->status = Connection::STATUS_ZOMBIE;
3816 return OK;
3817}
3818
3819void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003820 for (auto it = mMonitoringChannelsByDisplay.begin();
3821 it != mMonitoringChannelsByDisplay.end(); ) {
3822 Vector<sp<InputChannel>>& monitoringChannels = it->second;
3823 const size_t numChannels = monitoringChannels.size();
3824 for (size_t i = 0; i < numChannels; i++) {
3825 if (monitoringChannels[i] == inputChannel) {
3826 monitoringChannels.removeAt(i);
3827 break;
3828 }
3829 }
3830 if (monitoringChannels.empty()) {
3831 it = mMonitoringChannelsByDisplay.erase(it);
3832 } else {
3833 ++it;
3834 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 }
3836}
3837
3838ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07003839 if (inputChannel == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003840 return -1;
3841 }
3842
Robert Carr4e670e52018-08-15 13:26:12 -07003843 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3844 sp<Connection> connection = mConnectionsByFd.valueAt(i);
3845 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
3846 return i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003847 }
3848 }
Robert Carr4e670e52018-08-15 13:26:12 -07003849
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850 return -1;
3851}
3852
3853void InputDispatcher::onDispatchCycleFinishedLocked(
3854 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
3855 CommandEntry* commandEntry = postCommandLocked(
3856 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3857 commandEntry->connection = connection;
3858 commandEntry->eventTime = currentTime;
3859 commandEntry->seq = seq;
3860 commandEntry->handled = handled;
3861}
3862
3863void InputDispatcher::onDispatchCycleBrokenLocked(
3864 nsecs_t currentTime, const sp<Connection>& connection) {
3865 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003866 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867
3868 CommandEntry* commandEntry = postCommandLocked(
3869 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
3870 commandEntry->connection = connection;
3871}
3872
chaviw0c06c6e2019-01-09 13:27:07 -08003873void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
3874 const sp<InputWindowHandle>& newFocus) {
3875 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
3876 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Robert Carrf759f162018-11-13 12:57:11 -08003877 CommandEntry* commandEntry = postCommandLocked(
3878 & InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08003879 commandEntry->oldToken = oldToken;
3880 commandEntry->newToken = newToken;
Robert Carrf759f162018-11-13 12:57:11 -08003881}
3882
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883void InputDispatcher::onANRLocked(
3884 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
3885 const sp<InputWindowHandle>& windowHandle,
3886 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
3887 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
3888 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
3889 ALOGI("Application is not responding: %s. "
3890 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003891 getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 dispatchLatency, waitDuration, reason);
3893
3894 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07003895 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003896 struct tm tm;
3897 localtime_r(&t, &tm);
3898 char timestr[64];
3899 strftime(timestr, sizeof(timestr), "%F %T", &tm);
3900 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003901 mLastANRState += INDENT "ANR:\n";
3902 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
3903 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
3904 getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str());
3905 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
3906 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
3907 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908 dumpDispatchStateLocked(mLastANRState);
3909
3910 CommandEntry* commandEntry = postCommandLocked(
3911 & InputDispatcher::doNotifyANRLockedInterruptible);
3912 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07003913 commandEntry->inputChannel = windowHandle != nullptr ?
3914 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003915 commandEntry->reason = reason;
3916}
3917
3918void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3919 CommandEntry* commandEntry) {
3920 mLock.unlock();
3921
3922 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3923
3924 mLock.lock();
3925}
3926
3927void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3928 CommandEntry* commandEntry) {
3929 sp<Connection> connection = commandEntry->connection;
3930
3931 if (connection->status != Connection::STATUS_ZOMBIE) {
3932 mLock.unlock();
3933
Robert Carr803535b2018-08-02 16:38:15 -07003934 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935
3936 mLock.lock();
3937 }
3938}
3939
Robert Carrf759f162018-11-13 12:57:11 -08003940void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
3941 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08003942 sp<IBinder> oldToken = commandEntry->oldToken;
3943 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08003944 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08003945 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08003946 mLock.lock();
3947}
3948
Michael Wrightd02c5b62014-02-10 15:10:22 -08003949void InputDispatcher::doNotifyANRLockedInterruptible(
3950 CommandEntry* commandEntry) {
3951 mLock.unlock();
3952
3953 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07003954 commandEntry->inputApplicationHandle,
3955 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 commandEntry->reason);
3957
3958 mLock.lock();
3959
3960 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07003961 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962}
3963
3964void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3965 CommandEntry* commandEntry) {
3966 KeyEntry* entry = commandEntry->keyEntry;
3967
3968 KeyEvent event;
3969 initializeKeyEvent(&event, entry);
3970
3971 mLock.unlock();
3972
Michael Wright2b3c3302018-03-02 17:19:13 +00003973 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07003974 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
3975 commandEntry->inputChannel->getToken() : nullptr;
3976 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08003977 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003978 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3979 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
3980 std::to_string(t.duration().count()).c_str());
3981 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982
3983 mLock.lock();
3984
3985 if (delay < 0) {
3986 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3987 } else if (!delay) {
3988 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3989 } else {
3990 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3991 entry->interceptKeyWakeupTime = now() + delay;
3992 }
3993 entry->release();
3994}
3995
3996void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3997 CommandEntry* commandEntry) {
3998 sp<Connection> connection = commandEntry->connection;
3999 nsecs_t finishTime = commandEntry->eventTime;
4000 uint32_t seq = commandEntry->seq;
4001 bool handled = commandEntry->handled;
4002
4003 // Handle post-event policy actions.
4004 DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
4005 if (dispatchEntry) {
4006 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4007 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004008 std::string msg =
4009 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004010 connection->getWindowName().c_str(), eventDuration * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004011 dispatchEntry->eventEntry->appendDescription(msg);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004012 ALOGI("%s", msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004013 }
4014
4015 bool restartEvent;
4016 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4017 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4018 restartEvent = afterKeyEventLockedInterruptible(connection,
4019 dispatchEntry, keyEntry, handled);
4020 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4021 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4022 restartEvent = afterMotionEventLockedInterruptible(connection,
4023 dispatchEntry, motionEntry, handled);
4024 } else {
4025 restartEvent = false;
4026 }
4027
4028 // Dequeue the event and start the next cycle.
4029 // Note that because the lock might have been released, it is possible that the
4030 // contents of the wait queue to have been drained, so we need to double-check
4031 // a few things.
4032 if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
4033 connection->waitQueue.dequeue(dispatchEntry);
4034 traceWaitQueueLengthLocked(connection);
4035 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
4036 connection->outboundQueue.enqueueAtHead(dispatchEntry);
4037 traceOutboundQueueLengthLocked(connection);
4038 } else {
4039 releaseDispatchEntryLocked(dispatchEntry);
4040 }
4041 }
4042
4043 // Start the next dispatch cycle for this connection.
4044 startDispatchCycleLocked(now(), connection);
4045 }
4046}
4047
4048bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4049 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004050 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004051 if (!handled) {
4052 // Report the key as unhandled, since the fallback was not handled.
4053 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4054 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004055 return false;
4056 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004058 // Get the fallback key state.
4059 // Clear it out after dispatching the UP.
4060 int32_t originalKeyCode = keyEntry->keyCode;
4061 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4062 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4063 connection->inputState.removeFallbackKey(originalKeyCode);
4064 }
4065
4066 if (handled || !dispatchEntry->hasForegroundTarget()) {
4067 // If the application handles the original key for which we previously
4068 // generated a fallback or if the window is not a foreground window,
4069 // then cancel the associated fallback key, if any.
4070 if (fallbackKeyCode != -1) {
4071 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004073 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4075 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4076 keyEntry->policyFlags);
4077#endif
4078 KeyEvent event;
4079 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004080 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081
4082 mLock.unlock();
4083
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004084 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4085 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086
4087 mLock.lock();
4088
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004089 // Cancel the fallback key.
4090 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004092 "application handled the original non-fallback key "
4093 "or is no longer a foreground target, "
4094 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004095 options.keyCode = fallbackKeyCode;
4096 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004098 connection->inputState.removeFallbackKey(originalKeyCode);
4099 }
4100 } else {
4101 // If the application did not handle a non-fallback key, first check
4102 // that we are in a good state to perform unhandled key event processing
4103 // Then ask the policy what to do with it.
4104 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4105 && keyEntry->repeatCount == 0;
4106 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004107#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004108 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4109 "since this is not an initial down. "
4110 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4111 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4112 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004113#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004114 return false;
4115 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004117 // Dispatch the unhandled key to the policy.
4118#if DEBUG_OUTBOUND_EVENT_DETAILS
4119 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4120 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4121 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4122 keyEntry->policyFlags);
4123#endif
4124 KeyEvent event;
4125 initializeKeyEvent(&event, keyEntry);
4126
4127 mLock.unlock();
4128
4129 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4130 &event, keyEntry->policyFlags, &event);
4131
4132 mLock.lock();
4133
4134 if (connection->status != Connection::STATUS_NORMAL) {
4135 connection->inputState.removeFallbackKey(originalKeyCode);
4136 return false;
4137 }
4138
4139 // Latch the fallback keycode for this key on an initial down.
4140 // The fallback keycode cannot change at any other point in the lifecycle.
4141 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004142 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004143 fallbackKeyCode = event.getKeyCode();
4144 } else {
4145 fallbackKeyCode = AKEYCODE_UNKNOWN;
4146 }
4147 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4148 }
4149
4150 ALOG_ASSERT(fallbackKeyCode != -1);
4151
4152 // Cancel the fallback key if the policy decides not to send it anymore.
4153 // We will continue to dispatch the key to the policy but we will no
4154 // longer dispatch a fallback key to the application.
4155 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4156 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4157#if DEBUG_OUTBOUND_EVENT_DETAILS
4158 if (fallback) {
4159 ALOGD("Unhandled key event: Policy requested to send key %d"
4160 "as a fallback for %d, but on the DOWN it had requested "
4161 "to send %d instead. Fallback canceled.",
4162 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4163 } else {
4164 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4165 "but on the DOWN it had requested to send %d. "
4166 "Fallback canceled.",
4167 originalKeyCode, fallbackKeyCode);
4168 }
4169#endif
4170
4171 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4172 "canceling fallback, policy no longer desires it");
4173 options.keyCode = fallbackKeyCode;
4174 synthesizeCancelationEventsForConnectionLocked(connection, options);
4175
4176 fallback = false;
4177 fallbackKeyCode = AKEYCODE_UNKNOWN;
4178 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4179 connection->inputState.setFallbackKey(originalKeyCode,
4180 fallbackKeyCode);
4181 }
4182 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004183
4184#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004185 {
4186 std::string msg;
4187 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4188 connection->inputState.getFallbackKeys();
4189 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4190 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4191 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004193 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4194 fallbackKeys.size(), msg.c_str());
4195 }
4196#endif
4197
4198 if (fallback) {
4199 // Restart the dispatch cycle using the fallback key.
4200 keyEntry->eventTime = event.getEventTime();
4201 keyEntry->deviceId = event.getDeviceId();
4202 keyEntry->source = event.getSource();
4203 keyEntry->displayId = event.getDisplayId();
4204 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4205 keyEntry->keyCode = fallbackKeyCode;
4206 keyEntry->scanCode = event.getScanCode();
4207 keyEntry->metaState = event.getMetaState();
4208 keyEntry->repeatCount = event.getRepeatCount();
4209 keyEntry->downTime = event.getDownTime();
4210 keyEntry->syntheticRepeat = false;
4211
4212#if DEBUG_OUTBOUND_EVENT_DETAILS
4213 ALOGD("Unhandled key event: Dispatching fallback key. "
4214 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4215 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4216#endif
4217 return true; // restart the event
4218 } else {
4219#if DEBUG_OUTBOUND_EVENT_DETAILS
4220 ALOGD("Unhandled key event: No fallback key.");
4221#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004222
4223 // Report the key as unhandled, since there is no fallback key.
4224 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004225 }
4226 }
4227 return false;
4228}
4229
4230bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4231 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4232 return false;
4233}
4234
4235void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4236 mLock.unlock();
4237
4238 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4239
4240 mLock.lock();
4241}
4242
4243void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004244 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004245 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4246 entry->downTime, entry->eventTime);
4247}
4248
4249void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
4250 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4251 // TODO Write some statistics about how long we spend waiting.
4252}
4253
4254void InputDispatcher::traceInboundQueueLengthLocked() {
4255 if (ATRACE_ENABLED()) {
4256 ATRACE_INT("iq", mInboundQueue.count());
4257 }
4258}
4259
4260void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
4261 if (ATRACE_ENABLED()) {
4262 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004263 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004264 ATRACE_INT(counterName, connection->outboundQueue.count());
4265 }
4266}
4267
4268void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
4269 if (ATRACE_ENABLED()) {
4270 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004271 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272 ATRACE_INT(counterName, connection->waitQueue.count());
4273 }
4274}
4275
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004276void InputDispatcher::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004277 AutoMutex _l(mLock);
4278
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004279 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004280 dumpDispatchStateLocked(dump);
4281
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004282 if (!mLastANRState.empty()) {
4283 dump += "\nInput Dispatcher State at time of last ANR:\n";
4284 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285 }
4286}
4287
4288void InputDispatcher::monitor() {
4289 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
4290 mLock.lock();
4291 mLooper->wake();
4292 mDispatcherIsAliveCondition.wait(mLock);
4293 mLock.unlock();
4294}
4295
4296
Michael Wrightd02c5b62014-02-10 15:10:22 -08004297// --- InputDispatcher::InjectionState ---
4298
4299InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4300 refCount(1),
4301 injectorPid(injectorPid), injectorUid(injectorUid),
4302 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4303 pendingForegroundDispatches(0) {
4304}
4305
4306InputDispatcher::InjectionState::~InjectionState() {
4307}
4308
4309void InputDispatcher::InjectionState::release() {
4310 refCount -= 1;
4311 if (refCount == 0) {
4312 delete this;
4313 } else {
4314 ALOG_ASSERT(refCount > 0);
4315 }
4316}
4317
4318
4319// --- InputDispatcher::EventEntry ---
4320
Prabir Pradhan42611e02018-11-27 14:04:02 -08004321InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4322 nsecs_t eventTime, uint32_t policyFlags) :
4323 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4324 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325}
4326
4327InputDispatcher::EventEntry::~EventEntry() {
4328 releaseInjectionState();
4329}
4330
4331void InputDispatcher::EventEntry::release() {
4332 refCount -= 1;
4333 if (refCount == 0) {
4334 delete this;
4335 } else {
4336 ALOG_ASSERT(refCount > 0);
4337 }
4338}
4339
4340void InputDispatcher::EventEntry::releaseInjectionState() {
4341 if (injectionState) {
4342 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004343 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344 }
4345}
4346
4347
4348// --- InputDispatcher::ConfigurationChangedEntry ---
4349
Prabir Pradhan42611e02018-11-27 14:04:02 -08004350InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4351 uint32_t sequenceNum, nsecs_t eventTime) :
4352 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353}
4354
4355InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4356}
4357
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004358void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4359 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004360}
4361
4362
4363// --- InputDispatcher::DeviceResetEntry ---
4364
Prabir Pradhan42611e02018-11-27 14:04:02 -08004365InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4366 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4367 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368 deviceId(deviceId) {
4369}
4370
4371InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4372}
4373
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004374void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4375 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376 deviceId, policyFlags);
4377}
4378
4379
4380// --- InputDispatcher::KeyEntry ---
4381
Prabir Pradhan42611e02018-11-27 14:04:02 -08004382InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004383 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004384 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4385 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004386 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004387 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4389 repeatCount(repeatCount), downTime(downTime),
4390 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4391 interceptKeyWakeupTime(0) {
4392}
4393
4394InputDispatcher::KeyEntry::~KeyEntry() {
4395}
4396
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004397void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004398 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4400 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004401 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004402 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403}
4404
4405void InputDispatcher::KeyEntry::recycle() {
4406 releaseInjectionState();
4407
4408 dispatchInProgress = false;
4409 syntheticRepeat = false;
4410 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4411 interceptKeyWakeupTime = 0;
4412}
4413
4414
4415// --- InputDispatcher::MotionEntry ---
4416
Prabir Pradhan42611e02018-11-27 14:04:02 -08004417InputDispatcher::MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004418 uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
4419 int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004420 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
4421 int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004422 uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004423 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
4424 float xOffset, float yOffset) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004425 EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004426 eventTime(eventTime),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004427 deviceId(deviceId), source(source), displayId(displayId), action(action),
4428 actionButton(actionButton), flags(flags), metaState(metaState), buttonState(buttonState),
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004429 classification(classification), edgeFlags(edgeFlags),
4430 xPrecision(xPrecision), yPrecision(yPrecision),
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004431 downTime(downTime), pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004432 for (uint32_t i = 0; i < pointerCount; i++) {
4433 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4434 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004435 if (xOffset || yOffset) {
4436 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4437 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004438 }
4439}
4440
4441InputDispatcher::MotionEntry::~MotionEntry() {
4442}
4443
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004444void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004445 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004446 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004447 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[",
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004448 deviceId, source, displayId, motionActionToString(action).c_str(), actionButton, flags,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004449 metaState, buttonState, motionClassificationToString(classification), edgeFlags,
4450 xPrecision, yPrecision);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004451
Michael Wrightd02c5b62014-02-10 15:10:22 -08004452 for (uint32_t i = 0; i < pointerCount; i++) {
4453 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004454 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004456 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004457 pointerCoords[i].getX(), pointerCoords[i].getY());
4458 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004459 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004460}
4461
4462
4463// --- InputDispatcher::DispatchEntry ---
4464
4465volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4466
4467InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004468 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4469 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470 seq(nextSeq()),
4471 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004472 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4473 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004474 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4475 eventEntry->refCount += 1;
4476}
4477
4478InputDispatcher::DispatchEntry::~DispatchEntry() {
4479 eventEntry->release();
4480}
4481
4482uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4483 // Sequence number 0 is reserved and will never be returned.
4484 uint32_t seq;
4485 do {
4486 seq = android_atomic_inc(&sNextSeqAtomic);
4487 } while (!seq);
4488 return seq;
4489}
4490
4491
4492// --- InputDispatcher::InputState ---
4493
4494InputDispatcher::InputState::InputState() {
4495}
4496
4497InputDispatcher::InputState::~InputState() {
4498}
4499
4500bool InputDispatcher::InputState::isNeutral() const {
4501 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
4502}
4503
4504bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4505 int32_t displayId) const {
4506 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4507 const MotionMemento& memento = mMotionMementos.itemAt(i);
4508 if (memento.deviceId == deviceId
4509 && memento.source == source
4510 && memento.displayId == displayId
4511 && memento.hovering) {
4512 return true;
4513 }
4514 }
4515 return false;
4516}
4517
4518bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4519 int32_t action, int32_t flags) {
4520 switch (action) {
4521 case AKEY_EVENT_ACTION_UP: {
4522 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4523 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4524 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4525 mFallbackKeys.removeItemsAt(i);
4526 } else {
4527 i += 1;
4528 }
4529 }
4530 }
4531 ssize_t index = findKeyMemento(entry);
4532 if (index >= 0) {
4533 mKeyMementos.removeAt(index);
4534 return true;
4535 }
4536 /* FIXME: We can't just drop the key up event because that prevents creating
4537 * popup windows that are automatically shown when a key is held and then
4538 * dismissed when the key is released. The problem is that the popup will
4539 * not have received the original key down, so the key up will be considered
4540 * to be inconsistent with its observed state. We could perhaps handle this
4541 * by synthesizing a key down but that will cause other problems.
4542 *
4543 * So for now, allow inconsistent key up events to be dispatched.
4544 *
4545#if DEBUG_OUTBOUND_EVENT_DETAILS
4546 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4547 "keyCode=%d, scanCode=%d",
4548 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4549#endif
4550 return false;
4551 */
4552 return true;
4553 }
4554
4555 case AKEY_EVENT_ACTION_DOWN: {
4556 ssize_t index = findKeyMemento(entry);
4557 if (index >= 0) {
4558 mKeyMementos.removeAt(index);
4559 }
4560 addKeyMemento(entry, flags);
4561 return true;
4562 }
4563
4564 default:
4565 return true;
4566 }
4567}
4568
4569bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4570 int32_t action, int32_t flags) {
4571 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4572 switch (actionMasked) {
4573 case AMOTION_EVENT_ACTION_UP:
4574 case AMOTION_EVENT_ACTION_CANCEL: {
4575 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4576 if (index >= 0) {
4577 mMotionMementos.removeAt(index);
4578 return true;
4579 }
4580#if DEBUG_OUTBOUND_EVENT_DETAILS
4581 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004582 "displayId=%" PRId32 ", actionMasked=%d",
4583 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004584#endif
4585 return false;
4586 }
4587
4588 case AMOTION_EVENT_ACTION_DOWN: {
4589 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4590 if (index >= 0) {
4591 mMotionMementos.removeAt(index);
4592 }
4593 addMotionMemento(entry, flags, false /*hovering*/);
4594 return true;
4595 }
4596
4597 case AMOTION_EVENT_ACTION_POINTER_UP:
4598 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4599 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004600 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4601 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4602 // generate cancellation events for these since they're based in relative rather than
4603 // absolute units.
4604 return true;
4605 }
4606
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004608
4609 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4610 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4611 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4612 // other value and we need to track the motion so we can send cancellation events for
4613 // anything generating fallback events (e.g. DPad keys for joystick movements).
4614 if (index >= 0) {
4615 if (entry->pointerCoords[0].isEmpty()) {
4616 mMotionMementos.removeAt(index);
4617 } else {
4618 MotionMemento& memento = mMotionMementos.editItemAt(index);
4619 memento.setPointers(entry);
4620 }
4621 } else if (!entry->pointerCoords[0].isEmpty()) {
4622 addMotionMemento(entry, flags, false /*hovering*/);
4623 }
4624
4625 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4626 return true;
4627 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004628 if (index >= 0) {
4629 MotionMemento& memento = mMotionMementos.editItemAt(index);
4630 memento.setPointers(entry);
4631 return true;
4632 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004633#if DEBUG_OUTBOUND_EVENT_DETAILS
4634 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004635 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4636 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637#endif
4638 return false;
4639 }
4640
4641 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4642 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4643 if (index >= 0) {
4644 mMotionMementos.removeAt(index);
4645 return true;
4646 }
4647#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004648 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4649 "displayId=%" PRId32,
4650 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004651#endif
4652 return false;
4653 }
4654
4655 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4656 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4657 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4658 if (index >= 0) {
4659 mMotionMementos.removeAt(index);
4660 }
4661 addMotionMemento(entry, flags, true /*hovering*/);
4662 return true;
4663 }
4664
4665 default:
4666 return true;
4667 }
4668}
4669
4670ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4671 for (size_t i = 0; i < mKeyMementos.size(); i++) {
4672 const KeyMemento& memento = mKeyMementos.itemAt(i);
4673 if (memento.deviceId == entry->deviceId
4674 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004675 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004676 && memento.keyCode == entry->keyCode
4677 && memento.scanCode == entry->scanCode) {
4678 return i;
4679 }
4680 }
4681 return -1;
4682}
4683
4684ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4685 bool hovering) const {
4686 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4687 const MotionMemento& memento = mMotionMementos.itemAt(i);
4688 if (memento.deviceId == entry->deviceId
4689 && memento.source == entry->source
4690 && memento.displayId == entry->displayId
4691 && memento.hovering == hovering) {
4692 return i;
4693 }
4694 }
4695 return -1;
4696}
4697
4698void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
4699 mKeyMementos.push();
4700 KeyMemento& memento = mKeyMementos.editTop();
4701 memento.deviceId = entry->deviceId;
4702 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004703 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004704 memento.keyCode = entry->keyCode;
4705 memento.scanCode = entry->scanCode;
4706 memento.metaState = entry->metaState;
4707 memento.flags = flags;
4708 memento.downTime = entry->downTime;
4709 memento.policyFlags = entry->policyFlags;
4710}
4711
4712void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4713 int32_t flags, bool hovering) {
4714 mMotionMementos.push();
4715 MotionMemento& memento = mMotionMementos.editTop();
4716 memento.deviceId = entry->deviceId;
4717 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004718 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 memento.flags = flags;
4720 memento.xPrecision = entry->xPrecision;
4721 memento.yPrecision = entry->yPrecision;
4722 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004723 memento.setPointers(entry);
4724 memento.hovering = hovering;
4725 memento.policyFlags = entry->policyFlags;
4726}
4727
4728void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4729 pointerCount = entry->pointerCount;
4730 for (uint32_t i = 0; i < entry->pointerCount; i++) {
4731 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
4732 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
4733 }
4734}
4735
4736void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
4737 Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
4738 for (size_t i = 0; i < mKeyMementos.size(); i++) {
4739 const KeyMemento& memento = mKeyMementos.itemAt(i);
4740 if (shouldCancelKey(memento, options)) {
Prabir Pradhan42611e02018-11-27 14:04:02 -08004741 outEvents.push(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004742 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004743 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
4744 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
4745 }
4746 }
4747
4748 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4749 const MotionMemento& memento = mMotionMementos.itemAt(i);
4750 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004751 const int32_t action = memento.hovering ?
4752 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Prabir Pradhan42611e02018-11-27 14:04:02 -08004753 outEvents.push(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004754 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004755 action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/,
4756 MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004757 memento.xPrecision, memento.yPrecision, memento.downTime,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004758 memento.pointerCount, memento.pointerProperties, memento.pointerCoords,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004759 0 /*xOffset*/, 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004760 }
4761 }
4762}
4763
4764void InputDispatcher::InputState::clear() {
4765 mKeyMementos.clear();
4766 mMotionMementos.clear();
4767 mFallbackKeys.clear();
4768}
4769
4770void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
4771 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4772 const MotionMemento& memento = mMotionMementos.itemAt(i);
4773 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
4774 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
4775 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
4776 if (memento.deviceId == otherMemento.deviceId
4777 && memento.source == otherMemento.source
4778 && memento.displayId == otherMemento.displayId) {
4779 other.mMotionMementos.removeAt(j);
4780 } else {
4781 j += 1;
4782 }
4783 }
4784 other.mMotionMementos.push(memento);
4785 }
4786 }
4787}
4788
4789int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
4790 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4791 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
4792}
4793
4794void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
4795 int32_t fallbackKeyCode) {
4796 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4797 if (index >= 0) {
4798 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
4799 } else {
4800 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
4801 }
4802}
4803
4804void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
4805 mFallbackKeys.removeItem(originalKeyCode);
4806}
4807
4808bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
4809 const CancelationOptions& options) {
4810 if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
4811 return false;
4812 }
4813
4814 if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
4815 return false;
4816 }
4817
4818 switch (options.mode) {
4819 case CancelationOptions::CANCEL_ALL_EVENTS:
4820 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
4821 return true;
4822 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
4823 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
Tiger Huang721e26f2018-07-24 22:26:19 +08004824 case CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS:
4825 return memento.displayId == ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004826 default:
4827 return false;
4828 }
4829}
4830
4831bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
4832 const CancelationOptions& options) {
4833 if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
4834 return false;
4835 }
4836
4837 switch (options.mode) {
4838 case CancelationOptions::CANCEL_ALL_EVENTS:
4839 return true;
4840 case CancelationOptions::CANCEL_POINTER_EVENTS:
4841 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
4842 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
4843 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
Tiger Huang721e26f2018-07-24 22:26:19 +08004844 case CancelationOptions::CANCEL_DISPLAY_UNSPECIFIED_EVENTS:
4845 return memento.displayId == ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004846 default:
4847 return false;
4848 }
4849}
4850
4851
4852// --- InputDispatcher::Connection ---
4853
Robert Carr803535b2018-08-02 16:38:15 -07004854InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
4855 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004856 monitor(monitor),
4857 inputPublisher(inputChannel), inputPublisherBlocked(false) {
4858}
4859
4860InputDispatcher::Connection::~Connection() {
4861}
4862
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004863const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07004864 if (inputChannel != nullptr) {
4865 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004866 }
4867 if (monitor) {
4868 return "monitor";
4869 }
4870 return "?";
4871}
4872
4873const char* InputDispatcher::Connection::getStatusLabel() const {
4874 switch (status) {
4875 case STATUS_NORMAL:
4876 return "NORMAL";
4877
4878 case STATUS_BROKEN:
4879 return "BROKEN";
4880
4881 case STATUS_ZOMBIE:
4882 return "ZOMBIE";
4883
4884 default:
4885 return "UNKNOWN";
4886 }
4887}
4888
4889InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
Yi Kong9b14ac62018-07-17 13:48:38 -07004890 for (DispatchEntry* entry = waitQueue.head; entry != nullptr; entry = entry->next) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891 if (entry->seq == seq) {
4892 return entry;
4893 }
4894 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004895 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004896}
4897
4898
4899// --- InputDispatcher::CommandEntry ---
4900
4901InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07004902 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004903 seq(0), handled(false) {
4904}
4905
4906InputDispatcher::CommandEntry::~CommandEntry() {
4907}
4908
4909
4910// --- InputDispatcher::TouchState ---
4911
4912InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004913 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004914}
4915
4916InputDispatcher::TouchState::~TouchState() {
4917}
4918
4919void InputDispatcher::TouchState::reset() {
4920 down = false;
4921 split = false;
4922 deviceId = -1;
4923 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004924 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004926 portalWindows.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927}
4928
4929void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
4930 down = other.down;
4931 split = other.split;
4932 deviceId = other.deviceId;
4933 source = other.source;
4934 displayId = other.displayId;
4935 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004936 portalWindows = other.portalWindows;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937}
4938
4939void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
4940 int32_t targetFlags, BitSet32 pointerIds) {
4941 if (targetFlags & InputTarget::FLAG_SPLIT) {
4942 split = true;
4943 }
4944
4945 for (size_t i = 0; i < windows.size(); i++) {
4946 TouchedWindow& touchedWindow = windows.editItemAt(i);
4947 if (touchedWindow.windowHandle == windowHandle) {
4948 touchedWindow.targetFlags |= targetFlags;
4949 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
4950 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
4951 }
4952 touchedWindow.pointerIds.value |= pointerIds.value;
4953 return;
4954 }
4955 }
4956
4957 windows.push();
4958
4959 TouchedWindow& touchedWindow = windows.editTop();
4960 touchedWindow.windowHandle = windowHandle;
4961 touchedWindow.targetFlags = targetFlags;
4962 touchedWindow.pointerIds = pointerIds;
4963}
4964
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004965void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
4966 size_t numWindows = portalWindows.size();
4967 for (size_t i = 0; i < numWindows; i++) {
4968 sp<InputWindowHandle> portalWindowHandle = portalWindows.itemAt(i);
4969 if (portalWindowHandle == windowHandle) {
4970 return;
4971 }
4972 }
4973 portalWindows.push_back(windowHandle);
4974}
4975
Michael Wrightd02c5b62014-02-10 15:10:22 -08004976void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
4977 for (size_t i = 0; i < windows.size(); i++) {
4978 if (windows.itemAt(i).windowHandle == windowHandle) {
4979 windows.removeAt(i);
4980 return;
4981 }
4982 }
4983}
4984
Robert Carr803535b2018-08-02 16:38:15 -07004985void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
4986 for (size_t i = 0; i < windows.size(); i++) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004987 if (windows.itemAt(i).windowHandle->getToken() == token) {
Robert Carr803535b2018-08-02 16:38:15 -07004988 windows.removeAt(i);
4989 return;
4990 }
4991 }
4992}
4993
Michael Wrightd02c5b62014-02-10 15:10:22 -08004994void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
4995 for (size_t i = 0 ; i < windows.size(); ) {
4996 TouchedWindow& window = windows.editItemAt(i);
4997 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
4998 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
4999 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5000 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5001 i += 1;
5002 } else {
5003 windows.removeAt(i);
5004 }
5005 }
5006}
5007
5008sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5009 for (size_t i = 0; i < windows.size(); i++) {
5010 const TouchedWindow& window = windows.itemAt(i);
5011 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5012 return window.windowHandle;
5013 }
5014 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005015 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005016}
5017
5018bool InputDispatcher::TouchState::isSlippery() const {
5019 // Must have exactly one foreground window.
5020 bool haveSlipperyForegroundWindow = false;
5021 for (size_t i = 0; i < windows.size(); i++) {
5022 const TouchedWindow& window = windows.itemAt(i);
5023 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5024 if (haveSlipperyForegroundWindow
5025 || !(window.windowHandle->getInfo()->layoutParamsFlags
5026 & InputWindowInfo::FLAG_SLIPPERY)) {
5027 return false;
5028 }
5029 haveSlipperyForegroundWindow = true;
5030 }
5031 }
5032 return haveSlipperyForegroundWindow;
5033}
5034
5035
5036// --- InputDispatcherThread ---
5037
5038InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5039 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5040}
5041
5042InputDispatcherThread::~InputDispatcherThread() {
5043}
5044
5045bool InputDispatcherThread::threadLoop() {
5046 mDispatcher->dispatchOnce();
5047 return true;
5048}
5049
5050} // namespace android