blob: 019815c2c512a71e6fae73f27707da3c27e3d96e [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
Michael Wright3dd60e22019-03-27 22:06:44 +000020#define LOG_NDEBUG 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
31// Log debug messages about registrations.
32#define DEBUG_REGISTRATION 0
33
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
38#define DEBUG_FOCUS 0
39
40// Log debug messages about the app switch latency optimization.
41#define DEBUG_APP_SWITCH 0
42
43// Log debug messages about hover events.
44#define DEBUG_HOVER 0
45
46#include "InputDispatcher.h"
47
Michael Wrightd02c5b62014-02-10 15:10:22 -080048#include <errno.h>
Siarhei Vishniakou443ad902019-03-06 17:25:41 -080049#include <inttypes.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#include <limits.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080051#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070052#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080053#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070054#include <unistd.h>
55
Michael Wright2b3c3302018-03-02 17:19:13 +000056#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080057#include <android-base/stringprintf.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070058#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070059#include <utils/Trace.h>
60#include <powermanager/PowerManager.h>
Robert Carr4e670e52018-08-15 13:26:12 -070061#include <binder/Binder.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080062
63#define INDENT " "
64#define INDENT2 " "
65#define INDENT3 " "
66#define INDENT4 " "
67
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080068using android::base::StringPrintf;
69
Michael Wrightd02c5b62014-02-10 15:10:22 -080070namespace android {
71
72// Default input dispatching timeout if there is no focused application or paused window
73// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000074constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080075
76// Amount of time to allow for all pending events to be processed when an app switch
77// key is on the way. This is used to preempt input dispatch and drop input events
78// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000079constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080080
81// Amount of time to allow for an event to be dispatched (measured since its eventTime)
82// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000083constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080084
85// Amount of time to allow touch events to be streamed out to a connection before requiring
86// that the first event be finished. This value extends the ANR timeout by the specified
87// amount. For example, if streaming is allowed to get ahead by one second relative to the
88// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000089constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
91// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +000092constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
93
94// Log a warning when an interception call takes longer than this to process.
95constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080096
97// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
99
Prabir Pradhan42611e02018-11-27 14:04:02 -0800100// Sequence number for synthesized or injected events.
101constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
102
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
104static inline nsecs_t now() {
105 return systemTime(SYSTEM_TIME_MONOTONIC);
106}
107
108static inline const char* toString(bool value) {
109 return value ? "true" : "false";
110}
111
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800112static std::string motionActionToString(int32_t action) {
113 // Convert MotionEvent action to string
114 switch(action & AMOTION_EVENT_ACTION_MASK) {
115 case AMOTION_EVENT_ACTION_DOWN:
116 return "DOWN";
117 case AMOTION_EVENT_ACTION_MOVE:
118 return "MOVE";
119 case AMOTION_EVENT_ACTION_UP:
120 return "UP";
121 case AMOTION_EVENT_ACTION_POINTER_DOWN:
122 return "POINTER_DOWN";
123 case AMOTION_EVENT_ACTION_POINTER_UP:
124 return "POINTER_UP";
125 }
126 return StringPrintf("%" PRId32, action);
127}
128
129static std::string keyActionToString(int32_t action) {
130 // Convert KeyEvent action to string
Michael Wright3dd60e22019-03-27 22:06:44 +0000131 switch (action) {
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800132 case AKEY_EVENT_ACTION_DOWN:
133 return "DOWN";
134 case AKEY_EVENT_ACTION_UP:
135 return "UP";
136 case AKEY_EVENT_ACTION_MULTIPLE:
137 return "MULTIPLE";
138 }
139 return StringPrintf("%" PRId32, action);
140}
141
Michael Wright3dd60e22019-03-27 22:06:44 +0000142static std::string dispatchModeToString(int32_t dispatchMode) {
143 switch (dispatchMode) {
144 case InputTarget::FLAG_DISPATCH_AS_IS:
145 return "DISPATCH_AS_IS";
146 case InputTarget::FLAG_DISPATCH_AS_OUTSIDE:
147 return "DISPATCH_AS_OUTSIDE";
148 case InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER:
149 return "DISPATCH_AS_HOVER_ENTER";
150 case InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT:
151 return "DISPATCH_AS_HOVER_EXIT";
152 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT:
153 return "DISPATCH_AS_SLIPPERY_EXIT";
154 case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER:
155 return "DISPATCH_AS_SLIPPERY_ENTER";
156 }
157 return StringPrintf("%" PRId32, dispatchMode);
158}
159
Michael Wrightd02c5b62014-02-10 15:10:22 -0800160static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
161 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
162 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
163}
164
165static bool isValidKeyAction(int32_t action) {
166 switch (action) {
167 case AKEY_EVENT_ACTION_DOWN:
168 case AKEY_EVENT_ACTION_UP:
169 return true;
170 default:
171 return false;
172 }
173}
174
175static bool validateKeyEvent(int32_t action) {
176 if (! isValidKeyAction(action)) {
177 ALOGE("Key event has invalid action code 0x%x", action);
178 return false;
179 }
180 return true;
181}
182
Michael Wright7b159c92015-05-14 14:48:03 +0100183static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 switch (action & AMOTION_EVENT_ACTION_MASK) {
185 case AMOTION_EVENT_ACTION_DOWN:
186 case AMOTION_EVENT_ACTION_UP:
187 case AMOTION_EVENT_ACTION_CANCEL:
188 case AMOTION_EVENT_ACTION_MOVE:
189 case AMOTION_EVENT_ACTION_OUTSIDE:
190 case AMOTION_EVENT_ACTION_HOVER_ENTER:
191 case AMOTION_EVENT_ACTION_HOVER_MOVE:
192 case AMOTION_EVENT_ACTION_HOVER_EXIT:
193 case AMOTION_EVENT_ACTION_SCROLL:
194 return true;
195 case AMOTION_EVENT_ACTION_POINTER_DOWN:
196 case AMOTION_EVENT_ACTION_POINTER_UP: {
197 int32_t index = getMotionEventActionPointerIndex(action);
Dan Albert1bd2fc02016-02-02 15:11:57 -0800198 return index >= 0 && index < pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 }
Michael Wright7b159c92015-05-14 14:48:03 +0100200 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
201 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
202 return actionButton != 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 default:
204 return false;
205 }
206}
207
Michael Wright7b159c92015-05-14 14:48:03 +0100208static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 const PointerProperties* pointerProperties) {
Michael Wright7b159c92015-05-14 14:48:03 +0100210 if (! isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 ALOGE("Motion event has invalid action code 0x%x", action);
212 return false;
213 }
214 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000215 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 pointerCount, MAX_POINTERS);
217 return false;
218 }
219 BitSet32 pointerIdBits;
220 for (size_t i = 0; i < pointerCount; i++) {
221 int32_t id = pointerProperties[i].id;
222 if (id < 0 || id > MAX_POINTER_ID) {
223 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
224 id, MAX_POINTER_ID);
225 return false;
226 }
227 if (pointerIdBits.hasBit(id)) {
228 ALOGE("Motion event has duplicate pointer id %d", id);
229 return false;
230 }
231 pointerIdBits.markBit(id);
232 }
233 return true;
234}
235
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800236static void dumpRegion(std::string& dump, const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 if (region.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800238 dump += "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800239 return;
240 }
241
242 bool first = true;
243 Region::const_iterator cur = region.begin();
244 Region::const_iterator const tail = region.end();
245 while (cur != tail) {
246 if (first) {
247 first = false;
248 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800249 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800251 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 cur++;
253 }
254}
255
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700256/**
257 * Find the entry in std::unordered_map by key, and return it.
258 * If the entry is not found, return a default constructed entry.
259 *
260 * Useful when the entries are vectors, since an empty vector will be returned
261 * if the entry is not found.
262 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
263 */
264template <typename T, typename U>
265static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
266 auto it = map.find(key);
Tiger Huang721e26f2018-07-24 22:26:19 +0800267 return it != map.end() ? it->second : T{};
268}
269
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270
271// --- InputDispatcher ---
272
Garfield Tan00f511d2019-06-12 16:55:40 -0700273InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
274 : mPolicy(policy),
275 mPendingEvent(nullptr),
276 mLastDropReason(DROP_REASON_NOT_DROPPED),
277 mAppSwitchSawKeyDown(false),
278 mAppSwitchDueTime(LONG_LONG_MAX),
279 mNextUnblockedEvent(nullptr),
280 mDispatchEnabled(false),
281 mDispatchFrozen(false),
282 mInputFilterEnabled(false),
283 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
284 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800285 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800286 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800287
Yi Kong9b14ac62018-07-17 13:48:38 -0700288 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800289
290 policy->getDispatcherConfiguration(&mConfig);
291}
292
293InputDispatcher::~InputDispatcher() {
294 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800295 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296
297 resetKeyRepeatLocked();
298 releasePendingEventLocked();
299 drainInboundQueueLocked();
300 }
301
302 while (mConnectionsByFd.size() != 0) {
303 unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
304 }
305}
306
307void InputDispatcher::dispatchOnce() {
308 nsecs_t nextWakeupTime = LONG_LONG_MAX;
309 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800310 std::scoped_lock _l(mLock);
311 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800312
313 // Run a dispatch loop if there are no pending commands.
314 // The dispatch loop might enqueue commands to run afterwards.
315 if (!haveCommandsLocked()) {
316 dispatchOnceInnerLocked(&nextWakeupTime);
317 }
318
319 // Run all pending commands if there are any.
320 // If any commands were run then force the next poll to wake up immediately.
321 if (runCommandsLockedInterruptible()) {
322 nextWakeupTime = LONG_LONG_MIN;
323 }
324 } // release lock
325
326 // Wait for callback or timeout or wake. (make sure we round up, not down)
327 nsecs_t currentTime = now();
328 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
329 mLooper->pollOnce(timeoutMillis);
330}
331
332void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
333 nsecs_t currentTime = now();
334
Jeff Browndc5992e2014-04-11 01:27:26 -0700335 // Reset the key repeat timer whenever normal dispatch is suspended while the
336 // device is in a non-interactive state. This is to ensure that we abort a key
337 // repeat if the device is just coming out of sleep.
338 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800339 resetKeyRepeatLocked();
340 }
341
342 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
343 if (mDispatchFrozen) {
344#if DEBUG_FOCUS
345 ALOGD("Dispatch frozen. Waiting some more.");
346#endif
347 return;
348 }
349
350 // Optimize latency of app switches.
351 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
352 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
353 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
354 if (mAppSwitchDueTime < *nextWakeupTime) {
355 *nextWakeupTime = mAppSwitchDueTime;
356 }
357
358 // Ready to start a new event.
359 // If we don't already have a pending event, go grab one.
360 if (! mPendingEvent) {
361 if (mInboundQueue.isEmpty()) {
362 if (isAppSwitchDue) {
363 // The inbound queue is empty so the app switch key we were waiting
364 // for will never arrive. Stop waiting for it.
365 resetPendingAppSwitchLocked(false);
366 isAppSwitchDue = false;
367 }
368
369 // Synthesize a key repeat if appropriate.
370 if (mKeyRepeatState.lastKeyEntry) {
371 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
372 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
373 } else {
374 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
375 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
376 }
377 }
378 }
379
380 // Nothing to do if there is no pending event.
381 if (!mPendingEvent) {
382 return;
383 }
384 } else {
385 // Inbound queue has at least one entry.
386 mPendingEvent = mInboundQueue.dequeueAtHead();
387 traceInboundQueueLengthLocked();
388 }
389
390 // Poke user activity for this event.
391 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
392 pokeUserActivityLocked(mPendingEvent);
393 }
394
395 // Get ready to dispatch the event.
396 resetANRTimeoutsLocked();
397 }
398
399 // Now we have an event to dispatch.
400 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700401 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800402 bool done = false;
403 DropReason dropReason = DROP_REASON_NOT_DROPPED;
404 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
405 dropReason = DROP_REASON_POLICY;
406 } else if (!mDispatchEnabled) {
407 dropReason = DROP_REASON_DISABLED;
408 }
409
410 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700411 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800412 }
413
414 switch (mPendingEvent->type) {
415 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
416 ConfigurationChangedEntry* typedEntry =
417 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
418 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
419 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
420 break;
421 }
422
423 case EventEntry::TYPE_DEVICE_RESET: {
424 DeviceResetEntry* typedEntry =
425 static_cast<DeviceResetEntry*>(mPendingEvent);
426 done = dispatchDeviceResetLocked(currentTime, typedEntry);
427 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
428 break;
429 }
430
431 case EventEntry::TYPE_KEY: {
432 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
433 if (isAppSwitchDue) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800434 if (isAppSwitchKeyEvent(typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800435 resetPendingAppSwitchLocked(true);
436 isAppSwitchDue = false;
437 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
438 dropReason = DROP_REASON_APP_SWITCH;
439 }
440 }
441 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800442 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800443 dropReason = DROP_REASON_STALE;
444 }
445 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
446 dropReason = DROP_REASON_BLOCKED;
447 }
448 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
449 break;
450 }
451
452 case EventEntry::TYPE_MOTION: {
453 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
454 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
455 dropReason = DROP_REASON_APP_SWITCH;
456 }
457 if (dropReason == DROP_REASON_NOT_DROPPED
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800458 && isStaleEvent(currentTime, typedEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800459 dropReason = DROP_REASON_STALE;
460 }
461 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
462 dropReason = DROP_REASON_BLOCKED;
463 }
464 done = dispatchMotionLocked(currentTime, typedEntry,
465 &dropReason, nextWakeupTime);
466 break;
467 }
468
469 default:
470 ALOG_ASSERT(false);
471 break;
472 }
473
474 if (done) {
475 if (dropReason != DROP_REASON_NOT_DROPPED) {
476 dropInboundEventLocked(mPendingEvent, dropReason);
477 }
Michael Wright3a981722015-06-10 15:26:13 +0100478 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800479
480 releasePendingEventLocked();
481 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
482 }
483}
484
485bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
486 bool needWake = mInboundQueue.isEmpty();
487 mInboundQueue.enqueueAtTail(entry);
488 traceInboundQueueLengthLocked();
489
490 switch (entry->type) {
491 case EventEntry::TYPE_KEY: {
492 // Optimize app switch latency.
493 // If the application takes too long to catch up then we drop all events preceding
494 // the app switch key.
495 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800496 if (isAppSwitchKeyEvent(keyEntry)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800497 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
498 mAppSwitchSawKeyDown = true;
499 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
500 if (mAppSwitchSawKeyDown) {
501#if DEBUG_APP_SWITCH
502 ALOGD("App switch is pending!");
503#endif
504 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
505 mAppSwitchSawKeyDown = false;
506 needWake = true;
507 }
508 }
509 }
510 break;
511 }
512
513 case EventEntry::TYPE_MOTION: {
514 // Optimize case where the current application is unresponsive and the user
515 // decides to touch a window in a different application.
516 // If the application takes too long to catch up then we drop all events preceding
517 // the touch into the other window.
518 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
519 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
520 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
521 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Robert Carr740167f2018-10-11 19:03:41 -0700522 && mInputTargetWaitApplicationToken != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800523 int32_t displayId = motionEntry->displayId;
524 int32_t x = int32_t(motionEntry->pointerCoords[0].
525 getAxisValue(AMOTION_EVENT_AXIS_X));
526 int32_t y = int32_t(motionEntry->pointerCoords[0].
527 getAxisValue(AMOTION_EVENT_AXIS_Y));
528 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
Yi Kong9b14ac62018-07-17 13:48:38 -0700529 if (touchedWindowHandle != nullptr
Robert Carr740167f2018-10-11 19:03:41 -0700530 && touchedWindowHandle->getApplicationToken()
531 != mInputTargetWaitApplicationToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532 // User touched a different application than the one we are waiting on.
533 // Flag the event, and start pruning the input queue.
534 mNextUnblockedEvent = motionEntry;
535 needWake = true;
536 }
537 }
538 break;
539 }
540 }
541
542 return needWake;
543}
544
545void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
546 entry->refCount += 1;
547 mRecentQueue.enqueueAtTail(entry);
548 if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
549 mRecentQueue.dequeueAtHead()->release();
550 }
551}
552
553sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800554 int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800555 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800556 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
557 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 const InputWindowInfo* windowInfo = windowHandle->getInfo();
559 if (windowInfo->displayId == displayId) {
560 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561
562 if (windowInfo->visible) {
563 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
564 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
565 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
566 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800567 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
568 if (portalToDisplayId != ADISPLAY_ID_NONE
569 && portalToDisplayId != displayId) {
570 if (addPortalWindows) {
571 // For the monitoring channels of the display.
572 mTempTouchState.addPortalWindow(windowHandle);
573 }
574 return findTouchedWindowAtLocked(
575 portalToDisplayId, x, y, addOutsideTargets, addPortalWindows);
576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800577 // Found window.
578 return windowHandle;
579 }
580 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800581
582 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
583 mTempTouchState.addOrUpdateWindow(
584 windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0));
585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800586 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800587 }
588 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700589 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590}
591
Michael Wright3dd60e22019-03-27 22:06:44 +0000592std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
593 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
594 std::vector<TouchedMonitor> touchedMonitors;
595
596 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
597 addGestureMonitors(monitors, touchedMonitors);
598 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
599 const InputWindowInfo* windowInfo = portalWindow->getInfo();
600 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
601 addGestureMonitors(monitors, touchedMonitors,
602 -windowInfo->frameLeft, -windowInfo->frameTop);
603 }
604 return touchedMonitors;
605}
606
607void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
608 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset, float yOffset) {
609 if (monitors.empty()) {
610 return;
611 }
612 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
613 for (const Monitor& monitor : monitors) {
614 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
615 }
616}
617
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
619 const char* reason;
620 switch (dropReason) {
621 case DROP_REASON_POLICY:
622#if DEBUG_INBOUND_EVENT_DETAILS
623 ALOGD("Dropped event because policy consumed it.");
624#endif
625 reason = "inbound event was dropped because the policy consumed it";
626 break;
627 case DROP_REASON_DISABLED:
Michael Wright3a981722015-06-10 15:26:13 +0100628 if (mLastDropReason != DROP_REASON_DISABLED) {
629 ALOGI("Dropped event because input dispatch is disabled.");
630 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631 reason = "inbound event was dropped because input dispatch is disabled";
632 break;
633 case DROP_REASON_APP_SWITCH:
634 ALOGI("Dropped event because of pending overdue app switch.");
635 reason = "inbound event was dropped because of pending overdue app switch";
636 break;
637 case DROP_REASON_BLOCKED:
638 ALOGI("Dropped event because the current application is not responding and the user "
639 "has started interacting with a different application.");
640 reason = "inbound event was dropped because the current application is not responding "
641 "and the user has started interacting with a different application";
642 break;
643 case DROP_REASON_STALE:
644 ALOGI("Dropped event because it is stale.");
645 reason = "inbound event was dropped because it is stale";
646 break;
647 default:
648 ALOG_ASSERT(false);
649 return;
650 }
651
652 switch (entry->type) {
653 case EventEntry::TYPE_KEY: {
654 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
655 synthesizeCancelationEventsForAllConnectionsLocked(options);
656 break;
657 }
658 case EventEntry::TYPE_MOTION: {
659 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
660 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
661 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
662 synthesizeCancelationEventsForAllConnectionsLocked(options);
663 } else {
664 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
665 synthesizeCancelationEventsForAllConnectionsLocked(options);
666 }
667 break;
668 }
669 }
670}
671
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800672static bool isAppSwitchKeyCode(int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800673 return keyCode == AKEYCODE_HOME
674 || keyCode == AKEYCODE_ENDCALL
675 || keyCode == AKEYCODE_APP_SWITCH;
676}
677
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800678bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800679 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
680 && isAppSwitchKeyCode(keyEntry->keyCode)
681 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
682 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
683}
684
685bool InputDispatcher::isAppSwitchPendingLocked() {
686 return mAppSwitchDueTime != LONG_LONG_MAX;
687}
688
689void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
690 mAppSwitchDueTime = LONG_LONG_MAX;
691
692#if DEBUG_APP_SWITCH
693 if (handled) {
694 ALOGD("App switch has arrived.");
695 } else {
696 ALOGD("App switch was abandoned.");
697 }
698#endif
699}
700
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800701bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800702 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
703}
704
705bool InputDispatcher::haveCommandsLocked() const {
706 return !mCommandQueue.isEmpty();
707}
708
709bool InputDispatcher::runCommandsLockedInterruptible() {
710 if (mCommandQueue.isEmpty()) {
711 return false;
712 }
713
714 do {
715 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
716
717 Command command = commandEntry->command;
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700718 command(*this, commandEntry); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719
720 commandEntry->connection.clear();
721 delete commandEntry;
722 } while (! mCommandQueue.isEmpty());
723 return true;
724}
725
726InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
727 CommandEntry* commandEntry = new CommandEntry(command);
728 mCommandQueue.enqueueAtTail(commandEntry);
729 return commandEntry;
730}
731
732void InputDispatcher::drainInboundQueueLocked() {
733 while (! mInboundQueue.isEmpty()) {
734 EventEntry* entry = mInboundQueue.dequeueAtHead();
735 releaseInboundEventLocked(entry);
736 }
737 traceInboundQueueLengthLocked();
738}
739
740void InputDispatcher::releasePendingEventLocked() {
741 if (mPendingEvent) {
742 resetANRTimeoutsLocked();
743 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700744 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800745 }
746}
747
748void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
749 InjectionState* injectionState = entry->injectionState;
750 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
751#if DEBUG_DISPATCH_CYCLE
752 ALOGD("Injected inbound event was dropped.");
753#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800754 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800755 }
756 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700757 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800758 }
759 addRecentEventLocked(entry);
760 entry->release();
761}
762
763void InputDispatcher::resetKeyRepeatLocked() {
764 if (mKeyRepeatState.lastKeyEntry) {
765 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700766 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767 }
768}
769
770InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
771 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
772
773 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700774 uint32_t policyFlags = entry->policyFlags &
775 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800776 if (entry->refCount == 1) {
777 entry->recycle();
778 entry->eventTime = currentTime;
779 entry->policyFlags = policyFlags;
780 entry->repeatCount += 1;
781 } else {
Prabir Pradhan42611e02018-11-27 14:04:02 -0800782 KeyEntry* newEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100783 entry->deviceId, entry->source, entry->displayId, policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800784 entry->action, entry->flags, entry->keyCode, entry->scanCode,
785 entry->metaState, entry->repeatCount + 1, entry->downTime);
786
787 mKeyRepeatState.lastKeyEntry = newEntry;
788 entry->release();
789
790 entry = newEntry;
791 }
792 entry->syntheticRepeat = true;
793
794 // Increment reference count since we keep a reference to the event in
795 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
796 entry->refCount += 1;
797
798 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
799 return entry;
800}
801
802bool InputDispatcher::dispatchConfigurationChangedLocked(
803 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
804#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700805 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806#endif
807
808 // Reset key repeating in case a keyboard device was added or removed or something.
809 resetKeyRepeatLocked();
810
811 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700812 CommandEntry* commandEntry =
813 postCommandLocked(&InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800814 commandEntry->eventTime = entry->eventTime;
815 return true;
816}
817
818bool InputDispatcher::dispatchDeviceResetLocked(
819 nsecs_t currentTime, DeviceResetEntry* entry) {
820#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700821 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
822 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800823#endif
824
825 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
826 "device was reset");
827 options.deviceId = entry->deviceId;
828 synthesizeCancelationEventsForAllConnectionsLocked(options);
829 return true;
830}
831
832bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
833 DropReason* dropReason, nsecs_t* nextWakeupTime) {
834 // Preprocessing.
835 if (! entry->dispatchInProgress) {
836 if (entry->repeatCount == 0
837 && entry->action == AKEY_EVENT_ACTION_DOWN
838 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
839 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
840 if (mKeyRepeatState.lastKeyEntry
841 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
842 // We have seen two identical key downs in a row which indicates that the device
843 // driver is automatically generating key repeats itself. We take note of the
844 // repeat here, but we disable our own next key repeat timer since it is clear that
845 // we will not need to synthesize key repeats ourselves.
846 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
847 resetKeyRepeatLocked();
848 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
849 } else {
850 // Not a repeat. Save key down state in case we do see a repeat later.
851 resetKeyRepeatLocked();
852 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
853 }
854 mKeyRepeatState.lastKeyEntry = entry;
855 entry->refCount += 1;
856 } else if (! entry->syntheticRepeat) {
857 resetKeyRepeatLocked();
858 }
859
860 if (entry->repeatCount == 1) {
861 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
862 } else {
863 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
864 }
865
866 entry->dispatchInProgress = true;
867
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800868 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800869 }
870
871 // Handle case where the policy asked us to try again later last time.
872 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
873 if (currentTime < entry->interceptKeyWakeupTime) {
874 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
875 *nextWakeupTime = entry->interceptKeyWakeupTime;
876 }
877 return false; // wait until next wakeup
878 }
879 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
880 entry->interceptKeyWakeupTime = 0;
881 }
882
883 // Give the policy a chance to intercept the key.
884 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
885 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
886 CommandEntry* commandEntry = postCommandLocked(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700887 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800888 sp<InputWindowHandle> focusedWindowHandle =
889 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
890 if (focusedWindowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -0700891 commandEntry->inputChannel =
892 getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800893 }
894 commandEntry->keyEntry = entry;
895 entry->refCount += 1;
896 return false; // wait for the command to run
897 } else {
898 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
899 }
900 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
901 if (*dropReason == DROP_REASON_NOT_DROPPED) {
902 *dropReason = DROP_REASON_POLICY;
903 }
904 }
905
906 // Clean up if dropping the event.
907 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800908 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800909 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800910 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 return true;
912 }
913
914 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800915 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
917 entry, inputTargets, nextWakeupTime);
918 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
919 return false;
920 }
921
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800922 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800923 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
924 return true;
925 }
926
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800927 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000928 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929
930 // Dispatch the key.
931 dispatchEventLocked(currentTime, entry, inputTargets);
932 return true;
933}
934
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800935void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800936#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100937 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
938 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +0800939 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800940 prefix,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100941 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Arthur Hung82a4cad2018-11-15 12:10:30 +0800943 entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800944#endif
945}
946
947bool InputDispatcher::dispatchMotionLocked(
948 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000949 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800950 // Preprocessing.
951 if (! entry->dispatchInProgress) {
952 entry->dispatchInProgress = true;
953
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800954 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800955 }
956
957 // Clean up if dropping the event.
958 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800959 setInjectionResult(entry, *dropReason == DROP_REASON_POLICY
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
961 return true;
962 }
963
964 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
965
966 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800967 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800968
969 bool conflictingPointerActions = false;
970 int32_t injectionResult;
971 if (isPointerEvent) {
972 // Pointer event. (eg. touchscreen)
973 injectionResult = findTouchedWindowTargetsLocked(currentTime,
974 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
975 } else {
976 // Non touch event. (eg. trackball)
977 injectionResult = findFocusedWindowTargetsLocked(currentTime,
978 entry, inputTargets, nextWakeupTime);
979 }
980 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
981 return false;
982 }
983
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800984 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +0100986 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
987 CancelationOptions::Mode mode(isPointerEvent ?
988 CancelationOptions::CANCEL_POINTER_EVENTS :
989 CancelationOptions::CANCEL_NON_POINTER_EVENTS);
990 CancelationOptions options(mode, "input event injection failed");
991 synthesizeCancelationEventsForMonitorsLocked(options);
992 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800993 return true;
994 }
995
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800996 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000997 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800998
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800999 if (isPointerEvent) {
1000 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1001 if (stateIndex >= 0) {
1002 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001003 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001004 // The event has gone through these portal windows, so we add monitoring targets of
1005 // the corresponding displays as well.
1006 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001007 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001008 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001009 -windowInfo->frameLeft, -windowInfo->frameTop);
1010 }
1011 }
1012 }
1013 }
1014
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015 // Dispatch the motion.
1016 if (conflictingPointerActions) {
1017 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
1018 "conflicting pointer actions");
1019 synthesizeCancelationEventsForAllConnectionsLocked(options);
1020 }
1021 dispatchEventLocked(currentTime, entry, inputTargets);
1022 return true;
1023}
1024
1025
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001026void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001028 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1029 ", policyFlags=0x%x, "
Michael Wright7b159c92015-05-14 14:48:03 +01001030 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1031 "metaState=0x%x, buttonState=0x%x,"
Arthur Hung82a4cad2018-11-15 12:10:30 +08001032 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001033 prefix,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001034 entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001035 entry->action, entry->actionButton, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 entry->metaState, entry->buttonState,
1037 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Arthur Hung82a4cad2018-11-15 12:10:30 +08001038 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039
1040 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1041 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1042 "x=%f, y=%f, pressure=%f, size=%f, "
1043 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001044 "orientation=%f",
Michael Wrightd02c5b62014-02-10 15:10:22 -08001045 i, entry->pointerProperties[i].id,
1046 entry->pointerProperties[i].toolType,
1047 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1048 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1049 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1050 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1051 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1052 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1053 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1054 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08001055 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056 }
1057#endif
1058}
1059
1060void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001061 EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001062 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063#if DEBUG_DISPATCH_CYCLE
1064 ALOGD("dispatchEventToCurrentInputTargets");
1065#endif
1066
1067 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1068
1069 pokeUserActivityLocked(eventEntry);
1070
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001071 for (const InputTarget& inputTarget : inputTargets) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001072 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1073 if (connectionIndex >= 0) {
1074 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1075 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1076 } else {
1077#if DEBUG_FOCUS
1078 ALOGD("Dropping event delivery to target with channel '%s' because it "
1079 "is no longer registered with the input dispatcher.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001080 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001081#endif
1082 }
1083 }
1084}
1085
1086int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1087 const EventEntry* entry,
1088 const sp<InputApplicationHandle>& applicationHandle,
1089 const sp<InputWindowHandle>& windowHandle,
1090 nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001091 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001092 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1093#if DEBUG_FOCUS
1094 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1095#endif
1096 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1097 mInputTargetWaitStartTime = currentTime;
1098 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1099 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001100 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001101 }
1102 } else {
1103 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1104#if DEBUG_FOCUS
1105 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001106 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 reason);
1108#endif
1109 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001110 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001112 } else if (applicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001113 timeout = applicationHandle->getDispatchingTimeout(
1114 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1115 } else {
1116 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1117 }
1118
1119 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1120 mInputTargetWaitStartTime = currentTime;
1121 mInputTargetWaitTimeoutTime = currentTime + timeout;
1122 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001123 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124
Yi Kong9b14ac62018-07-17 13:48:38 -07001125 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001126 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001127 }
Robert Carr740167f2018-10-11 19:03:41 -07001128 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1129 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001130 }
1131 }
1132 }
1133
1134 if (mInputTargetWaitTimeoutExpired) {
1135 return INPUT_EVENT_INJECTION_TIMED_OUT;
1136 }
1137
1138 if (currentTime >= mInputTargetWaitTimeoutTime) {
1139 onANRLocked(currentTime, applicationHandle, windowHandle,
1140 entry->eventTime, mInputTargetWaitStartTime, reason);
1141
1142 // Force poll loop to wake up immediately on next iteration once we get the
1143 // ANR response back from the policy.
1144 *nextWakeupTime = LONG_LONG_MIN;
1145 return INPUT_EVENT_INJECTION_PENDING;
1146 } else {
1147 // Force poll loop to wake up when timeout is due.
1148 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1149 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1150 }
1151 return INPUT_EVENT_INJECTION_PENDING;
1152 }
1153}
1154
Robert Carr803535b2018-08-02 16:38:15 -07001155void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1156 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1157 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1158 state.removeWindowByToken(token);
1159 }
1160}
1161
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1163 const sp<InputChannel>& inputChannel) {
1164 if (newTimeout > 0) {
1165 // Extend the timeout.
1166 mInputTargetWaitTimeoutTime = now() + newTimeout;
1167 } else {
1168 // Give up.
1169 mInputTargetWaitTimeoutExpired = true;
1170
1171 // Input state will not be realistic. Mark it out of sync.
1172 if (inputChannel.get()) {
1173 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1174 if (connectionIndex >= 0) {
1175 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
Robert Carr803535b2018-08-02 16:38:15 -07001176 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177
Robert Carr803535b2018-08-02 16:38:15 -07001178 if (token != nullptr) {
1179 removeWindowByTokenLocked(token);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180 }
1181
1182 if (connection->status == Connection::STATUS_NORMAL) {
1183 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1184 "application not responding");
1185 synthesizeCancelationEventsForConnectionLocked(connection, options);
1186 }
1187 }
1188 }
1189 }
1190}
1191
1192nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1193 nsecs_t currentTime) {
1194 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1195 return currentTime - mInputTargetWaitStartTime;
1196 }
1197 return 0;
1198}
1199
1200void InputDispatcher::resetANRTimeoutsLocked() {
1201#if DEBUG_FOCUS
1202 ALOGD("Resetting ANR timeouts.");
1203#endif
1204
1205 // Reset input target wait timeout.
1206 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001207 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208}
1209
Tiger Huang721e26f2018-07-24 22:26:19 +08001210/**
1211 * Get the display id that the given event should go to. If this event specifies a valid display id,
1212 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1213 * Focused display is the display that the user most recently interacted with.
1214 */
1215int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1216 int32_t displayId;
1217 switch (entry->type) {
1218 case EventEntry::TYPE_KEY: {
1219 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1220 displayId = typedEntry->displayId;
1221 break;
1222 }
1223 case EventEntry::TYPE_MOTION: {
1224 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1225 displayId = typedEntry->displayId;
1226 break;
1227 }
1228 default: {
1229 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1230 return ADISPLAY_ID_NONE;
1231 }
1232 }
1233 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1234}
1235
Michael Wrightd02c5b62014-02-10 15:10:22 -08001236int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001237 const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001239 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240
Tiger Huang721e26f2018-07-24 22:26:19 +08001241 int32_t displayId = getTargetDisplayId(entry);
1242 sp<InputWindowHandle> focusedWindowHandle =
1243 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1244 sp<InputApplicationHandle> focusedApplicationHandle =
1245 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1246
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247 // If there is no currently focused window and no focused application
1248 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001249 if (focusedWindowHandle == nullptr) {
1250 if (focusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001252 focusedApplicationHandle, nullptr, nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 "Waiting because no window has focus but there is a "
1254 "focused application that may eventually add a window "
1255 "when it finishes starting up.");
1256 goto Unresponsive;
1257 }
1258
Arthur Hung3b413f22018-10-26 18:05:34 +08001259 ALOGI("Dropping event because there is no focused window or focused application in display "
1260 "%" PRId32 ".", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1262 goto Failed;
1263 }
1264
1265 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001266 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001267 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1268 goto Failed;
1269 }
1270
Jeff Brownffb49772014-10-10 19:01:34 -07001271 // Check whether the window is ready for more input.
1272 reason = checkWindowReadyForMoreInputLocked(currentTime,
Tiger Huang721e26f2018-07-24 22:26:19 +08001273 focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001274 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001275 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Tiger Huang721e26f2018-07-24 22:26:19 +08001276 focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001277 goto Unresponsive;
1278 }
1279
1280 // Success! Output targets.
1281 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001282 addWindowTargetLocked(focusedWindowHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1284 inputTargets);
1285
1286 // Done.
1287Failed:
1288Unresponsive:
1289 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001290 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291#if DEBUG_FOCUS
1292 ALOGD("findFocusedWindow finished: injectionResult=%d, "
1293 "timeSpentWaitingForApplication=%0.1fms",
1294 injectionResult, timeSpentWaitingForApplication / 1000000.0);
1295#endif
1296 return injectionResult;
1297}
1298
1299int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001300 const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001301 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001302 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001303 enum InjectionPermission {
1304 INJECTION_PERMISSION_UNKNOWN,
1305 INJECTION_PERMISSION_GRANTED,
1306 INJECTION_PERMISSION_DENIED
1307 };
1308
Michael Wrightd02c5b62014-02-10 15:10:22 -08001309 // For security reasons, we defer updating the touch state until we are sure that
1310 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311 int32_t displayId = entry->displayId;
1312 int32_t action = entry->action;
1313 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1314
1315 // Update the touch state as needed based on the properties of the touch event.
1316 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1317 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1318 sp<InputWindowHandle> newHoverWindowHandle;
1319
Jeff Brownf086ddb2014-02-11 14:28:48 -08001320 // Copy current touch state into mTempTouchState.
1321 // This state is always reset at the end of this function, so if we don't find state
1322 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001323 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001324 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1325 if (oldStateIndex >= 0) {
1326 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1327 mTempTouchState.copyFrom(*oldState);
1328 }
1329
1330 bool isSplit = mTempTouchState.split;
1331 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
1332 && (mTempTouchState.deviceId != entry->deviceId
1333 || mTempTouchState.source != entry->source
1334 || mTempTouchState.displayId != displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001335 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1336 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1337 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1338 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1339 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1340 || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001341 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001342 bool wrongDevice = false;
1343 if (newGesture) {
1344 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001345 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001346#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001347 ALOGD("Dropping event because a pointer for a different device is already down "
1348 "in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001350 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1352 switchedDevice = false;
1353 wrongDevice = true;
1354 goto Failed;
1355 }
1356 mTempTouchState.reset();
1357 mTempTouchState.down = down;
1358 mTempTouchState.deviceId = entry->deviceId;
1359 mTempTouchState.source = entry->source;
1360 mTempTouchState.displayId = displayId;
1361 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001362 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1363#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001364 ALOGI("Dropping move event because a pointer for a different device is already active "
1365 "in display %" PRId32, displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001366#endif
1367 // TODO: test multiple simultaneous input streams.
1368 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1369 switchedDevice = false;
1370 wrongDevice = true;
1371 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001372 }
1373
1374 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1375 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1376
Garfield Tan00f511d2019-06-12 16:55:40 -07001377 int32_t x;
1378 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001379 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001380 // Always dispatch mouse events to cursor position.
1381 if (isFromMouse) {
1382 x = int32_t(entry->xCursorPosition);
1383 y = int32_t(entry->yCursorPosition);
1384 } else {
1385 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1386 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1387 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001388 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001389 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
Michael Wright3dd60e22019-03-27 22:06:44 +00001390 displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
1391
1392 std::vector<TouchedMonitor> newGestureMonitors = isDown
1393 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1394 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395
Michael Wrightd02c5b62014-02-10 15:10:22 -08001396 // Figure out whether splitting will be allowed for this window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001397 if (newTouchedWindowHandle != nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001398 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001399 // New window supports splitting, but we should never split mouse events.
1400 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 } else if (isSplit) {
1402 // New window does not support splitting but we have already split events.
1403 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001404 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405 }
1406
1407 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001408 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001409 // Try to assign the pointer to the first foreground window we find, if there is one.
1410 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001411 }
1412
1413 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1414 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
1415 "(%d, %d) in display %" PRId32 ".", x, y, displayId);
1416 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1417 goto Failed;
1418 }
1419
1420 if (newTouchedWindowHandle != nullptr) {
1421 // Set target flags.
1422 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1423 if (isSplit) {
1424 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001425 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001426 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1427 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1428 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1429 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1430 }
1431
1432 // Update hover state.
1433 if (isHoverAction) {
1434 newHoverWindowHandle = newTouchedWindowHandle;
1435 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1436 newHoverWindowHandle = mLastHoverWindowHandle;
1437 }
1438
1439 // Update the temporary touch state.
1440 BitSet32 pointerIds;
1441 if (isSplit) {
1442 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1443 pointerIds.markBit(pointerId);
1444 }
1445 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001446 }
1447
Michael Wright3dd60e22019-03-27 22:06:44 +00001448 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001449 } else {
1450 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1451
1452 // If the pointer is not currently down, then ignore the event.
1453 if (! mTempTouchState.down) {
1454#if DEBUG_FOCUS
1455 ALOGD("Dropping event because the pointer is not down or we previously "
Arthur Hung3b413f22018-10-26 18:05:34 +08001456 "dropped the pointer down event in display %" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457#endif
1458 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1459 goto Failed;
1460 }
1461
1462 // Check whether touches should slip outside of the current foreground window.
1463 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1464 && entry->pointerCount == 1
1465 && mTempTouchState.isSlippery()) {
1466 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1467 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1468
1469 sp<InputWindowHandle> oldTouchedWindowHandle =
1470 mTempTouchState.getFirstForegroundWindowHandle();
1471 sp<InputWindowHandle> newTouchedWindowHandle =
1472 findTouchedWindowAtLocked(displayId, x, y);
1473 if (oldTouchedWindowHandle != newTouchedWindowHandle
Michael Wright3dd60e22019-03-27 22:06:44 +00001474 && oldTouchedWindowHandle != nullptr
Yi Kong9b14ac62018-07-17 13:48:38 -07001475 && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001477 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001478 oldTouchedWindowHandle->getName().c_str(),
Arthur Hung3b413f22018-10-26 18:05:34 +08001479 newTouchedWindowHandle->getName().c_str(),
1480 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001481#endif
1482 // Make a slippery exit from the old window.
1483 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1484 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1485
1486 // Make a slippery entrance into the new window.
1487 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1488 isSplit = true;
1489 }
1490
1491 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1492 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1493 if (isSplit) {
1494 targetFlags |= InputTarget::FLAG_SPLIT;
1495 }
1496 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1497 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1498 }
1499
1500 BitSet32 pointerIds;
1501 if (isSplit) {
1502 pointerIds.markBit(entry->pointerProperties[0].id);
1503 }
1504 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1505 }
1506 }
1507 }
1508
1509 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1510 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001511 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001512#if DEBUG_HOVER
1513 ALOGD("Sending hover exit event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001514 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001515#endif
1516 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1517 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1518 }
1519
1520 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001521 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001522#if DEBUG_HOVER
1523 ALOGD("Sending hover enter event to window %s.",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001524 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525#endif
1526 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1527 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1528 }
1529 }
1530
1531 // Check permission to inject into all touched foreground windows and ensure there
1532 // is at least one touched foreground window.
1533 {
1534 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001535 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1537 haveForegroundWindow = true;
1538 if (! checkInjectionPermission(touchedWindow.windowHandle,
1539 entry->injectionState)) {
1540 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1541 injectionPermission = INJECTION_PERMISSION_DENIED;
1542 goto Failed;
1543 }
1544 }
1545 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001546 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1547 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001548#if DEBUG_FOCUS
Michael Wright3dd60e22019-03-27 22:06:44 +00001549 ALOGD("Dropping event because there is no touched foreground window in display %"
1550 PRId32 " or gesture monitor to receive it.", displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001551#endif
1552 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1553 goto Failed;
1554 }
1555
1556 // Permission granted to injection into all touched foreground windows.
1557 injectionPermission = INJECTION_PERMISSION_GRANTED;
1558 }
1559
1560 // Check whether windows listening for outside touches are owned by the same UID. If it is
1561 // set the policy flag that we will not reveal coordinate information to this window.
1562 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1563 sp<InputWindowHandle> foregroundWindowHandle =
1564 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001565 if (foregroundWindowHandle) {
1566 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1567 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1568 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1569 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1570 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1571 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1572 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1573 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001574 }
1575 }
1576 }
1577 }
1578
1579 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001580 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001581 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001582 // Check whether the window is ready for more input.
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001583 std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001584 touchedWindow.windowHandle, entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001585 if (!reason.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001586 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Yi Kong9b14ac62018-07-17 13:48:38 -07001587 nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001588 goto Unresponsive;
1589 }
1590 }
1591 }
1592
1593 // If this is the first pointer going down and the touched window has a wallpaper
1594 // then also add the touched wallpaper windows so they are locked in for the duration
1595 // of the touch gesture.
1596 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1597 // engine only supports touch events. We would need to add a mechanism similar
1598 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1599 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1600 sp<InputWindowHandle> foregroundWindowHandle =
1601 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001602 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001603 const std::vector<sp<InputWindowHandle>> windowHandles =
1604 getWindowHandlesLocked(displayId);
1605 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 const InputWindowInfo* info = windowHandle->getInfo();
1607 if (info->displayId == displayId
1608 && windowHandle->getInfo()->layoutParamsType
1609 == InputWindowInfo::TYPE_WALLPAPER) {
1610 mTempTouchState.addOrUpdateWindow(windowHandle,
1611 InputTarget::FLAG_WINDOW_IS_OBSCURED
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001612 | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 | InputTarget::FLAG_DISPATCH_AS_IS,
1614 BitSet32(0));
1615 }
1616 }
1617 }
1618 }
1619
1620 // Success! Output targets.
1621 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1622
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001623 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1625 touchedWindow.pointerIds, inputTargets);
1626 }
1627
Michael Wright3dd60e22019-03-27 22:06:44 +00001628 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1629 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
1630 touchedMonitor.yOffset, inputTargets);
1631 }
1632
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633 // Drop the outside or hover touch windows since we will not care about them
1634 // in the next iteration.
1635 mTempTouchState.filterNonAsIsTouchWindows();
1636
1637Failed:
1638 // Check injection permission once and for all.
1639 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001640 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641 injectionPermission = INJECTION_PERMISSION_GRANTED;
1642 } else {
1643 injectionPermission = INJECTION_PERMISSION_DENIED;
1644 }
1645 }
1646
1647 // Update final pieces of touch state if the injector had permission.
1648 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1649 if (!wrongDevice) {
1650 if (switchedDevice) {
1651#if DEBUG_FOCUS
1652 ALOGD("Conflicting pointer actions: Switched to a different device.");
1653#endif
1654 *outConflictingPointerActions = true;
1655 }
1656
1657 if (isHoverAction) {
1658 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001659 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001660#if DEBUG_FOCUS
1661 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1662#endif
1663 *outConflictingPointerActions = true;
1664 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001665 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001666 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1667 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001668 mTempTouchState.deviceId = entry->deviceId;
1669 mTempTouchState.source = entry->source;
1670 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001671 }
1672 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1673 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1674 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001675 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001676 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1677 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001678 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001679#if DEBUG_FOCUS
1680 ALOGD("Conflicting pointer actions: Down received while already down.");
1681#endif
1682 *outConflictingPointerActions = true;
1683 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001684 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1685 // One pointer went up.
1686 if (isSplit) {
1687 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1688 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1689
1690 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001691 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001692 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1693 touchedWindow.pointerIds.clearBit(pointerId);
1694 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001695 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 continue;
1697 }
1698 }
1699 i += 1;
1700 }
1701 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001702 }
1703
1704 // Save changes unless the action was scroll in which case the temporary touch
1705 // state was only valid for this one action.
1706 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1707 if (mTempTouchState.displayId >= 0) {
1708 if (oldStateIndex >= 0) {
1709 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1710 } else {
1711 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1712 }
1713 } else if (oldStateIndex >= 0) {
1714 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001716 }
1717
1718 // Update hover state.
1719 mLastHoverWindowHandle = newHoverWindowHandle;
1720 }
1721 } else {
1722#if DEBUG_FOCUS
1723 ALOGD("Not updating touch focus because injection was denied.");
1724#endif
1725 }
1726
1727Unresponsive:
1728 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1729 mTempTouchState.reset();
1730
1731 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001732 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733#if DEBUG_FOCUS
1734 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1735 "timeSpentWaitingForApplication=%0.1fms",
1736 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1737#endif
1738 return injectionResult;
1739}
1740
1741void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001742 int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001743 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1744 if (inputChannel == nullptr) {
1745 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1746 return;
1747 }
1748
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001750 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001751 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 target.flags = targetFlags;
1753 target.xOffset = - windowInfo->frameLeft;
1754 target.yOffset = - windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001755 target.globalScaleFactor = windowInfo->globalScaleFactor;
1756 target.windowXScale = windowInfo->windowXScale;
1757 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001759 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001760}
1761
Michael Wright3dd60e22019-03-27 22:06:44 +00001762void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
1763 int32_t displayId, float xOffset, float yOffset) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001764
Michael Wright3dd60e22019-03-27 22:06:44 +00001765 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1766 mGlobalMonitorsByDisplay.find(displayId);
1767
1768 if (it != mGlobalMonitorsByDisplay.end()) {
1769 const std::vector<Monitor>& monitors = it->second;
1770 for (const Monitor& monitor : monitors) {
1771 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001772 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001773 }
1774}
1775
Michael Wright3dd60e22019-03-27 22:06:44 +00001776void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor,
1777 float xOffset, float yOffset, std::vector<InputTarget>& inputTargets) {
1778 InputTarget target;
1779 target.inputChannel = monitor.inputChannel;
1780 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1781 target.xOffset = xOffset;
1782 target.yOffset = yOffset;
1783 target.pointerIds.clear();
1784 target.globalScaleFactor = 1.0f;
1785 inputTargets.push_back(target);
1786}
1787
Michael Wrightd02c5b62014-02-10 15:10:22 -08001788bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1789 const InjectionState* injectionState) {
1790 if (injectionState
Yi Kong9b14ac62018-07-17 13:48:38 -07001791 && (windowHandle == nullptr
Michael Wrightd02c5b62014-02-10 15:10:22 -08001792 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1793 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001794 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1796 "owned by uid %d",
1797 injectionState->injectorPid, injectionState->injectorUid,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001798 windowHandle->getName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08001799 windowHandle->getInfo()->ownerUid);
1800 } else {
1801 ALOGW("Permission denied: injecting event from pid %d uid %d",
1802 injectionState->injectorPid, injectionState->injectorUid);
1803 }
1804 return false;
1805 }
1806 return true;
1807}
1808
1809bool InputDispatcher::isWindowObscuredAtPointLocked(
1810 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1811 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001812 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1813 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001814 if (otherHandle == windowHandle) {
1815 break;
1816 }
1817
1818 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1819 if (otherInfo->displayId == displayId
1820 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1821 && otherInfo->frameContainsPoint(x, y)) {
1822 return true;
1823 }
1824 }
1825 return false;
1826}
1827
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001828
1829bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1830 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001831 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001832 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001833 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001834 if (otherHandle == windowHandle) {
1835 break;
1836 }
1837
1838 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1839 if (otherInfo->displayId == displayId
1840 && otherInfo->visible && !otherInfo->isTrustedOverlay()
1841 && otherInfo->overlaps(windowInfo)) {
1842 return true;
1843 }
1844 }
1845 return false;
1846}
1847
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001848std::string InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
Jeff Brownffb49772014-10-10 19:01:34 -07001849 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
1850 const char* targetType) {
1851 // If the window is paused then keep waiting.
1852 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001853 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001854 }
1855
1856 // If the window's connection is not registered then keep waiting.
Robert Carr5c8a0262018-10-03 16:30:44 -07001857 ssize_t connectionIndex = getConnectionIndexLocked(
1858 getInputChannelLocked(windowHandle->getToken()));
Jeff Brownffb49772014-10-10 19:01:34 -07001859 if (connectionIndex < 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001860 return StringPrintf("Waiting because the %s window's input channel is not "
Jeff Brownffb49772014-10-10 19:01:34 -07001861 "registered with the input dispatcher. The window may be in the process "
1862 "of being removed.", targetType);
1863 }
1864
1865 // If the connection is dead then keep waiting.
1866 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1867 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001868 return StringPrintf("Waiting because the %s window's input connection is %s."
Jeff Brownffb49772014-10-10 19:01:34 -07001869 "The window may be in the process of being removed.", targetType,
1870 connection->getStatusLabel());
1871 }
1872
1873 // If the connection is backed up then keep waiting.
1874 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001875 return StringPrintf("Waiting because the %s window's input channel is full. "
Jeff Brownffb49772014-10-10 19:01:34 -07001876 "Outbound queue length: %d. Wait queue length: %d.",
1877 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
1878 }
1879
1880 // Ensure that the dispatch queues aren't too far backed up for this event.
1881 if (eventEntry->type == EventEntry::TYPE_KEY) {
1882 // If the event is a key event, then we must wait for all previous events to
1883 // complete before delivering it because previous events may have the
1884 // side-effect of transferring focus to a different window and we want to
1885 // ensure that the following keys are sent to the new window.
1886 //
1887 // Suppose the user touches a button in a window then immediately presses "A".
1888 // If the button causes a pop-up window to appear then we want to ensure that
1889 // the "A" key is delivered to the new pop-up window. This is because users
1890 // often anticipate pending UI changes when typing on a keyboard.
1891 // To obtain this behavior, we must serialize key events with respect to all
1892 // prior input events.
1893 if (!connection->outboundQueue.isEmpty() || !connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001894 return StringPrintf("Waiting to send key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001895 "finished processing all of the input events that were previously "
1896 "delivered to it. Outbound queue length: %d. Wait queue length: %d.",
1897 targetType, connection->outboundQueue.count(), connection->waitQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001898 }
Jeff Brownffb49772014-10-10 19:01:34 -07001899 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001900 // Touch events can always be sent to a window immediately because the user intended
1901 // to touch whatever was visible at the time. Even if focus changes or a new
1902 // window appears moments later, the touch event was meant to be delivered to
1903 // whatever window happened to be on screen at the time.
1904 //
1905 // Generic motion events, such as trackball or joystick events are a little trickier.
1906 // Like key events, generic motion events are delivered to the focused window.
1907 // Unlike key events, generic motion events don't tend to transfer focus to other
1908 // windows and it is not important for them to be serialized. So we prefer to deliver
1909 // generic motion events as soon as possible to improve efficiency and reduce lag
1910 // through batching.
1911 //
1912 // The one case where we pause input event delivery is when the wait queue is piling
1913 // up with lots of events because the application is not responding.
1914 // This condition ensures that ANRs are detected reliably.
1915 if (!connection->waitQueue.isEmpty()
1916 && currentTime >= connection->waitQueue.head->deliveryTime
1917 + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001918 return StringPrintf("Waiting to send non-key event because the %s window has not "
Jeff Brownffb49772014-10-10 19:01:34 -07001919 "finished processing certain input events that were delivered to it over "
1920 "%0.1fms ago. Wait queue length: %d. Wait queue head age: %0.1fms.",
1921 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1922 connection->waitQueue.count(),
1923 (currentTime - connection->waitQueue.head->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 }
1925 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001926 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927}
1928
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001929std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001930 const sp<InputApplicationHandle>& applicationHandle,
1931 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001932 if (applicationHandle != nullptr) {
1933 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001934 std::string label(applicationHandle->getName());
1935 label += " - ";
1936 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001937 return label;
1938 } else {
1939 return applicationHandle->getName();
1940 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001941 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001942 return windowHandle->getName();
1943 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001944 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001945 }
1946}
1947
1948void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001949 int32_t displayId = getTargetDisplayId(eventEntry);
1950 sp<InputWindowHandle> focusedWindowHandle =
1951 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1952 if (focusedWindowHandle != nullptr) {
1953 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001954 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1955#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001956 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001957#endif
1958 return;
1959 }
1960 }
1961
1962 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1963 switch (eventEntry->type) {
1964 case EventEntry::TYPE_MOTION: {
1965 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1966 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1967 return;
1968 }
1969
1970 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1971 eventType = USER_ACTIVITY_EVENT_TOUCH;
1972 }
1973 break;
1974 }
1975 case EventEntry::TYPE_KEY: {
1976 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1977 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1978 return;
1979 }
1980 eventType = USER_ACTIVITY_EVENT_BUTTON;
1981 break;
1982 }
1983 }
1984
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001985 CommandEntry* commandEntry =
1986 postCommandLocked(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001987 commandEntry->eventTime = eventEntry->eventTime;
1988 commandEntry->userActivityEventType = eventType;
1989}
1990
1991void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1992 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001993 if (ATRACE_ENABLED()) {
1994 std::string message = StringPrintf(
1995 "prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
1996 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
1997 ATRACE_NAME(message.c_str());
1998 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001999#if DEBUG_DISPATCH_CYCLE
2000 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Robert Carre07e1032018-11-26 12:55:53 -08002001 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
2002 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002003 connection->getInputChannelName().c_str(), inputTarget->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002004 inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002005 inputTarget->globalScaleFactor,
2006 inputTarget->windowXScale, inputTarget->windowYScale,
2007 inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008#endif
2009
2010 // Skip this event if the connection status is not normal.
2011 // We don't want to enqueue additional outbound events if the connection is broken.
2012 if (connection->status != Connection::STATUS_NORMAL) {
2013#if DEBUG_DISPATCH_CYCLE
2014 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002015 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002016#endif
2017 return;
2018 }
2019
2020 // Split a motion event if needed.
2021 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2022 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2023
2024 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2025 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
2026 MotionEntry* splitMotionEntry = splitMotionEvent(
2027 originalMotionEntry, inputTarget->pointerIds);
2028 if (!splitMotionEntry) {
2029 return; // split event was dropped
2030 }
2031#if DEBUG_FOCUS
2032 ALOGD("channel '%s' ~ Split motion event.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002033 connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002034 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002035#endif
2036 enqueueDispatchEntriesLocked(currentTime, connection,
2037 splitMotionEntry, inputTarget);
2038 splitMotionEntry->release();
2039 return;
2040 }
2041 }
2042
2043 // Not splitting. Enqueue dispatch entries for the event as is.
2044 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2045}
2046
2047void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
2048 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002049 if (ATRACE_ENABLED()) {
2050 std::string message = StringPrintf(
2051 "enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2052 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
2053 ATRACE_NAME(message.c_str());
2054 }
2055
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 bool wasEmpty = connection->outboundQueue.isEmpty();
2057
2058 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002059 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002061 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002062 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002063 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002064 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002065 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002066 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002067 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002068 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002069 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002070 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2071
2072 // If the outbound queue was previously empty, start the dispatch cycle going.
2073 if (wasEmpty && !connection->outboundQueue.isEmpty()) {
2074 startDispatchCycleLocked(currentTime, connection);
2075 }
2076}
2077
chaviw8c9cf542019-03-25 13:02:48 -07002078void InputDispatcher::enqueueDispatchEntryLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2080 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002081 if (ATRACE_ENABLED()) {
2082 std::string message = StringPrintf(
2083 "enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2084 connection->getInputChannelName().c_str(),
2085 dispatchModeToString(dispatchMode).c_str());
2086 ATRACE_NAME(message.c_str());
2087 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088 int32_t inputTargetFlags = inputTarget->flags;
2089 if (!(inputTargetFlags & dispatchMode)) {
2090 return;
2091 }
2092 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2093
2094 // This is a new event.
2095 // Enqueue a new dispatch entry onto the outbound queue for this connection.
2096 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2097 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Robert Carre07e1032018-11-26 12:55:53 -08002098 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2099 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100
2101 // Apply target flags and update the connection's input state.
2102 switch (eventEntry->type) {
2103 case EventEntry::TYPE_KEY: {
2104 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2105 dispatchEntry->resolvedAction = keyEntry->action;
2106 dispatchEntry->resolvedFlags = keyEntry->flags;
2107
2108 if (!connection->inputState.trackKey(keyEntry,
2109 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2110#if DEBUG_DISPATCH_CYCLE
2111 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002112 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002113#endif
2114 delete dispatchEntry;
2115 return; // skip the inconsistent event
2116 }
2117 break;
2118 }
2119
2120 case EventEntry::TYPE_MOTION: {
2121 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2122 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2123 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2124 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2125 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2126 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2127 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2128 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2129 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2130 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2131 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2132 } else {
2133 dispatchEntry->resolvedAction = motionEntry->action;
2134 }
2135 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2136 && !connection->inputState.isHovering(
2137 motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
2138#if DEBUG_DISPATCH_CYCLE
2139 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002140 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002141#endif
2142 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2143 }
2144
2145 dispatchEntry->resolvedFlags = motionEntry->flags;
2146 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2147 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2148 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002149 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2150 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2151 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002152
2153 if (!connection->inputState.trackMotion(motionEntry,
2154 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2155#if DEBUG_DISPATCH_CYCLE
2156 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002157 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158#endif
2159 delete dispatchEntry;
2160 return; // skip the inconsistent event
2161 }
chaviw8c9cf542019-03-25 13:02:48 -07002162
chaviwfd6d3512019-03-25 13:23:49 -07002163 dispatchPointerDownOutsideFocus(motionEntry->source,
chaviw8c9cf542019-03-25 13:02:48 -07002164 dispatchEntry->resolvedAction, inputTarget->inputChannel->getToken());
2165
Michael Wrightd02c5b62014-02-10 15:10:22 -08002166 break;
2167 }
2168 }
2169
2170 // Remember that we are waiting for this dispatch to complete.
2171 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002172 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173 }
2174
2175 // Enqueue the dispatch entry.
2176 connection->outboundQueue.enqueueAtTail(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002177 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002178
2179}
2180
chaviwfd6d3512019-03-25 13:23:49 -07002181void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
chaviw8c9cf542019-03-25 13:02:48 -07002182 const sp<IBinder>& newToken) {
2183 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002184 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2185 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002186 return;
2187 }
2188
2189 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2190 if (inputWindowHandle == nullptr) {
2191 return;
2192 }
2193
chaviw8c9cf542019-03-25 13:02:48 -07002194 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002195 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002196
2197 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2198
2199 if (!hasFocusChanged) {
2200 return;
2201 }
2202
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07002203 CommandEntry* commandEntry =
2204 postCommandLocked(&InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002205 commandEntry->newToken = newToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002206}
2207
2208void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2209 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002210 if (ATRACE_ENABLED()) {
2211 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
2212 connection->getInputChannelName().c_str());
2213 ATRACE_NAME(message.c_str());
2214 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002215#if DEBUG_DISPATCH_CYCLE
2216 ALOGD("channel '%s' ~ startDispatchCycle",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002217 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218#endif
2219
2220 while (connection->status == Connection::STATUS_NORMAL
2221 && !connection->outboundQueue.isEmpty()) {
2222 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
2223 dispatchEntry->deliveryTime = currentTime;
2224
2225 // Publish the event.
2226 status_t status;
2227 EventEntry* eventEntry = dispatchEntry->eventEntry;
2228 switch (eventEntry->type) {
2229 case EventEntry::TYPE_KEY: {
2230 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2231
2232 // Publish the key event.
2233 status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002234 keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002235 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2236 keyEntry->keyCode, keyEntry->scanCode,
2237 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2238 keyEntry->eventTime);
2239 break;
2240 }
2241
2242 case EventEntry::TYPE_MOTION: {
2243 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2244
2245 PointerCoords scaledCoords[MAX_POINTERS];
2246 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2247
2248 // Set the X and Y offset depending on the input source.
Siarhei Vishniakou635cb712017-11-01 16:32:14 -07002249 float xOffset, yOffset;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
2251 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Robert Carre07e1032018-11-26 12:55:53 -08002252 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2253 float wxs = dispatchEntry->windowXScale;
2254 float wys = dispatchEntry->windowYScale;
2255 xOffset = dispatchEntry->xOffset * wxs;
2256 yOffset = dispatchEntry->yOffset * wys;
2257 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002258 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259 scaledCoords[i] = motionEntry->pointerCoords[i];
Robert Carre07e1032018-11-26 12:55:53 -08002260 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002261 }
2262 usingCoords = scaledCoords;
2263 }
2264 } else {
2265 xOffset = 0.0f;
2266 yOffset = 0.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267
2268 // We don't want the dispatch target to know.
2269 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01002270 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 scaledCoords[i].clear();
2272 }
2273 usingCoords = scaledCoords;
2274 }
2275 }
2276
2277 // Publish the motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002278 status =
2279 connection->inputPublisher
2280 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2281 motionEntry->source, motionEntry->displayId,
2282 dispatchEntry->resolvedAction,
2283 motionEntry->actionButton,
2284 dispatchEntry->resolvedFlags,
2285 motionEntry->edgeFlags, motionEntry->metaState,
2286 motionEntry->buttonState,
2287 motionEntry->classification, xOffset, yOffset,
2288 motionEntry->xPrecision, motionEntry->yPrecision,
2289 motionEntry->xCursorPosition,
2290 motionEntry->yCursorPosition, motionEntry->downTime,
2291 motionEntry->eventTime, motionEntry->pointerCount,
2292 motionEntry->pointerProperties, usingCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293 break;
2294 }
2295
2296 default:
2297 ALOG_ASSERT(false);
2298 return;
2299 }
2300
2301 // Check the result.
2302 if (status) {
2303 if (status == WOULD_BLOCK) {
2304 if (connection->waitQueue.isEmpty()) {
2305 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
2306 "This is unexpected because the wait queue is empty, so the pipe "
2307 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002308 "event to it, status=%d", connection->getInputChannelName().c_str(),
2309 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002310 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2311 } else {
2312 // Pipe is full and we are waiting for the app to finish process some events
2313 // before sending more events to it.
2314#if DEBUG_DISPATCH_CYCLE
2315 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
2316 "waiting for the application to catch up",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002317 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002318#endif
2319 connection->inputPublisherBlocked = true;
2320 }
2321 } else {
2322 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002323 "status=%d", connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002324 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2325 }
2326 return;
2327 }
2328
2329 // Re-enqueue the event on the wait queue.
2330 connection->outboundQueue.dequeue(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002331 traceOutboundQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002332 connection->waitQueue.enqueueAtTail(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002333 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334 }
2335}
2336
2337void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
2338 const sp<Connection>& connection, uint32_t seq, bool handled) {
2339#if DEBUG_DISPATCH_CYCLE
2340 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002341 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342#endif
2343
2344 connection->inputPublisherBlocked = false;
2345
2346 if (connection->status == Connection::STATUS_BROKEN
2347 || connection->status == Connection::STATUS_ZOMBIE) {
2348 return;
2349 }
2350
2351 // Notify other system components and prepare to start the next dispatch cycle.
2352 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2353}
2354
2355void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2356 const sp<Connection>& connection, bool notify) {
2357#if DEBUG_DISPATCH_CYCLE
2358 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002359 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002360#endif
2361
2362 // Clear the dispatch queues.
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002363 drainDispatchQueue(&connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002364 traceOutboundQueueLength(connection);
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002365 drainDispatchQueue(&connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002366 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002367
2368 // The connection appears to be unrecoverably broken.
2369 // Ignore already broken or zombie connections.
2370 if (connection->status == Connection::STATUS_NORMAL) {
2371 connection->status = Connection::STATUS_BROKEN;
2372
2373 if (notify) {
2374 // Notify other system components.
2375 onDispatchCycleBrokenLocked(currentTime, connection);
2376 }
2377 }
2378}
2379
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002380void InputDispatcher::drainDispatchQueue(Queue<DispatchEntry>* queue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002381 while (!queue->isEmpty()) {
2382 DispatchEntry* dispatchEntry = queue->dequeueAtHead();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002383 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002384 }
2385}
2386
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002387void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002388 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002389 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002390 }
2391 delete dispatchEntry;
2392}
2393
2394int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2395 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2396
2397 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002398 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002399
2400 ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2401 if (connectionIndex < 0) {
2402 ALOGE("Received spurious receive callback for unknown input channel. "
2403 "fd=%d, events=0x%x", fd, events);
2404 return 0; // remove the callback
2405 }
2406
2407 bool notify;
2408 sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2409 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2410 if (!(events & ALOOPER_EVENT_INPUT)) {
2411 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002412 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413 return 1;
2414 }
2415
2416 nsecs_t currentTime = now();
2417 bool gotOne = false;
2418 status_t status;
2419 for (;;) {
2420 uint32_t seq;
2421 bool handled;
2422 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2423 if (status) {
2424 break;
2425 }
2426 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2427 gotOne = true;
2428 }
2429 if (gotOne) {
2430 d->runCommandsLockedInterruptible();
2431 if (status == WOULD_BLOCK) {
2432 return 1;
2433 }
2434 }
2435
2436 notify = status != DEAD_OBJECT || !connection->monitor;
2437 if (notify) {
2438 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002439 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440 }
2441 } else {
2442 // Monitor channels are never explicitly unregistered.
2443 // We do it automatically when the remote endpoint is closed so don't warn
2444 // about them.
2445 notify = !connection->monitor;
2446 if (notify) {
2447 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002448 "events=0x%x", connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002449 }
2450 }
2451
2452 // Unregister the channel.
2453 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2454 return 0; // remove the callback
2455 } // release lock
2456}
2457
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002458void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked (
Michael Wrightd02c5b62014-02-10 15:10:22 -08002459 const CancelationOptions& options) {
2460 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2461 synthesizeCancelationEventsForConnectionLocked(
2462 mConnectionsByFd.valueAt(i), options);
2463 }
2464}
2465
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002466void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002467 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002468 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2469 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2470}
2471
2472void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2473 const CancelationOptions& options,
2474 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2475 for (const auto& it : monitorsByDisplay) {
2476 const std::vector<Monitor>& monitors = it.second;
2477 for (const Monitor& monitor : monitors) {
2478 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002479 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002480 }
2481}
2482
Michael Wrightd02c5b62014-02-10 15:10:22 -08002483void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2484 const sp<InputChannel>& channel, const CancelationOptions& options) {
2485 ssize_t index = getConnectionIndexLocked(channel);
2486 if (index >= 0) {
2487 synthesizeCancelationEventsForConnectionLocked(
2488 mConnectionsByFd.valueAt(index), options);
2489 }
2490}
2491
2492void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2493 const sp<Connection>& connection, const CancelationOptions& options) {
2494 if (connection->status == Connection::STATUS_BROKEN) {
2495 return;
2496 }
2497
2498 nsecs_t currentTime = now();
2499
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002500 std::vector<EventEntry*> cancelationEvents;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501 connection->inputState.synthesizeCancelationEvents(currentTime,
2502 cancelationEvents, options);
2503
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002504 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002505#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002506 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Michael Wrightd02c5b62014-02-10 15:10:22 -08002507 "with reality: %s, mode=%d.",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08002508 connection->getInputChannelName().c_str(), cancelationEvents.size(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002509 options.reason, options.mode);
2510#endif
2511 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002512 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513 switch (cancelationEventEntry->type) {
2514 case EventEntry::TYPE_KEY:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002515 logOutboundKeyDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002516 static_cast<KeyEntry*>(cancelationEventEntry));
2517 break;
2518 case EventEntry::TYPE_MOTION:
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002519 logOutboundMotionDetails("cancel - ",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002520 static_cast<MotionEntry*>(cancelationEventEntry));
2521 break;
2522 }
2523
2524 InputTarget target;
chaviwfbe5d9c2018-12-26 12:23:37 -08002525 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
2526 connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002527 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2529 target.xOffset = -windowInfo->frameLeft;
2530 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002531 target.globalScaleFactor = windowInfo->globalScaleFactor;
2532 target.windowXScale = windowInfo->windowXScale;
2533 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002534 } else {
2535 target.xOffset = 0;
2536 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002537 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002538 }
2539 target.inputChannel = connection->inputChannel;
2540 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2541
chaviw8c9cf542019-03-25 13:02:48 -07002542 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Michael Wrightd02c5b62014-02-10 15:10:22 -08002543 &target, InputTarget::FLAG_DISPATCH_AS_IS);
2544
2545 cancelationEventEntry->release();
2546 }
2547
2548 startDispatchCycleLocked(currentTime, connection);
2549 }
2550}
2551
2552InputDispatcher::MotionEntry*
2553InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2554 ALOG_ASSERT(pointerIds.value != 0);
2555
2556 uint32_t splitPointerIndexMap[MAX_POINTERS];
2557 PointerProperties splitPointerProperties[MAX_POINTERS];
2558 PointerCoords splitPointerCoords[MAX_POINTERS];
2559
2560 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2561 uint32_t splitPointerCount = 0;
2562
2563 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2564 originalPointerIndex++) {
2565 const PointerProperties& pointerProperties =
2566 originalMotionEntry->pointerProperties[originalPointerIndex];
2567 uint32_t pointerId = uint32_t(pointerProperties.id);
2568 if (pointerIds.hasBit(pointerId)) {
2569 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2570 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2571 splitPointerCoords[splitPointerCount].copyFrom(
2572 originalMotionEntry->pointerCoords[originalPointerIndex]);
2573 splitPointerCount += 1;
2574 }
2575 }
2576
2577 if (splitPointerCount != pointerIds.count()) {
2578 // This is bad. We are missing some of the pointers that we expected to deliver.
2579 // Most likely this indicates that we received an ACTION_MOVE events that has
2580 // different pointer ids than we expected based on the previous ACTION_DOWN
2581 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2582 // in this way.
2583 ALOGW("Dropping split motion event because the pointer count is %d but "
2584 "we expected there to be %d pointers. This probably means we received "
2585 "a broken sequence of pointer ids from the input device.",
2586 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002587 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002588 }
2589
2590 int32_t action = originalMotionEntry->action;
2591 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2592 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2593 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2594 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2595 const PointerProperties& pointerProperties =
2596 originalMotionEntry->pointerProperties[originalPointerIndex];
2597 uint32_t pointerId = uint32_t(pointerProperties.id);
2598 if (pointerIds.hasBit(pointerId)) {
2599 if (pointerIds.count() == 1) {
2600 // The first/last pointer went down/up.
2601 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2602 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2603 } else {
2604 // A secondary pointer went down/up.
2605 uint32_t splitPointerIndex = 0;
2606 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2607 splitPointerIndex += 1;
2608 }
2609 action = maskedAction | (splitPointerIndex
2610 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2611 }
2612 } else {
2613 // An unrelated pointer changed.
2614 action = AMOTION_EVENT_ACTION_MOVE;
2615 }
2616 }
2617
Garfield Tan00f511d2019-06-12 16:55:40 -07002618 MotionEntry* splitMotionEntry =
2619 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2620 originalMotionEntry->deviceId, originalMotionEntry->source,
2621 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2622 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2623 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2624 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2625 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2626 originalMotionEntry->xCursorPosition,
2627 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2628 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002629
2630 if (originalMotionEntry->injectionState) {
2631 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2632 splitMotionEntry->injectionState->refCount += 1;
2633 }
2634
2635 return splitMotionEntry;
2636}
2637
2638void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2639#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002640 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002641#endif
2642
2643 bool needWake;
2644 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002645 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002646
Prabir Pradhan42611e02018-11-27 14:04:02 -08002647 ConfigurationChangedEntry* newEntry =
2648 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002649 needWake = enqueueInboundEventLocked(newEntry);
2650 } // release lock
2651
2652 if (needWake) {
2653 mLooper->wake();
2654 }
2655}
2656
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002657/**
2658 * If one of the meta shortcuts is detected, process them here:
2659 * Meta + Backspace -> generate BACK
2660 * Meta + Enter -> generate HOME
2661 * This will potentially overwrite keyCode and metaState.
2662 */
2663void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
2664 int32_t& keyCode, int32_t& metaState) {
2665 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2666 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2667 if (keyCode == AKEYCODE_DEL) {
2668 newKeyCode = AKEYCODE_BACK;
2669 } else if (keyCode == AKEYCODE_ENTER) {
2670 newKeyCode = AKEYCODE_HOME;
2671 }
2672 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002673 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002674 struct KeyReplacement replacement = {keyCode, deviceId};
2675 mReplacedKeys.add(replacement, newKeyCode);
2676 keyCode = newKeyCode;
2677 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2678 }
2679 } else if (action == AKEY_EVENT_ACTION_UP) {
2680 // In order to maintain a consistent stream of up and down events, check to see if the key
2681 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2682 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002683 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002684 struct KeyReplacement replacement = {keyCode, deviceId};
2685 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2686 if (index >= 0) {
2687 keyCode = mReplacedKeys.valueAt(index);
2688 mReplacedKeys.removeItemsAt(index);
2689 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2690 }
2691 }
2692}
2693
Michael Wrightd02c5b62014-02-10 15:10:22 -08002694void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2695#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002696 ALOGD("notifyKey - eventTime=%" PRId64
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002697 ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
Arthur Hung82a4cad2018-11-15 12:10:30 +08002698 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002699 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002700 args->action, args->flags, args->keyCode, args->scanCode,
Arthur Hung82a4cad2018-11-15 12:10:30 +08002701 args->metaState, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002702#endif
2703 if (!validateKeyEvent(args->action)) {
2704 return;
2705 }
2706
2707 uint32_t policyFlags = args->policyFlags;
2708 int32_t flags = args->flags;
2709 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002710 // InputDispatcher tracks and generates key repeats on behalf of
2711 // whatever notifies it, so repeatCount should always be set to 0
2712 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002713 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2714 policyFlags |= POLICY_FLAG_VIRTUAL;
2715 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2716 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717 if (policyFlags & POLICY_FLAG_FUNCTION) {
2718 metaState |= AMETA_FUNCTION_ON;
2719 }
2720
2721 policyFlags |= POLICY_FLAG_TRUSTED;
2722
Michael Wright78f24442014-08-06 15:55:28 -07002723 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002724 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002725
Michael Wrightd02c5b62014-02-10 15:10:22 -08002726 KeyEvent event;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002727 event.initialize(args->deviceId, args->source, args->displayId, args->action,
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002728 flags, keyCode, args->scanCode, metaState, repeatCount,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729 args->downTime, args->eventTime);
2730
Michael Wright2b3c3302018-03-02 17:19:13 +00002731 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002733 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2734 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2735 std::to_string(t.duration().count()).c_str());
2736 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737
Michael Wrightd02c5b62014-02-10 15:10:22 -08002738 bool needWake;
2739 { // acquire lock
2740 mLock.lock();
2741
2742 if (shouldSendKeyToInputFilterLocked(args)) {
2743 mLock.unlock();
2744
2745 policyFlags |= POLICY_FLAG_FILTERED;
2746 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2747 return; // event was consumed by the filter
2748 }
2749
2750 mLock.lock();
2751 }
2752
Prabir Pradhan42611e02018-11-27 14:04:02 -08002753 KeyEntry* newEntry = new KeyEntry(args->sequenceNum, args->eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002754 args->deviceId, args->source, args->displayId, policyFlags,
Michael Wright78f24442014-08-06 15:55:28 -07002755 args->action, flags, keyCode, args->scanCode,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002756 metaState, repeatCount, args->downTime);
2757
2758 needWake = enqueueInboundEventLocked(newEntry);
2759 mLock.unlock();
2760 } // release lock
2761
2762 if (needWake) {
2763 mLooper->wake();
2764 }
2765}
2766
2767bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2768 return mInputFilterEnabled;
2769}
2770
2771void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2772#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002773 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002774 ", policyFlags=0x%x, "
2775 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2776 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002777 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002778 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2779 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2780 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2781 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002782 for (uint32_t i = 0; i < args->pointerCount; i++) {
2783 ALOGD(" Pointer %d: id=%d, toolType=%d, "
2784 "x=%f, y=%f, pressure=%f, size=%f, "
2785 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2786 "orientation=%f",
2787 i, args->pointerProperties[i].id,
2788 args->pointerProperties[i].toolType,
2789 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2790 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2791 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2792 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2793 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2794 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2795 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2796 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2797 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2798 }
2799#endif
Michael Wright7b159c92015-05-14 14:48:03 +01002800 if (!validateMotionEvent(args->action, args->actionButton,
2801 args->pointerCount, args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002802 return;
2803 }
2804
2805 uint32_t policyFlags = args->policyFlags;
2806 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002807
2808 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002809 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002810 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2811 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2812 std::to_string(t.duration().count()).c_str());
2813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002814
2815 bool needWake;
2816 { // acquire lock
2817 mLock.lock();
2818
2819 if (shouldSendMotionToInputFilterLocked(args)) {
2820 mLock.unlock();
2821
2822 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002823 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2824 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2825 args->buttonState, args->classification, 0, 0, args->xPrecision,
2826 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2827 args->downTime, args->eventTime, args->pointerCount,
2828 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002829
2830 policyFlags |= POLICY_FLAG_FILTERED;
2831 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2832 return; // event was consumed by the filter
2833 }
2834
2835 mLock.lock();
2836 }
2837
2838 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002839 MotionEntry* newEntry =
2840 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2841 args->displayId, policyFlags, args->action, args->actionButton,
2842 args->flags, args->metaState, args->buttonState,
2843 args->classification, args->edgeFlags, args->xPrecision,
2844 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2845 args->downTime, args->pointerCount, args->pointerProperties,
2846 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847
2848 needWake = enqueueInboundEventLocked(newEntry);
2849 mLock.unlock();
2850 } // release lock
2851
2852 if (needWake) {
2853 mLooper->wake();
2854 }
2855}
2856
2857bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002858 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859}
2860
2861void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2862#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002863 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2864 "switchMask=0x%08x",
2865 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002866#endif
2867
2868 uint32_t policyFlags = args->policyFlags;
2869 policyFlags |= POLICY_FLAG_TRUSTED;
2870 mPolicy->notifySwitch(args->eventTime,
2871 args->switchValues, args->switchMask, policyFlags);
2872}
2873
2874void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2875#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002876 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d",
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877 args->eventTime, args->deviceId);
2878#endif
2879
2880 bool needWake;
2881 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002882 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002883
Prabir Pradhan42611e02018-11-27 14:04:02 -08002884 DeviceResetEntry* newEntry =
2885 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002886 needWake = enqueueInboundEventLocked(newEntry);
2887 } // release lock
2888
2889 if (needWake) {
2890 mLooper->wake();
2891 }
2892}
2893
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002894int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002895 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2896 uint32_t policyFlags) {
2897#if DEBUG_INBOUND_EVENT_DETAILS
2898 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002899 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2900 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002901#endif
2902
2903 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2904
2905 policyFlags |= POLICY_FLAG_INJECTED;
2906 if (hasInjectionPermission(injectorPid, injectorUid)) {
2907 policyFlags |= POLICY_FLAG_TRUSTED;
2908 }
2909
2910 EventEntry* firstInjectedEntry;
2911 EventEntry* lastInjectedEntry;
2912 switch (event->getType()) {
2913 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002914 KeyEvent keyEvent;
2915 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2916 int32_t action = keyEvent.getAction();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002917 if (! validateKeyEvent(action)) {
2918 return INPUT_EVENT_INJECTION_FAILED;
2919 }
2920
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002921 int32_t flags = keyEvent.getFlags();
2922 int32_t keyCode = keyEvent.getKeyCode();
2923 int32_t metaState = keyEvent.getMetaState();
2924 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2925 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002926 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002927 action, flags, keyCode, keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002928 keyEvent.getDownTime(), keyEvent.getEventTime());
2929
Michael Wrightd02c5b62014-02-10 15:10:22 -08002930 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2931 policyFlags |= POLICY_FLAG_VIRTUAL;
2932 }
2933
2934 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wright2b3c3302018-03-02 17:19:13 +00002935 android::base::Timer t;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002936 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002937 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2938 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2939 std::to_string(t.duration().count()).c_str());
2940 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941 }
2942
Michael Wrightd02c5b62014-02-10 15:10:22 -08002943 mLock.lock();
Prabir Pradhan42611e02018-11-27 14:04:02 -08002944 firstInjectedEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01002945 keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002946 policyFlags, action, flags,
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002947 keyEvent.getKeyCode(), keyEvent.getScanCode(), keyEvent.getMetaState(),
2948 keyEvent.getRepeatCount(), keyEvent.getDownTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002949 lastInjectedEntry = firstInjectedEntry;
2950 break;
2951 }
2952
2953 case AINPUT_EVENT_TYPE_MOTION: {
2954 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002955 int32_t action = motionEvent->getAction();
2956 size_t pointerCount = motionEvent->getPointerCount();
2957 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
Michael Wright7b159c92015-05-14 14:48:03 +01002958 int32_t actionButton = motionEvent->getActionButton();
Charles Chen3611f1f2019-01-29 17:26:18 +08002959 int32_t displayId = motionEvent->getDisplayId();
Michael Wright7b159c92015-05-14 14:48:03 +01002960 if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002961 return INPUT_EVENT_INJECTION_FAILED;
2962 }
2963
2964 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2965 nsecs_t eventTime = motionEvent->getEventTime();
Michael Wright2b3c3302018-03-02 17:19:13 +00002966 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002967 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002968 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2969 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
2970 std::to_string(t.duration().count()).c_str());
2971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002972 }
2973
2974 mLock.lock();
2975 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2976 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Garfield Tan00f511d2019-06-12 16:55:40 -07002977 firstInjectedEntry =
2978 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2979 motionEvent->getDeviceId(), motionEvent->getSource(),
2980 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2981 motionEvent->getFlags(), motionEvent->getMetaState(),
2982 motionEvent->getButtonState(), motionEvent->getClassification(),
2983 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2984 motionEvent->getYPrecision(), motionEvent->getRawXCursorPosition(),
2985 motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
2986 uint32_t(pointerCount), pointerProperties, samplePointerCoords,
2987 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002988 lastInjectedEntry = firstInjectedEntry;
2989 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2990 sampleEventTimes += 1;
2991 samplePointerCoords += pointerCount;
Garfield Tan00f511d2019-06-12 16:55:40 -07002992 MotionEntry* nextInjectedEntry =
2993 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
2994 motionEvent->getDeviceId(), motionEvent->getSource(),
2995 motionEvent->getDisplayId(), policyFlags, action, actionButton,
2996 motionEvent->getFlags(), motionEvent->getMetaState(),
2997 motionEvent->getButtonState(), motionEvent->getClassification(),
2998 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
2999 motionEvent->getYPrecision(),
3000 motionEvent->getRawXCursorPosition(),
3001 motionEvent->getRawYCursorPosition(),
3002 motionEvent->getDownTime(), uint32_t(pointerCount),
3003 pointerProperties, samplePointerCoords,
3004 motionEvent->getXOffset(), motionEvent->getYOffset());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005 lastInjectedEntry->next = nextInjectedEntry;
3006 lastInjectedEntry = nextInjectedEntry;
3007 }
3008 break;
3009 }
3010
3011 default:
3012 ALOGW("Cannot inject event of type %d", event->getType());
3013 return INPUT_EVENT_INJECTION_FAILED;
3014 }
3015
3016 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3017 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3018 injectionState->injectionIsAsync = true;
3019 }
3020
3021 injectionState->refCount += 1;
3022 lastInjectedEntry->injectionState = injectionState;
3023
3024 bool needWake = false;
Yi Kong9b14ac62018-07-17 13:48:38 -07003025 for (EventEntry* entry = firstInjectedEntry; entry != nullptr; ) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003026 EventEntry* nextEntry = entry->next;
3027 needWake |= enqueueInboundEventLocked(entry);
3028 entry = nextEntry;
3029 }
3030
3031 mLock.unlock();
3032
3033 if (needWake) {
3034 mLooper->wake();
3035 }
3036
3037 int32_t injectionResult;
3038 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003039 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003040
3041 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3042 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3043 } else {
3044 for (;;) {
3045 injectionResult = injectionState->injectionResult;
3046 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3047 break;
3048 }
3049
3050 nsecs_t remainingTimeout = endTime - now();
3051 if (remainingTimeout <= 0) {
3052#if DEBUG_INJECTION
3053 ALOGD("injectInputEvent - Timed out waiting for injection result "
3054 "to become available.");
3055#endif
3056 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3057 break;
3058 }
3059
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003060 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003061 }
3062
3063 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3064 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
3065 while (injectionState->pendingForegroundDispatches != 0) {
3066#if DEBUG_INJECTION
3067 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
3068 injectionState->pendingForegroundDispatches);
3069#endif
3070 nsecs_t remainingTimeout = endTime - now();
3071 if (remainingTimeout <= 0) {
3072#if DEBUG_INJECTION
3073 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3074 "dispatches to finish.");
3075#endif
3076 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3077 break;
3078 }
3079
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003080 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003081 }
3082 }
3083 }
3084
3085 injectionState->release();
3086 } // release lock
3087
3088#if DEBUG_INJECTION
3089 ALOGD("injectInputEvent - Finished with result %d. "
3090 "injectorPid=%d, injectorUid=%d",
3091 injectionResult, injectorPid, injectorUid);
3092#endif
3093
3094 return injectionResult;
3095}
3096
3097bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3098 return injectorUid == 0
3099 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3100}
3101
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003102void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003103 InjectionState* injectionState = entry->injectionState;
3104 if (injectionState) {
3105#if DEBUG_INJECTION
3106 ALOGD("Setting input event injection result to %d. "
3107 "injectorPid=%d, injectorUid=%d",
3108 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
3109#endif
3110
3111 if (injectionState->injectionIsAsync
3112 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
3113 // Log the outcome since the injector did not wait for the injection result.
3114 switch (injectionResult) {
3115 case INPUT_EVENT_INJECTION_SUCCEEDED:
3116 ALOGV("Asynchronous input event injection succeeded.");
3117 break;
3118 case INPUT_EVENT_INJECTION_FAILED:
3119 ALOGW("Asynchronous input event injection failed.");
3120 break;
3121 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3122 ALOGW("Asynchronous input event injection permission denied.");
3123 break;
3124 case INPUT_EVENT_INJECTION_TIMED_OUT:
3125 ALOGW("Asynchronous input event injection timed out.");
3126 break;
3127 }
3128 }
3129
3130 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003131 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003132 }
3133}
3134
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003135void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136 InjectionState* injectionState = entry->injectionState;
3137 if (injectionState) {
3138 injectionState->pendingForegroundDispatches += 1;
3139 }
3140}
3141
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003142void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143 InjectionState* injectionState = entry->injectionState;
3144 if (injectionState) {
3145 injectionState->pendingForegroundDispatches -= 1;
3146
3147 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003148 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003149 }
3150 }
3151}
3152
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003153std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3154 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003155 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003156}
3157
Michael Wrightd02c5b62014-02-10 15:10:22 -08003158sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003159 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003160 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003161 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3162 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003163 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003164 return windowHandle;
3165 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166 }
3167 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003168 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169}
3170
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003171bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003172 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003173 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3174 for (const sp<InputWindowHandle>& handle : windowHandles) {
3175 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003176 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003177 ALOGE("Found window %s in display %" PRId32
3178 ", but it should belong to display %" PRId32,
3179 windowHandle->getName().c_str(), it.first,
3180 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003181 }
3182 return true;
3183 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184 }
3185 }
3186 return false;
3187}
3188
Robert Carr5c8a0262018-10-03 16:30:44 -07003189sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3190 size_t count = mInputChannelsByToken.count(token);
3191 if (count == 0) {
3192 return nullptr;
3193 }
3194 return mInputChannelsByToken.at(token);
3195}
3196
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003197void InputDispatcher::updateWindowHandlesForDisplayLocked(
3198 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3199 if (inputWindowHandles.empty()) {
3200 // Remove all handles on a display if there are no windows left.
3201 mWindowHandlesByDisplay.erase(displayId);
3202 return;
3203 }
3204
3205 // Since we compare the pointer of input window handles across window updates, we need
3206 // to make sure the handle object for the same window stays unchanged across updates.
3207 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
3208 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3209 for (const sp<InputWindowHandle>& handle : oldHandles) {
3210 oldHandlesByTokens[handle->getToken()] = handle;
3211 }
3212
3213 std::vector<sp<InputWindowHandle>> newHandles;
3214 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3215 if (!handle->updateInfo()) {
3216 // handle no longer valid
3217 continue;
3218 }
3219
3220 const InputWindowInfo* info = handle->getInfo();
3221 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3222 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3223 const bool noInputChannel =
3224 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3225 const bool canReceiveInput =
3226 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3227 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3228 if (canReceiveInput && !noInputChannel) {
3229 ALOGE("Window handle %s has no registered input channel",
3230 handle->getName().c_str());
3231 }
3232 continue;
3233 }
3234
3235 if (info->displayId != displayId) {
3236 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3237 handle->getName().c_str(), displayId, info->displayId);
3238 continue;
3239 }
3240
3241 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3242 const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
3243 oldHandle->updateFrom(handle);
3244 newHandles.push_back(oldHandle);
3245 } else {
3246 newHandles.push_back(handle);
3247 }
3248 }
3249
3250 // Insert or replace
3251 mWindowHandlesByDisplay[displayId] = newHandles;
3252}
3253
Arthur Hungb92218b2018-08-14 12:00:21 +08003254/**
3255 * Called from InputManagerService, update window handle list by displayId that can receive input.
3256 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3257 * If set an empty list, remove all handles from the specific display.
3258 * For focused handle, check if need to change and send a cancel event to previous one.
3259 * For removed handle, check if need to send a cancel event if already in touch.
3260 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003261void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
chaviw291d88a2019-02-14 10:33:58 -08003262 int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003263#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003264 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003265#endif
3266 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003267 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003268
Arthur Hungb92218b2018-08-14 12:00:21 +08003269 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003270 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3271 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003272
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003273 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3274
Tiger Huang721e26f2018-07-24 22:26:19 +08003275 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003276 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003277 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3278 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3279 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3280 windowHandle->getInfo()->visible) {
3281 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003282 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003283 if (windowHandle == mLastHoverWindowHandle) {
3284 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003285 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003286 }
3287
3288 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003289 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003290 }
3291
Tiger Huang721e26f2018-07-24 22:26:19 +08003292 sp<InputWindowHandle> oldFocusedWindowHandle =
3293 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3294
3295 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3296 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003297#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003298 ALOGD("Focus left window: %s in display %" PRId32,
3299 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003300#endif
Robert Carr5c8a0262018-10-03 16:30:44 -07003301 sp<InputChannel> focusedInputChannel = getInputChannelLocked(
3302 oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003303 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3305 "focus left window");
3306 synthesizeCancelationEventsForInputChannelLocked(
3307 focusedInputChannel, options);
3308 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003309 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003311 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003313 ALOGD("Focus entered window: %s in display %" PRId32,
3314 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003316 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317 }
Robert Carrf759f162018-11-13 12:57:11 -08003318
3319 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003320 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003321 }
3322
Michael Wrightd02c5b62014-02-10 15:10:22 -08003323 }
3324
Arthur Hungb92218b2018-08-14 12:00:21 +08003325 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3326 if (stateIndex >= 0) {
3327 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Ivan Lozano96f12992017-11-09 14:45:38 -08003328 for (size_t i = 0; i < state.windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003329 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003330 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003332 ALOGD("Touched window was removed: %s in display %" PRId32,
3333 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003334#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003335 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003336 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003337 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003338 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3339 "touched window was removed");
3340 synthesizeCancelationEventsForInputChannelLocked(
3341 touchedInputChannel, options);
3342 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003343 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003344 } else {
3345 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003346 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347 }
3348 }
3349
3350 // Release information for windows that are no longer present.
3351 // This ensures that unused input channels are released promptly.
3352 // Otherwise, they might stick around until the window handle is destroyed
3353 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003354 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003355 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003357 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003358#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003359 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003360 }
3361 }
3362 } // release lock
3363
3364 // Wake up poll loop since it may need to make new input dispatching choices.
3365 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003366
3367 if (setInputWindowsListener) {
3368 setInputWindowsListener->onSetInputWindowsFinished();
3369 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370}
3371
3372void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003373 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003374#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003375 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003376#endif
3377 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003378 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379
Tiger Huang721e26f2018-07-24 22:26:19 +08003380 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3381 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003382 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003383 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3384 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003385 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003387 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003388 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003389 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003391 oldFocusedApplicationHandle.clear();
3392 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003393 }
3394
3395#if DEBUG_FOCUS
3396 //logDispatchStateLocked();
3397#endif
3398 } // release lock
3399
3400 // Wake up poll loop since it may need to make new input dispatching choices.
3401 mLooper->wake();
3402}
3403
Tiger Huang721e26f2018-07-24 22:26:19 +08003404/**
3405 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3406 * the display not specified.
3407 *
3408 * We track any unreleased events for each window. If a window loses the ability to receive the
3409 * released event, we will send a cancel event to it. So when the focused display is changed, we
3410 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3411 * display. The display-specified events won't be affected.
3412 */
3413void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3414#if DEBUG_FOCUS
3415 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3416#endif
3417 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003418 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003419
3420 if (mFocusedDisplayId != displayId) {
3421 sp<InputWindowHandle> oldFocusedWindowHandle =
3422 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3423 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003424 sp<InputChannel> inputChannel =
3425 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003426 if (inputChannel != nullptr) {
3427 CancelationOptions options(
Michael Wright3dd60e22019-03-27 22:06:44 +00003428 CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Tiger Huang721e26f2018-07-24 22:26:19 +08003429 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003430 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003431 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3432 }
3433 }
3434 mFocusedDisplayId = displayId;
3435
3436 // Sanity check
3437 sp<InputWindowHandle> newFocusedWindowHandle =
3438 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003439 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003440
Tiger Huang721e26f2018-07-24 22:26:19 +08003441 if (newFocusedWindowHandle == nullptr) {
3442 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3443 if (!mFocusedWindowHandlesByDisplay.empty()) {
3444 ALOGE("But another display has a focused window:");
3445 for (auto& it : mFocusedWindowHandlesByDisplay) {
3446 const int32_t displayId = it.first;
3447 const sp<InputWindowHandle>& windowHandle = it.second;
3448 ALOGE("Display #%" PRId32 " has focused window: '%s'\n",
3449 displayId, windowHandle->getName().c_str());
3450 }
3451 }
3452 }
3453 }
3454
3455#if DEBUG_FOCUS
3456 logDispatchStateLocked();
3457#endif
3458 } // release lock
3459
3460 // Wake up poll loop since it may need to make new input dispatching choices.
3461 mLooper->wake();
3462}
3463
Michael Wrightd02c5b62014-02-10 15:10:22 -08003464void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3465#if DEBUG_FOCUS
3466 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3467#endif
3468
3469 bool changed;
3470 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003471 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003472
3473 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3474 if (mDispatchFrozen && !frozen) {
3475 resetANRTimeoutsLocked();
3476 }
3477
3478 if (mDispatchEnabled && !enabled) {
3479 resetAndDropEverythingLocked("dispatcher is being disabled");
3480 }
3481
3482 mDispatchEnabled = enabled;
3483 mDispatchFrozen = frozen;
3484 changed = true;
3485 } else {
3486 changed = false;
3487 }
3488
3489#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003490 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003491#endif
3492 } // release lock
3493
3494 if (changed) {
3495 // Wake up poll loop since it may need to make new input dispatching choices.
3496 mLooper->wake();
3497 }
3498}
3499
3500void InputDispatcher::setInputFilterEnabled(bool enabled) {
3501#if DEBUG_FOCUS
3502 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3503#endif
3504
3505 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003506 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003507
3508 if (mInputFilterEnabled == enabled) {
3509 return;
3510 }
3511
3512 mInputFilterEnabled = enabled;
3513 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3514 } // release lock
3515
3516 // Wake up poll loop since there might be work to do to drop everything.
3517 mLooper->wake();
3518}
3519
chaviwfbe5d9c2018-12-26 12:23:37 -08003520bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3521 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003522#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003523 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003525 return true;
3526 }
3527
Michael Wrightd02c5b62014-02-10 15:10:22 -08003528 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003529 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530
chaviwfbe5d9c2018-12-26 12:23:37 -08003531 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3532 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003533 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003534 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003535 return false;
3536 }
chaviw4f2dd402018-12-26 15:30:27 -08003537#if DEBUG_FOCUS
3538 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
3539 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
3540#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003541 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3542#if DEBUG_FOCUS
3543 ALOGD("Cannot transfer focus because windows are on different displays.");
3544#endif
3545 return false;
3546 }
3547
3548 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003549 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3550 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3551 for (size_t i = 0; i < state.windows.size(); i++) {
3552 const TouchedWindow& touchedWindow = state.windows[i];
3553 if (touchedWindow.windowHandle == fromWindowHandle) {
3554 int32_t oldTargetFlags = touchedWindow.targetFlags;
3555 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003557 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003558
Jeff Brownf086ddb2014-02-11 14:28:48 -08003559 int32_t newTargetFlags = oldTargetFlags
3560 & (InputTarget::FLAG_FOREGROUND
3561 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
3562 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003563
Jeff Brownf086ddb2014-02-11 14:28:48 -08003564 found = true;
3565 goto Found;
3566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567 }
3568 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08003569Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003570
3571 if (! found) {
3572#if DEBUG_FOCUS
3573 ALOGD("Focus transfer failed because from window did not have focus.");
3574#endif
3575 return false;
3576 }
3577
chaviwfbe5d9c2018-12-26 12:23:37 -08003578
3579 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3580 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3582 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3583 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3584 sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
3585 sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
3586
3587 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3588 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3589 "transferring touch focus from this window to another window");
3590 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3591 }
3592
3593#if DEBUG_FOCUS
3594 logDispatchStateLocked();
3595#endif
3596 } // release lock
3597
3598 // Wake up poll loop since it may need to make new input dispatching choices.
3599 mLooper->wake();
3600 return true;
3601}
3602
3603void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3604#if DEBUG_FOCUS
3605 ALOGD("Resetting and dropping all events (%s).", reason);
3606#endif
3607
3608 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3609 synthesizeCancelationEventsForAllConnectionsLocked(options);
3610
3611 resetKeyRepeatLocked();
3612 releasePendingEventLocked();
3613 drainInboundQueueLocked();
3614 resetANRTimeoutsLocked();
3615
Jeff Brownf086ddb2014-02-11 14:28:48 -08003616 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003618 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003619}
3620
3621void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003622 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003623 dumpDispatchStateLocked(dump);
3624
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003625 std::istringstream stream(dump);
3626 std::string line;
3627
3628 while (std::getline(stream, line, '\n')) {
3629 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630 }
3631}
3632
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003633void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003634 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3635 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3636 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003637 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003638
Tiger Huang721e26f2018-07-24 22:26:19 +08003639 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3640 dump += StringPrintf(INDENT "FocusedApplications:\n");
3641 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3642 const int32_t displayId = it.first;
3643 const sp<InputApplicationHandle>& applicationHandle = it.second;
3644 dump += StringPrintf(
3645 INDENT2 "displayId=%" PRId32 ", name='%s', dispatchingTimeout=%0.3fms\n",
3646 displayId,
3647 applicationHandle->getName().c_str(),
3648 applicationHandle->getDispatchingTimeout(
3649 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3650 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003652 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003654
3655 if (!mFocusedWindowHandlesByDisplay.empty()) {
3656 dump += StringPrintf(INDENT "FocusedWindows:\n");
3657 for (auto& it : mFocusedWindowHandlesByDisplay) {
3658 const int32_t displayId = it.first;
3659 const sp<InputWindowHandle>& windowHandle = it.second;
3660 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n",
3661 displayId, windowHandle->getName().c_str());
3662 }
3663 } else {
3664 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3665 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003666
Jeff Brownf086ddb2014-02-11 14:28:48 -08003667 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003668 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003669 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3670 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003671 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Jeff Brownf086ddb2014-02-11 14:28:48 -08003672 state.displayId, toString(state.down), toString(state.split),
3673 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003674 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003675 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003676 for (size_t i = 0; i < state.windows.size(); i++) {
3677 const TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003678 dump += StringPrintf(INDENT4 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3679 i, touchedWindow.windowHandle->getName().c_str(),
Jeff Brownf086ddb2014-02-11 14:28:48 -08003680 touchedWindow.pointerIds.value,
3681 touchedWindow.targetFlags);
3682 }
3683 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003684 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003685 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003686 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003687 dump += INDENT3 "Portal windows:\n";
3688 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003689 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003690 dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
3691 i, portalWindowHandle->getName().c_str());
3692 }
3693 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003694 }
3695 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003696 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003697 }
3698
Arthur Hungb92218b2018-08-14 12:00:21 +08003699 if (!mWindowHandlesByDisplay.empty()) {
3700 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003701 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003702 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003703 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003704 dump += INDENT2 "Windows:\n";
3705 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003706 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003707 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708
Arthur Hungb92218b2018-08-14 12:00:21 +08003709 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003710 "portalToDisplayId=%d, paused=%s, hasFocus=%s, hasWallpaper=%s, "
Arthur Hungb92218b2018-08-14 12:00:21 +08003711 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Riddle Hsu39d4aa52018-11-30 20:46:53 +08003712 "frame=[%d,%d][%d,%d], globalScale=%f, windowScale=(%f,%f), "
Arthur Hungb92218b2018-08-14 12:00:21 +08003713 "touchableRegion=",
3714 i, windowInfo->name.c_str(), windowInfo->displayId,
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003715 windowInfo->portalToDisplayId,
Arthur Hungb92218b2018-08-14 12:00:21 +08003716 toString(windowInfo->paused),
3717 toString(windowInfo->hasFocus),
3718 toString(windowInfo->hasWallpaper),
3719 toString(windowInfo->visible),
3720 toString(windowInfo->canReceiveKeys),
3721 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3722 windowInfo->layer,
3723 windowInfo->frameLeft, windowInfo->frameTop,
3724 windowInfo->frameRight, windowInfo->frameBottom,
Robert Carre07e1032018-11-26 12:55:53 -08003725 windowInfo->globalScaleFactor,
3726 windowInfo->windowXScale, windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003727 dumpRegion(dump, windowInfo->touchableRegion);
3728 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3729 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3730 windowInfo->ownerPid, windowInfo->ownerUid,
3731 windowInfo->dispatchingTimeout / 1000000.0);
3732 }
3733 } else {
3734 dump += INDENT2 "Windows: <none>\n";
3735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 }
3737 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003738 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003739 }
3740
Michael Wright3dd60e22019-03-27 22:06:44 +00003741 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
3742 for (auto& it : mGlobalMonitorsByDisplay) {
3743 const std::vector<Monitor>& monitors = it.second;
3744 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3745 dumpMonitors(dump, monitors);
3746 }
3747 for (auto& it : mGestureMonitorsByDisplay) {
3748 const std::vector<Monitor>& monitors = it.second;
3749 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3750 dumpMonitors(dump, monitors);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003752 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003753 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003754 }
3755
3756 nsecs_t currentTime = now();
3757
3758 // Dump recently dispatched or dropped events from oldest to newest.
3759 if (!mRecentQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003760 dump += StringPrintf(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761 for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003762 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003764 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765 (currentTime - entry->eventTime) * 0.000001f);
3766 }
3767 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003768 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769 }
3770
3771 // Dump event currently being dispatched.
3772 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003773 dump += INDENT "PendingEvent:\n";
3774 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003776 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777 (currentTime - mPendingEvent->eventTime) * 0.000001f);
3778 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003779 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 }
3781
3782 // Dump inbound events from oldest to newest.
3783 if (!mInboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003784 dump += StringPrintf(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003786 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787 entry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003788 dump += StringPrintf(", age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003789 (currentTime - entry->eventTime) * 0.000001f);
3790 }
3791 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003792 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 }
3794
Michael Wright78f24442014-08-06 15:55:28 -07003795 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003796 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003797 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3798 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3799 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003800 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
Michael Wright78f24442014-08-06 15:55:28 -07003801 i, replacement.keyCode, replacement.deviceId, newKeyCode);
3802 }
3803 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003804 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003805 }
3806
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807 if (!mConnectionsByFd.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003808 dump += INDENT "Connections:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
3810 const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003811 dump += StringPrintf(INDENT2 "%zu: channelName='%s', windowName='%s', "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08003813 i, connection->getInputChannelName().c_str(),
3814 connection->getWindowName().c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815 connection->getStatusLabel(), toString(connection->monitor),
3816 toString(connection->inputPublisherBlocked));
3817
3818 if (!connection->outboundQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003819 dump += StringPrintf(INDENT3 "OutboundQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820 connection->outboundQueue.count());
3821 for (DispatchEntry* entry = connection->outboundQueue.head; entry;
3822 entry = entry->next) {
3823 dump.append(INDENT4);
3824 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003825 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826 entry->targetFlags, entry->resolvedAction,
3827 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
3828 }
3829 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003830 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003831 }
3832
3833 if (!connection->waitQueue.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003834 dump += StringPrintf(INDENT3 "WaitQueue: length=%u\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003835 connection->waitQueue.count());
3836 for (DispatchEntry* entry = connection->waitQueue.head; entry;
3837 entry = entry->next) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003838 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003840 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08003841 "age=%0.1fms, wait=%0.1fms\n",
3842 entry->targetFlags, entry->resolvedAction,
3843 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3844 (currentTime - entry->deliveryTime) * 0.000001f);
3845 }
3846 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003847 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 }
3849 }
3850 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003851 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 }
3853
3854 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003855 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 (mAppSwitchDueTime - now()) / 1000000.0);
3857 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003858 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003859 }
3860
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003861 dump += INDENT "Configuration:\n";
3862 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863 mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003864 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 mConfig.keyRepeatTimeout * 0.000001f);
3866}
3867
Michael Wright3dd60e22019-03-27 22:06:44 +00003868void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3869 const size_t numMonitors = monitors.size();
3870 for (size_t i = 0; i < numMonitors; i++) {
3871 const Monitor& monitor = monitors[i];
3872 const sp<InputChannel>& channel = monitor.inputChannel;
3873 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3874 dump += "\n";
3875 }
3876}
3877
3878status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3879 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003881 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
3882 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883#endif
3884
3885 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003886 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887
3888 if (getConnectionIndexLocked(inputChannel) >= 0) {
3889 ALOGW("Attempted to register already registered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003890 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891 return BAD_VALUE;
3892 }
3893
Michael Wright3dd60e22019-03-27 22:06:44 +00003894 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003895
3896 int fd = inputChannel->getFd();
3897 mConnectionsByFd.add(fd, connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07003898 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003899
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3901 } // release lock
3902
3903 // Wake the looper because some connections have changed.
3904 mLooper->wake();
3905 return OK;
3906}
3907
Michael Wright3dd60e22019-03-27 22:06:44 +00003908status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
3909 int32_t displayId, bool isGestureMonitor) {
3910 { // acquire lock
3911 std::scoped_lock _l(mLock);
3912
3913 if (displayId < 0) {
3914 ALOGW("Attempted to register input monitor without a specified display.");
3915 return BAD_VALUE;
3916 }
3917
3918 if (inputChannel->getToken() == nullptr) {
3919 ALOGW("Attempted to register input monitor without an identifying token.");
3920 return BAD_VALUE;
3921 }
3922
3923 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3924
3925 const int fd = inputChannel->getFd();
3926 mConnectionsByFd.add(fd, connection);
3927 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3928
3929 auto& monitorsByDisplay = isGestureMonitor
3930 ? mGestureMonitorsByDisplay
3931 : mGlobalMonitorsByDisplay;
3932 monitorsByDisplay[displayId].emplace_back(inputChannel);
3933
3934 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3935
3936 }
3937 // Wake the looper because some connections have changed.
3938 mLooper->wake();
3939 return OK;
3940}
3941
Michael Wrightd02c5b62014-02-10 15:10:22 -08003942status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3943#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003944 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003945#endif
3946
3947 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003948 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003949
3950 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3951 if (status) {
3952 return status;
3953 }
3954 } // release lock
3955
3956 // Wake the poll loop because removing the connection may have changed the current
3957 // synchronization state.
3958 mLooper->wake();
3959 return OK;
3960}
3961
3962status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3963 bool notify) {
3964 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3965 if (connectionIndex < 0) {
3966 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003967 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968 return BAD_VALUE;
3969 }
3970
3971 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3972 mConnectionsByFd.removeItemsAt(connectionIndex);
3973
Robert Carr5c8a0262018-10-03 16:30:44 -07003974 mInputChannelsByToken.erase(inputChannel->getToken());
3975
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976 if (connection->monitor) {
3977 removeMonitorChannelLocked(inputChannel);
3978 }
3979
3980 mLooper->removeFd(inputChannel->getFd());
3981
3982 nsecs_t currentTime = now();
3983 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3984
3985 connection->status = Connection::STATUS_ZOMBIE;
3986 return OK;
3987}
3988
3989void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003990 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
3991 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
3992}
3993
3994void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
3995 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3996 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end(); ) {
3997 std::vector<Monitor>& monitors = it->second;
3998 const size_t numMonitors = monitors.size();
3999 for (size_t i = 0; i < numMonitors; i++) {
4000 if (monitors[i].inputChannel == inputChannel) {
4001 monitors.erase(monitors.begin() + i);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004002 break;
4003 }
4004 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004005 if (monitors.empty()) {
4006 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004007 } else {
4008 ++it;
4009 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004010 }
4011}
4012
Michael Wright3dd60e22019-03-27 22:06:44 +00004013status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4014 { // acquire lock
4015 std::scoped_lock _l(mLock);
4016 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4017
4018 if (!foundDisplayId) {
4019 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4020 return BAD_VALUE;
4021 }
4022 int32_t displayId = foundDisplayId.value();
4023
4024 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4025 if (stateIndex < 0) {
4026 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4027 return BAD_VALUE;
4028 }
4029
4030 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4031 std::optional<int32_t> foundDeviceId;
4032 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4033 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4034 foundDeviceId = state.deviceId;
4035 }
4036 }
4037 if (!foundDeviceId || !state.down) {
4038 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
4039 " Ignoring.");
4040 return BAD_VALUE;
4041 }
4042 int32_t deviceId = foundDeviceId.value();
4043
4044 // Send cancel events to all the input channels we're stealing from.
4045 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4046 "gesture monitor stole pointer stream");
4047 options.deviceId = deviceId;
4048 options.displayId = displayId;
4049 for (const TouchedWindow& window : state.windows) {
4050 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4051 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4052 }
4053 // Then clear the current touch state so we stop dispatching to them as well.
4054 state.filterNonMonitors();
4055 }
4056 return OK;
4057}
4058
4059
4060std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4061 const sp<IBinder>& token) {
4062 for (const auto& it : mGestureMonitorsByDisplay) {
4063 const std::vector<Monitor>& monitors = it.second;
4064 for (const Monitor& monitor : monitors) {
4065 if (monitor.inputChannel->getToken() == token) {
4066 return it.first;
4067 }
4068 }
4069 }
4070 return std::nullopt;
4071}
4072
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004074 if (inputChannel == nullptr) {
Arthur Hung3b413f22018-10-26 18:05:34 +08004075 return -1;
4076 }
4077
Robert Carr4e670e52018-08-15 13:26:12 -07004078 for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
4079 sp<Connection> connection = mConnectionsByFd.valueAt(i);
4080 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
4081 return i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 }
4083 }
Robert Carr4e670e52018-08-15 13:26:12 -07004084
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 return -1;
4086}
4087
4088void InputDispatcher::onDispatchCycleFinishedLocked(
4089 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004090 CommandEntry* commandEntry =
4091 postCommandLocked(&InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092 commandEntry->connection = connection;
4093 commandEntry->eventTime = currentTime;
4094 commandEntry->seq = seq;
4095 commandEntry->handled = handled;
4096}
4097
4098void InputDispatcher::onDispatchCycleBrokenLocked(
4099 nsecs_t currentTime, const sp<Connection>& connection) {
4100 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004101 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004102
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004103 CommandEntry* commandEntry =
4104 postCommandLocked(&InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004105 commandEntry->connection = connection;
4106}
4107
chaviw0c06c6e2019-01-09 13:27:07 -08004108void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
4109 const sp<InputWindowHandle>& newFocus) {
4110 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4111 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004112 CommandEntry* commandEntry =
4113 postCommandLocked(&InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004114 commandEntry->oldToken = oldToken;
4115 commandEntry->newToken = newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004116}
4117
Michael Wrightd02c5b62014-02-10 15:10:22 -08004118void InputDispatcher::onANRLocked(
4119 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
4120 const sp<InputWindowHandle>& windowHandle,
4121 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
4122 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4123 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4124 ALOGI("Application is not responding: %s. "
4125 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004126 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004127 dispatchLatency, waitDuration, reason);
4128
4129 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004130 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131 struct tm tm;
4132 localtime_r(&t, &tm);
4133 char timestr[64];
4134 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4135 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004136 mLastANRState += INDENT "ANR:\n";
4137 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
4138 mLastANRState += StringPrintf(INDENT2 "Window: %s\n",
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004139 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004140 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4141 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4142 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004143 dumpDispatchStateLocked(mLastANRState);
4144
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07004145 CommandEntry* commandEntry =
4146 postCommandLocked(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147 commandEntry->inputApplicationHandle = applicationHandle;
Robert Carr5c8a0262018-10-03 16:30:44 -07004148 commandEntry->inputChannel = windowHandle != nullptr ?
4149 getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004150 commandEntry->reason = reason;
4151}
4152
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004153void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible (
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154 CommandEntry* commandEntry) {
4155 mLock.unlock();
4156
4157 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4158
4159 mLock.lock();
4160}
4161
4162void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
4163 CommandEntry* commandEntry) {
4164 sp<Connection> connection = commandEntry->connection;
4165
4166 if (connection->status != Connection::STATUS_ZOMBIE) {
4167 mLock.unlock();
4168
Robert Carr803535b2018-08-02 16:38:15 -07004169 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170
4171 mLock.lock();
4172 }
4173}
4174
Robert Carrf759f162018-11-13 12:57:11 -08004175void InputDispatcher::doNotifyFocusChangedLockedInterruptible(
4176 CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004177 sp<IBinder> oldToken = commandEntry->oldToken;
4178 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004179 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004180 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004181 mLock.lock();
4182}
4183
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184void InputDispatcher::doNotifyANRLockedInterruptible(
4185 CommandEntry* commandEntry) {
4186 mLock.unlock();
4187
4188 nsecs_t newTimeout = mPolicy->notifyANR(
Robert Carr803535b2018-08-02 16:38:15 -07004189 commandEntry->inputApplicationHandle,
4190 commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004191 commandEntry->reason);
4192
4193 mLock.lock();
4194
4195 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
Robert Carr803535b2018-08-02 16:38:15 -07004196 commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004197}
4198
4199void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4200 CommandEntry* commandEntry) {
4201 KeyEntry* entry = commandEntry->keyEntry;
4202
4203 KeyEvent event;
4204 initializeKeyEvent(&event, entry);
4205
4206 mLock.unlock();
4207
Michael Wright2b3c3302018-03-02 17:19:13 +00004208 android::base::Timer t;
Robert Carr803535b2018-08-02 16:38:15 -07004209 sp<IBinder> token = commandEntry->inputChannel != nullptr ?
4210 commandEntry->inputChannel->getToken() : nullptr;
4211 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004212 &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004213 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4214 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
4215 std::to_string(t.duration().count()).c_str());
4216 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217
4218 mLock.lock();
4219
4220 if (delay < 0) {
4221 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4222 } else if (!delay) {
4223 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4224 } else {
4225 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4226 entry->interceptKeyWakeupTime = now() + delay;
4227 }
4228 entry->release();
4229}
4230
chaviwfd6d3512019-03-25 13:23:49 -07004231void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4232 mLock.unlock();
4233 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4234 mLock.lock();
4235}
4236
Michael Wrightd02c5b62014-02-10 15:10:22 -08004237void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
4238 CommandEntry* commandEntry) {
4239 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004240 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004241 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004242 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004243
4244 // Handle post-event policy actions.
4245 DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004246 if (!dispatchEntry) {
4247 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004249
4250 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4251 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4252 std::string msg =
4253 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4254 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4255 dispatchEntry->eventEntry->appendDescription(msg);
4256 ALOGI("%s", msg.c_str());
4257 }
4258
4259 bool restartEvent;
4260 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4261 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4262 restartEvent =
4263 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
4264 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4265 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4266 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4267 handled);
4268 } else {
4269 restartEvent = false;
4270 }
4271
4272 // Dequeue the event and start the next cycle.
4273 // Note that because the lock might have been released, it is possible that the
4274 // contents of the wait queue to have been drained, so we need to double-check
4275 // a few things.
4276 if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
4277 connection->waitQueue.dequeue(dispatchEntry);
4278 traceWaitQueueLength(connection);
4279 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
4280 connection->outboundQueue.enqueueAtHead(dispatchEntry);
4281 traceOutboundQueueLength(connection);
4282 } else {
4283 releaseDispatchEntry(dispatchEntry);
4284 }
4285 }
4286
4287 // Start the next dispatch cycle for this connection.
4288 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289}
4290
4291bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
4292 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004293 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004294 if (!handled) {
4295 // Report the key as unhandled, since the fallback was not handled.
4296 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4297 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004298 return false;
4299 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004300
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004301 // Get the fallback key state.
4302 // Clear it out after dispatching the UP.
4303 int32_t originalKeyCode = keyEntry->keyCode;
4304 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4305 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4306 connection->inputState.removeFallbackKey(originalKeyCode);
4307 }
4308
4309 if (handled || !dispatchEntry->hasForegroundTarget()) {
4310 // If the application handles the original key for which we previously
4311 // generated a fallback or if the window is not a foreground window,
4312 // then cancel the associated fallback key, if any.
4313 if (fallbackKeyCode != -1) {
4314 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004315#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004316 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004317 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4318 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4319 keyEntry->policyFlags);
4320#endif
4321 KeyEvent event;
4322 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004323 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324
4325 mLock.unlock();
4326
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004327 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4328 &event, keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329
4330 mLock.lock();
4331
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004332 // Cancel the fallback key.
4333 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004334 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004335 "application handled the original non-fallback key "
4336 "or is no longer a foreground target, "
4337 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338 options.keyCode = fallbackKeyCode;
4339 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004340 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004341 connection->inputState.removeFallbackKey(originalKeyCode);
4342 }
4343 } else {
4344 // If the application did not handle a non-fallback key, first check
4345 // that we are in a good state to perform unhandled key event processing
4346 // Then ask the policy what to do with it.
4347 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
4348 && keyEntry->repeatCount == 0;
4349 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004350#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004351 ALOGD("Unhandled key event: Skipping unhandled key event processing "
4352 "since this is not an initial down. "
4353 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4354 originalKeyCode, keyEntry->action, keyEntry->repeatCount,
4355 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004357 return false;
4358 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004360 // Dispatch the unhandled key to the policy.
4361#if DEBUG_OUTBOUND_EVENT_DETAILS
4362 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
4363 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4364 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4365 keyEntry->policyFlags);
4366#endif
4367 KeyEvent event;
4368 initializeKeyEvent(&event, keyEntry);
4369
4370 mLock.unlock();
4371
4372 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(),
4373 &event, keyEntry->policyFlags, &event);
4374
4375 mLock.lock();
4376
4377 if (connection->status != Connection::STATUS_NORMAL) {
4378 connection->inputState.removeFallbackKey(originalKeyCode);
4379 return false;
4380 }
4381
4382 // Latch the fallback keycode for this key on an initial down.
4383 // The fallback keycode cannot change at any other point in the lifecycle.
4384 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004386 fallbackKeyCode = event.getKeyCode();
4387 } else {
4388 fallbackKeyCode = AKEYCODE_UNKNOWN;
4389 }
4390 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4391 }
4392
4393 ALOG_ASSERT(fallbackKeyCode != -1);
4394
4395 // Cancel the fallback key if the policy decides not to send it anymore.
4396 // We will continue to dispatch the key to the policy but we will no
4397 // longer dispatch a fallback key to the application.
4398 if (fallbackKeyCode != AKEYCODE_UNKNOWN
4399 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
4400#if DEBUG_OUTBOUND_EVENT_DETAILS
4401 if (fallback) {
4402 ALOGD("Unhandled key event: Policy requested to send key %d"
4403 "as a fallback for %d, but on the DOWN it had requested "
4404 "to send %d instead. Fallback canceled.",
4405 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
4406 } else {
4407 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
4408 "but on the DOWN it had requested to send %d. "
4409 "Fallback canceled.",
4410 originalKeyCode, fallbackKeyCode);
4411 }
4412#endif
4413
4414 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4415 "canceling fallback, policy no longer desires it");
4416 options.keyCode = fallbackKeyCode;
4417 synthesizeCancelationEventsForConnectionLocked(connection, options);
4418
4419 fallback = false;
4420 fallbackKeyCode = AKEYCODE_UNKNOWN;
4421 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
4422 connection->inputState.setFallbackKey(originalKeyCode,
4423 fallbackKeyCode);
4424 }
4425 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004426
4427#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004428 {
4429 std::string msg;
4430 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4431 connection->inputState.getFallbackKeys();
4432 for (size_t i = 0; i < fallbackKeys.size(); i++) {
4433 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i),
4434 fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004435 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004436 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
4437 fallbackKeys.size(), msg.c_str());
4438 }
4439#endif
4440
4441 if (fallback) {
4442 // Restart the dispatch cycle using the fallback key.
4443 keyEntry->eventTime = event.getEventTime();
4444 keyEntry->deviceId = event.getDeviceId();
4445 keyEntry->source = event.getSource();
4446 keyEntry->displayId = event.getDisplayId();
4447 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4448 keyEntry->keyCode = fallbackKeyCode;
4449 keyEntry->scanCode = event.getScanCode();
4450 keyEntry->metaState = event.getMetaState();
4451 keyEntry->repeatCount = event.getRepeatCount();
4452 keyEntry->downTime = event.getDownTime();
4453 keyEntry->syntheticRepeat = false;
4454
4455#if DEBUG_OUTBOUND_EVENT_DETAILS
4456 ALOGD("Unhandled key event: Dispatching fallback key. "
4457 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4458 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4459#endif
4460 return true; // restart the event
4461 } else {
4462#if DEBUG_OUTBOUND_EVENT_DETAILS
4463 ALOGD("Unhandled key event: No fallback key.");
4464#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004465
4466 // Report the key as unhandled, since there is no fallback key.
4467 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004468 }
4469 }
4470 return false;
4471}
4472
4473bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4474 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4475 return false;
4476}
4477
4478void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4479 mLock.unlock();
4480
4481 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4482
4483 mLock.lock();
4484}
4485
4486void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004487 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004488 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4489 entry->downTime, entry->eventTime);
4490}
4491
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004492void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4494 // TODO Write some statistics about how long we spend waiting.
4495}
4496
4497void InputDispatcher::traceInboundQueueLengthLocked() {
4498 if (ATRACE_ENABLED()) {
4499 ATRACE_INT("iq", mInboundQueue.count());
4500 }
4501}
4502
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004503void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004504 if (ATRACE_ENABLED()) {
4505 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004506 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004507 ATRACE_INT(counterName, connection->outboundQueue.count());
4508 }
4509}
4510
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004511void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004512 if (ATRACE_ENABLED()) {
4513 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004514 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004515 ATRACE_INT(counterName, connection->waitQueue.count());
4516 }
4517}
4518
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004519void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004520 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004521
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004522 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004523 dumpDispatchStateLocked(dump);
4524
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004525 if (!mLastANRState.empty()) {
4526 dump += "\nInput Dispatcher State at time of last ANR:\n";
4527 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004528 }
4529}
4530
4531void InputDispatcher::monitor() {
4532 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004533 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004534 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004535 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004536}
4537
4538
Michael Wrightd02c5b62014-02-10 15:10:22 -08004539// --- InputDispatcher::InjectionState ---
4540
4541InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4542 refCount(1),
4543 injectorPid(injectorPid), injectorUid(injectorUid),
4544 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4545 pendingForegroundDispatches(0) {
4546}
4547
4548InputDispatcher::InjectionState::~InjectionState() {
4549}
4550
4551void InputDispatcher::InjectionState::release() {
4552 refCount -= 1;
4553 if (refCount == 0) {
4554 delete this;
4555 } else {
4556 ALOG_ASSERT(refCount > 0);
4557 }
4558}
4559
4560
4561// --- InputDispatcher::EventEntry ---
4562
Prabir Pradhan42611e02018-11-27 14:04:02 -08004563InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type,
4564 nsecs_t eventTime, uint32_t policyFlags) :
4565 sequenceNum(sequenceNum), refCount(1), type(type), eventTime(eventTime),
4566 policyFlags(policyFlags), injectionState(nullptr), dispatchInProgress(false) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567}
4568
4569InputDispatcher::EventEntry::~EventEntry() {
4570 releaseInjectionState();
4571}
4572
4573void InputDispatcher::EventEntry::release() {
4574 refCount -= 1;
4575 if (refCount == 0) {
4576 delete this;
4577 } else {
4578 ALOG_ASSERT(refCount > 0);
4579 }
4580}
4581
4582void InputDispatcher::EventEntry::releaseInjectionState() {
4583 if (injectionState) {
4584 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004585 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586 }
4587}
4588
4589
4590// --- InputDispatcher::ConfigurationChangedEntry ---
4591
Prabir Pradhan42611e02018-11-27 14:04:02 -08004592InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(
4593 uint32_t sequenceNum, nsecs_t eventTime) :
4594 EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595}
4596
4597InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4598}
4599
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004600void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4601 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004602}
4603
4604
4605// --- InputDispatcher::DeviceResetEntry ---
4606
Prabir Pradhan42611e02018-11-27 14:04:02 -08004607InputDispatcher::DeviceResetEntry::DeviceResetEntry(
4608 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
4609 EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004610 deviceId(deviceId) {
4611}
4612
4613InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4614}
4615
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004616void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
4617 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618 deviceId, policyFlags);
4619}
4620
4621
4622// --- InputDispatcher::KeyEntry ---
4623
Prabir Pradhan42611e02018-11-27 14:04:02 -08004624InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004625 int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4627 int32_t repeatCount, nsecs_t downTime) :
Prabir Pradhan42611e02018-11-27 14:04:02 -08004628 EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004629 deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004630 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4631 repeatCount(repeatCount), downTime(downTime),
4632 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4633 interceptKeyWakeupTime(0) {
4634}
4635
4636InputDispatcher::KeyEntry::~KeyEntry() {
4637}
4638
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004639void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004640 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Michael Wrightd02c5b62014-02-10 15:10:22 -08004641 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4642 "repeatCount=%d), policyFlags=0x%08x",
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004643 deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004644 scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004645}
4646
4647void InputDispatcher::KeyEntry::recycle() {
4648 releaseInjectionState();
4649
4650 dispatchInProgress = false;
4651 syntheticRepeat = false;
4652 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4653 interceptKeyWakeupTime = 0;
4654}
4655
4656
4657// --- InputDispatcher::MotionEntry ---
4658
Garfield Tan00f511d2019-06-12 16:55:40 -07004659InputDispatcher::MotionEntry::MotionEntry(
4660 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4661 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004662 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004663 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4664 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004665 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004666 float xOffset, float yOffset)
4667 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004668 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004669 deviceId(deviceId),
4670 source(source),
4671 displayId(displayId),
4672 action(action),
4673 actionButton(actionButton),
4674 flags(flags),
4675 metaState(metaState),
4676 buttonState(buttonState),
4677 classification(classification),
4678 edgeFlags(edgeFlags),
4679 xPrecision(xPrecision),
4680 yPrecision(yPrecision),
4681 xCursorPosition(xCursorPosition),
4682 yCursorPosition(yCursorPosition),
4683 downTime(downTime),
4684 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004685 for (uint32_t i = 0; i < pointerCount; i++) {
4686 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4687 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004688 if (xOffset || yOffset) {
4689 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4690 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691 }
4692}
4693
4694InputDispatcher::MotionEntry::~MotionEntry() {
4695}
4696
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004697void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004698 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004699 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4700 "buttonState=0x%08x, "
4701 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4702 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4703 deviceId, source, displayId, motionActionToString(action).c_str(),
4704 actionButton, flags, metaState, buttonState,
4705 motionClassificationToString(classification), edgeFlags, xPrecision,
4706 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004707
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708 for (uint32_t i = 0; i < pointerCount; i++) {
4709 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004710 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004711 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004712 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 pointerCoords[i].getX(), pointerCoords[i].getY());
4714 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004715 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716}
4717
4718
4719// --- InputDispatcher::DispatchEntry ---
4720
4721volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4722
4723InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
Robert Carre07e1032018-11-26 12:55:53 -08004724 int32_t targetFlags, float xOffset, float yOffset, float globalScaleFactor,
4725 float windowXScale, float windowYScale) :
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726 seq(nextSeq()),
4727 eventEntry(eventEntry), targetFlags(targetFlags),
Robert Carre07e1032018-11-26 12:55:53 -08004728 xOffset(xOffset), yOffset(yOffset), globalScaleFactor(globalScaleFactor),
4729 windowXScale(windowXScale), windowYScale(windowYScale),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730 deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
4731 eventEntry->refCount += 1;
4732}
4733
4734InputDispatcher::DispatchEntry::~DispatchEntry() {
4735 eventEntry->release();
4736}
4737
4738uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4739 // Sequence number 0 is reserved and will never be returned.
4740 uint32_t seq;
4741 do {
4742 seq = android_atomic_inc(&sNextSeqAtomic);
4743 } while (!seq);
4744 return seq;
4745}
4746
4747
4748// --- InputDispatcher::InputState ---
4749
4750InputDispatcher::InputState::InputState() {
4751}
4752
4753InputDispatcher::InputState::~InputState() {
4754}
4755
4756bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004757 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758}
4759
4760bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
4761 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004762 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004763 if (memento.deviceId == deviceId
4764 && memento.source == source
4765 && memento.displayId == displayId
4766 && memento.hovering) {
4767 return true;
4768 }
4769 }
4770 return false;
4771}
4772
4773bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4774 int32_t action, int32_t flags) {
4775 switch (action) {
4776 case AKEY_EVENT_ACTION_UP: {
4777 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4778 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4779 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4780 mFallbackKeys.removeItemsAt(i);
4781 } else {
4782 i += 1;
4783 }
4784 }
4785 }
4786 ssize_t index = findKeyMemento(entry);
4787 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004788 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004789 return true;
4790 }
4791 /* FIXME: We can't just drop the key up event because that prevents creating
4792 * popup windows that are automatically shown when a key is held and then
4793 * dismissed when the key is released. The problem is that the popup will
4794 * not have received the original key down, so the key up will be considered
4795 * to be inconsistent with its observed state. We could perhaps handle this
4796 * by synthesizing a key down but that will cause other problems.
4797 *
4798 * So for now, allow inconsistent key up events to be dispatched.
4799 *
4800#if DEBUG_OUTBOUND_EVENT_DETAILS
4801 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4802 "keyCode=%d, scanCode=%d",
4803 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4804#endif
4805 return false;
4806 */
4807 return true;
4808 }
4809
4810 case AKEY_EVENT_ACTION_DOWN: {
4811 ssize_t index = findKeyMemento(entry);
4812 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004813 mKeyMementos.erase(mKeyMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004814 }
4815 addKeyMemento(entry, flags);
4816 return true;
4817 }
4818
4819 default:
4820 return true;
4821 }
4822}
4823
4824bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4825 int32_t action, int32_t flags) {
4826 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4827 switch (actionMasked) {
4828 case AMOTION_EVENT_ACTION_UP:
4829 case AMOTION_EVENT_ACTION_CANCEL: {
4830 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4831 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004832 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833 return true;
4834 }
4835#if DEBUG_OUTBOUND_EVENT_DETAILS
4836 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004837 "displayId=%" PRId32 ", actionMasked=%d",
4838 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004839#endif
4840 return false;
4841 }
4842
4843 case AMOTION_EVENT_ACTION_DOWN: {
4844 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4845 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004846 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 }
4848 addMotionMemento(entry, flags, false /*hovering*/);
4849 return true;
4850 }
4851
4852 case AMOTION_EVENT_ACTION_POINTER_UP:
4853 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4854 case AMOTION_EVENT_ACTION_MOVE: {
Michael Wright38dcdff2014-03-19 12:06:10 -07004855 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4856 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
4857 // generate cancellation events for these since they're based in relative rather than
4858 // absolute units.
4859 return true;
4860 }
4861
Michael Wrightd02c5b62014-02-10 15:10:22 -08004862 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004863
4864 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4865 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4866 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
4867 // other value and we need to track the motion so we can send cancellation events for
4868 // anything generating fallback events (e.g. DPad keys for joystick movements).
4869 if (index >= 0) {
4870 if (entry->pointerCoords[0].isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004871 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wright38dcdff2014-03-19 12:06:10 -07004872 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004873 MotionMemento& memento = mMotionMementos[index];
Michael Wright38dcdff2014-03-19 12:06:10 -07004874 memento.setPointers(entry);
4875 }
4876 } else if (!entry->pointerCoords[0].isEmpty()) {
4877 addMotionMemento(entry, flags, false /*hovering*/);
4878 }
4879
4880 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4881 return true;
4882 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004883 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004884 MotionMemento& memento = mMotionMementos[index];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004885 memento.setPointers(entry);
4886 return true;
4887 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004888#if DEBUG_OUTBOUND_EVENT_DETAILS
4889 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004890 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4891 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004892#endif
4893 return false;
4894 }
4895
4896 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4897 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4898 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004899 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900 return true;
4901 }
4902#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004903 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4904 "displayId=%" PRId32,
4905 entry->deviceId, entry->source, entry->displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906#endif
4907 return false;
4908 }
4909
4910 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4911 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4912 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4913 if (index >= 0) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004914 mMotionMementos.erase(mMotionMementos.begin() + index);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004915 }
4916 addMotionMemento(entry, flags, true /*hovering*/);
4917 return true;
4918 }
4919
4920 default:
4921 return true;
4922 }
4923}
4924
4925ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4926 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004927 const KeyMemento& memento = mKeyMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004928 if (memento.deviceId == entry->deviceId
4929 && memento.source == entry->source
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004930 && memento.displayId == entry->displayId
Michael Wrightd02c5b62014-02-10 15:10:22 -08004931 && memento.keyCode == entry->keyCode
4932 && memento.scanCode == entry->scanCode) {
4933 return i;
4934 }
4935 }
4936 return -1;
4937}
4938
4939ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4940 bool hovering) const {
4941 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004942 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08004943 if (memento.deviceId == entry->deviceId
4944 && memento.source == entry->source
4945 && memento.displayId == entry->displayId
4946 && memento.hovering == hovering) {
4947 return i;
4948 }
4949 }
4950 return -1;
4951}
4952
4953void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004954 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 memento.deviceId = entry->deviceId;
4956 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004957 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004958 memento.keyCode = entry->keyCode;
4959 memento.scanCode = entry->scanCode;
4960 memento.metaState = entry->metaState;
4961 memento.flags = flags;
4962 memento.downTime = entry->downTime;
4963 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004964 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004965}
4966
4967void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4968 int32_t flags, bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004969 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004970 memento.deviceId = entry->deviceId;
4971 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004972 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004973 memento.flags = flags;
4974 memento.xPrecision = entry->xPrecision;
4975 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07004976 memento.xCursorPosition = entry->xCursorPosition;
4977 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004978 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 memento.setPointers(entry);
4980 memento.hovering = hovering;
4981 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004982 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983}
4984
4985void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4986 pointerCount = entry->pointerCount;
4987 for (uint32_t i = 0; i < entry->pointerCount; i++) {
4988 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
4989 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
4990 }
4991}
4992
4993void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004994 std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
4995 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004996 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004997 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004998 memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
5000 memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
5001 }
5002 }
5003
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005004 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005 if (shouldCancelMotion(memento, options)) {
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08005006 const int32_t action = memento.hovering ?
5007 AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005008 outEvents.push_back(
5009 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5010 memento.source, memento.displayId, memento.policyFlags, action,
5011 0 /*actionButton*/, memento.flags, AMETA_NONE,
5012 0 /*buttonState*/, MotionClassification::NONE,
5013 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5014 memento.yPrecision, memento.xCursorPosition,
5015 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5016 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5017 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005018 }
5019 }
5020}
5021
5022void InputDispatcher::InputState::clear() {
5023 mKeyMementos.clear();
5024 mMotionMementos.clear();
5025 mFallbackKeys.clear();
5026}
5027
5028void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5029 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005030 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005031 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
5032 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005033 const MotionMemento& otherMemento = other.mMotionMementos[j];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005034 if (memento.deviceId == otherMemento.deviceId
5035 && memento.source == otherMemento.source
5036 && memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005037 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005038 } else {
5039 j += 1;
5040 }
5041 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005042 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005043 }
5044 }
5045}
5046
5047int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5048 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5049 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5050}
5051
5052void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
5053 int32_t fallbackKeyCode) {
5054 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5055 if (index >= 0) {
5056 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5057 } else {
5058 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5059 }
5060}
5061
5062void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5063 mFallbackKeys.removeItem(originalKeyCode);
5064}
5065
5066bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
5067 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005068 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005069 return false;
5070 }
5071
Michael Wright3dd60e22019-03-27 22:06:44 +00005072 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5073 return false;
5074 }
5075
5076 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077 return false;
5078 }
5079
5080 switch (options.mode) {
5081 case CancelationOptions::CANCEL_ALL_EVENTS:
5082 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5083 return true;
5084 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5085 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5086 default:
5087 return false;
5088 }
5089}
5090
5091bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5092 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005093 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5094 return false;
5095 }
5096
5097 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005098 return false;
5099 }
5100
5101 switch (options.mode) {
5102 case CancelationOptions::CANCEL_ALL_EVENTS:
5103 return true;
5104 case CancelationOptions::CANCEL_POINTER_EVENTS:
5105 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5106 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5107 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5108 default:
5109 return false;
5110 }
5111}
5112
5113
5114// --- InputDispatcher::Connection ---
5115
Robert Carr803535b2018-08-02 16:38:15 -07005116InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor) :
5117 status(STATUS_NORMAL), inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005118 monitor(monitor),
5119 inputPublisher(inputChannel), inputPublisherBlocked(false) {
5120}
5121
5122InputDispatcher::Connection::~Connection() {
5123}
5124
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005125const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005126 if (inputChannel != nullptr) {
5127 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128 }
5129 if (monitor) {
5130 return "monitor";
5131 }
5132 return "?";
5133}
5134
5135const char* InputDispatcher::Connection::getStatusLabel() const {
5136 switch (status) {
5137 case STATUS_NORMAL:
5138 return "NORMAL";
5139
5140 case STATUS_BROKEN:
5141 return "BROKEN";
5142
5143 case STATUS_ZOMBIE:
5144 return "ZOMBIE";
5145
5146 default:
5147 return "UNKNOWN";
5148 }
5149}
5150
5151InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
Yi Kong9b14ac62018-07-17 13:48:38 -07005152 for (DispatchEntry* entry = waitQueue.head; entry != nullptr; entry = entry->next) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153 if (entry->seq == seq) {
5154 return entry;
5155 }
5156 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005157 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005158}
5159
Michael Wright3dd60e22019-03-27 22:06:44 +00005160// --- InputDispatcher::Monitor
5161InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel) :
5162 inputChannel(inputChannel) {
5163}
5164
Michael Wrightd02c5b62014-02-10 15:10:22 -08005165
5166// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005167//
Michael Wrightd02c5b62014-02-10 15:10:22 -08005168InputDispatcher::CommandEntry::CommandEntry(Command command) :
Yi Kong9b14ac62018-07-17 13:48:38 -07005169 command(command), eventTime(0), keyEntry(nullptr), userActivityEventType(0),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170 seq(0), handled(false) {
5171}
5172
5173InputDispatcher::CommandEntry::~CommandEntry() {
5174}
5175
Michael Wright3dd60e22019-03-27 22:06:44 +00005176// --- InputDispatcher::TouchedMonitor ---
5177InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
5178 float yOffset) : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {
5179}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005180
5181// --- InputDispatcher::TouchState ---
5182
5183InputDispatcher::TouchState::TouchState() :
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005184 down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005185}
5186
5187InputDispatcher::TouchState::~TouchState() {
5188}
5189
5190void InputDispatcher::TouchState::reset() {
5191 down = false;
5192 split = false;
5193 deviceId = -1;
5194 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005195 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005196 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005197 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005198 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005199}
5200
5201void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5202 down = other.down;
5203 split = other.split;
5204 deviceId = other.deviceId;
5205 source = other.source;
5206 displayId = other.displayId;
5207 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005208 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005209 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005210}
5211
5212void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
5213 int32_t targetFlags, BitSet32 pointerIds) {
5214 if (targetFlags & InputTarget::FLAG_SPLIT) {
5215 split = true;
5216 }
5217
5218 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005219 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220 if (touchedWindow.windowHandle == windowHandle) {
5221 touchedWindow.targetFlags |= targetFlags;
5222 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5223 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5224 }
5225 touchedWindow.pointerIds.value |= pointerIds.value;
5226 return;
5227 }
5228 }
5229
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005230 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005231 touchedWindow.windowHandle = windowHandle;
5232 touchedWindow.targetFlags = targetFlags;
5233 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005234 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235}
5236
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005237void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5238 size_t numWindows = portalWindows.size();
5239 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005240 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005241 return;
5242 }
5243 }
5244 portalWindows.push_back(windowHandle);
5245}
5246
Michael Wright3dd60e22019-03-27 22:06:44 +00005247void InputDispatcher::TouchState::addGestureMonitors(
5248 const std::vector<TouchedMonitor>& newMonitors) {
5249 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5250 gestureMonitors.reserve(newSize);
5251 gestureMonitors.insert(std::end(gestureMonitors),
5252 std::begin(newMonitors), std::end(newMonitors));
5253}
5254
Michael Wrightd02c5b62014-02-10 15:10:22 -08005255void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5256 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005257 if (windows[i].windowHandle == windowHandle) {
5258 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005259 return;
5260 }
5261 }
5262}
5263
Robert Carr803535b2018-08-02 16:38:15 -07005264void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5265 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005266 if (windows[i].windowHandle->getToken() == token) {
5267 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005268 return;
5269 }
5270 }
5271}
5272
Michael Wrightd02c5b62014-02-10 15:10:22 -08005273void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
5274 for (size_t i = 0 ; i < windows.size(); ) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005275 TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005276 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
5277 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
5278 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5279 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5280 i += 1;
5281 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005282 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005283 }
5284 }
5285}
5286
Michael Wright3dd60e22019-03-27 22:06:44 +00005287void InputDispatcher::TouchState::filterNonMonitors() {
5288 windows.clear();
5289 portalWindows.clear();
5290}
5291
Michael Wrightd02c5b62014-02-10 15:10:22 -08005292sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5293 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005294 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005295 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5296 return window.windowHandle;
5297 }
5298 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005299 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005300}
5301
5302bool InputDispatcher::TouchState::isSlippery() const {
5303 // Must have exactly one foreground window.
5304 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005305 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5307 if (haveSlipperyForegroundWindow
5308 || !(window.windowHandle->getInfo()->layoutParamsFlags
5309 & InputWindowInfo::FLAG_SLIPPERY)) {
5310 return false;
5311 }
5312 haveSlipperyForegroundWindow = true;
5313 }
5314 }
5315 return haveSlipperyForegroundWindow;
5316}
5317
5318
5319// --- InputDispatcherThread ---
5320
5321InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
5322 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
5323}
5324
5325InputDispatcherThread::~InputDispatcherThread() {
5326}
5327
5328bool InputDispatcherThread::threadLoop() {
5329 mDispatcher->dispatchOnce();
5330 return true;
5331}
5332
5333} // namespace android