blob: 4b8c51be5e48b4dbdf77b6d8408dc0d6c5f44a29 [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>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070051#include <stddef.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080052#include <time.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070053#include <unistd.h>
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -070054#include <queue>
55#include <sstream>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070056
Michael Wright2b3c3302018-03-02 17:19:13 +000057#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080058#include <android-base/stringprintf.h>
Robert Carr4e670e52018-08-15 13:26:12 -070059#include <binder/Binder.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <log/log.h>
61#include <powermanager/PowerManager.h>
62#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080063
64#define INDENT " "
65#define INDENT2 " "
66#define INDENT3 " "
67#define INDENT4 " "
68
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080069using android::base::StringPrintf;
70
Michael Wrightd02c5b62014-02-10 15:10:22 -080071namespace android {
72
73// Default input dispatching timeout if there is no focused application or paused window
74// from which to determine an appropriate dispatching timeout.
Michael Wright2b3c3302018-03-02 17:19:13 +000075constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080076
77// Amount of time to allow for all pending events to be processed when an app switch
78// key is on the way. This is used to preempt input dispatch and drop input events
79// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000080constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080081
82// Amount of time to allow for an event to be dispatched (measured since its eventTime)
83// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +000084constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080085
86// Amount of time to allow touch events to be streamed out to a connection before requiring
87// that the first event be finished. This value extends the ANR timeout by the specified
88// amount. For example, if streaming is allowed to get ahead by one second relative to the
89// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
Michael Wright2b3c3302018-03-02 17:19:13 +000090constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080091
92// 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 +000093constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
94
95// Log a warning when an interception call takes longer than this to process.
96constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -080097
98// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +000099constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
100
Prabir Pradhan42611e02018-11-27 14:04:02 -0800101// Sequence number for synthesized or injected events.
102constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104static 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
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700114 switch (action & AMOTION_EVENT_ACTION_MASK) {
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -0800115 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) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
162 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163}
164
165static bool isValidKeyAction(int32_t action) {
166 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700167 case AKEY_EVENT_ACTION_DOWN:
168 case AKEY_EVENT_ACTION_UP:
169 return true;
170 default:
171 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172 }
173}
174
175static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700176 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 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) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700185 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);
198 return index >= 0 && index < pointerCount;
199 }
200 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
201 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
202 return actionButton != 0;
203 default:
204 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205 }
206}
207
Michael Wright7b159c92015-05-14 14:48:03 +0100208static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700209 const PointerProperties* pointerProperties) {
210 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.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700216 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 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) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700223 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
224 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 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 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700264template <typename K, typename V>
265static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700266 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700267 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800268}
269
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700270/**
271 * Find the entry in std::unordered_map by value, and remove it.
272 * If more than one entry has the same value, then all matching
273 * key-value pairs will be removed.
274 *
275 * Return true if at least one value has been removed.
276 */
277template <typename K, typename V>
278static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
279 bool removed = false;
280 for (auto it = map.begin(); it != map.end();) {
281 if (it->second == value) {
282 it = map.erase(it);
283 removed = true;
284 } else {
285 it++;
286 }
287 }
288 return removed;
289}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800290
291// --- InputDispatcher ---
292
Garfield Tan00f511d2019-06-12 16:55:40 -0700293InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
294 : mPolicy(policy),
295 mPendingEvent(nullptr),
296 mLastDropReason(DROP_REASON_NOT_DROPPED),
297 mAppSwitchSawKeyDown(false),
298 mAppSwitchDueTime(LONG_LONG_MAX),
299 mNextUnblockedEvent(nullptr),
300 mDispatchEnabled(false),
301 mDispatchFrozen(false),
302 mInputFilterEnabled(false),
303 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
304 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800305 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800306 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800307
Yi Kong9b14ac62018-07-17 13:48:38 -0700308 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800309
310 policy->getDispatcherConfiguration(&mConfig);
311}
312
313InputDispatcher::~InputDispatcher() {
314 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800315 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800316
317 resetKeyRepeatLocked();
318 releasePendingEventLocked();
319 drainInboundQueueLocked();
320 }
321
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700322 while (!mConnectionsByFd.empty()) {
323 sp<Connection> connection = mConnectionsByFd.begin()->second;
324 unregisterInputChannel(connection->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800325 }
326}
327
328void InputDispatcher::dispatchOnce() {
329 nsecs_t nextWakeupTime = LONG_LONG_MAX;
330 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800331 std::scoped_lock _l(mLock);
332 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800333
334 // Run a dispatch loop if there are no pending commands.
335 // The dispatch loop might enqueue commands to run afterwards.
336 if (!haveCommandsLocked()) {
337 dispatchOnceInnerLocked(&nextWakeupTime);
338 }
339
340 // Run all pending commands if there are any.
341 // If any commands were run then force the next poll to wake up immediately.
342 if (runCommandsLockedInterruptible()) {
343 nextWakeupTime = LONG_LONG_MIN;
344 }
345 } // release lock
346
347 // Wait for callback or timeout or wake. (make sure we round up, not down)
348 nsecs_t currentTime = now();
349 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
350 mLooper->pollOnce(timeoutMillis);
351}
352
353void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
354 nsecs_t currentTime = now();
355
Jeff Browndc5992e2014-04-11 01:27:26 -0700356 // Reset the key repeat timer whenever normal dispatch is suspended while the
357 // device is in a non-interactive state. This is to ensure that we abort a key
358 // repeat if the device is just coming out of sleep.
359 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800360 resetKeyRepeatLocked();
361 }
362
363 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
364 if (mDispatchFrozen) {
365#if DEBUG_FOCUS
366 ALOGD("Dispatch frozen. Waiting some more.");
367#endif
368 return;
369 }
370
371 // Optimize latency of app switches.
372 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
373 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
374 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
375 if (mAppSwitchDueTime < *nextWakeupTime) {
376 *nextWakeupTime = mAppSwitchDueTime;
377 }
378
379 // Ready to start a new event.
380 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700381 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700382 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800383 if (isAppSwitchDue) {
384 // The inbound queue is empty so the app switch key we were waiting
385 // for will never arrive. Stop waiting for it.
386 resetPendingAppSwitchLocked(false);
387 isAppSwitchDue = false;
388 }
389
390 // Synthesize a key repeat if appropriate.
391 if (mKeyRepeatState.lastKeyEntry) {
392 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
393 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
394 } else {
395 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
396 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
397 }
398 }
399 }
400
401 // Nothing to do if there is no pending event.
402 if (!mPendingEvent) {
403 return;
404 }
405 } else {
406 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700407 mPendingEvent = mInboundQueue.front();
408 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800409 traceInboundQueueLengthLocked();
410 }
411
412 // Poke user activity for this event.
413 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
414 pokeUserActivityLocked(mPendingEvent);
415 }
416
417 // Get ready to dispatch the event.
418 resetANRTimeoutsLocked();
419 }
420
421 // Now we have an event to dispatch.
422 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700423 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800424 bool done = false;
425 DropReason dropReason = DROP_REASON_NOT_DROPPED;
426 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
427 dropReason = DROP_REASON_POLICY;
428 } else if (!mDispatchEnabled) {
429 dropReason = DROP_REASON_DISABLED;
430 }
431
432 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700433 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800434 }
435
436 switch (mPendingEvent->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700437 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
438 ConfigurationChangedEntry* typedEntry =
439 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
440 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
441 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
442 break;
443 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800444
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700445 case EventEntry::TYPE_DEVICE_RESET: {
446 DeviceResetEntry* typedEntry = static_cast<DeviceResetEntry*>(mPendingEvent);
447 done = dispatchDeviceResetLocked(currentTime, typedEntry);
448 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
449 break;
450 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800451
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700452 case EventEntry::TYPE_KEY: {
453 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
454 if (isAppSwitchDue) {
455 if (isAppSwitchKeyEvent(typedEntry)) {
456 resetPendingAppSwitchLocked(true);
457 isAppSwitchDue = false;
458 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
459 dropReason = DROP_REASON_APP_SWITCH;
460 }
461 }
462 if (dropReason == DROP_REASON_NOT_DROPPED && isStaleEvent(currentTime, typedEntry)) {
463 dropReason = DROP_REASON_STALE;
464 }
465 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
466 dropReason = DROP_REASON_BLOCKED;
467 }
468 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
469 break;
470 }
471
472 case EventEntry::TYPE_MOTION: {
473 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
474 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800475 dropReason = DROP_REASON_APP_SWITCH;
476 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700477 if (dropReason == DROP_REASON_NOT_DROPPED && isStaleEvent(currentTime, typedEntry)) {
478 dropReason = DROP_REASON_STALE;
479 }
480 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
481 dropReason = DROP_REASON_BLOCKED;
482 }
483 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
484 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800485 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800486
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700487 default:
488 ALOG_ASSERT(false);
489 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 }
491
492 if (done) {
493 if (dropReason != DROP_REASON_NOT_DROPPED) {
494 dropInboundEventLocked(mPendingEvent, dropReason);
495 }
Michael Wright3a981722015-06-10 15:26:13 +0100496 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800497
498 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700499 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800500 }
501}
502
503bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700504 bool needWake = mInboundQueue.empty();
505 mInboundQueue.push_back(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800506 traceInboundQueueLengthLocked();
507
508 switch (entry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700509 case EventEntry::TYPE_KEY: {
510 // Optimize app switch latency.
511 // If the application takes too long to catch up then we drop all events preceding
512 // the app switch key.
513 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
514 if (isAppSwitchKeyEvent(keyEntry)) {
515 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
516 mAppSwitchSawKeyDown = true;
517 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
518 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800519#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700520 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800521#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700522 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
523 mAppSwitchSawKeyDown = false;
524 needWake = true;
525 }
526 }
527 }
528 break;
529 }
530
531 case EventEntry::TYPE_MOTION: {
532 // Optimize case where the current application is unresponsive and the user
533 // decides to touch a window in a different application.
534 // If the application takes too long to catch up then we drop all events preceding
535 // the touch into the other window.
536 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
537 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN &&
538 (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
539 mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY &&
540 mInputTargetWaitApplicationToken != nullptr) {
541 int32_t displayId = motionEntry->displayId;
542 int32_t x =
543 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
544 int32_t y =
545 int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
546 sp<InputWindowHandle> touchedWindowHandle =
547 findTouchedWindowAtLocked(displayId, x, y);
548 if (touchedWindowHandle != nullptr &&
549 touchedWindowHandle->getApplicationToken() !=
550 mInputTargetWaitApplicationToken) {
551 // User touched a different application than the one we are waiting on.
552 // Flag the event, and start pruning the input queue.
553 mNextUnblockedEvent = motionEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800554 needWake = true;
555 }
556 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700557 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559 }
560
561 return needWake;
562}
563
564void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
565 entry->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700566 mRecentQueue.push_back(entry);
567 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
568 mRecentQueue.front()->release();
569 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570 }
571}
572
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700573sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
574 int32_t y, bool addOutsideTargets,
575 bool addPortalWindows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800576 // Traverse windows from front to back to find touched window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800577 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
578 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800579 const InputWindowInfo* windowInfo = windowHandle->getInfo();
580 if (windowInfo->displayId == displayId) {
581 int32_t flags = windowInfo->layoutParamsFlags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582
583 if (windowInfo->visible) {
584 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700585 bool isTouchModal = (flags &
586 (InputWindowInfo::FLAG_NOT_FOCUSABLE |
587 InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800589 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700590 if (portalToDisplayId != ADISPLAY_ID_NONE &&
591 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800592 if (addPortalWindows) {
593 // For the monitoring channels of the display.
594 mTempTouchState.addPortalWindow(windowHandle);
595 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700596 return findTouchedWindowAtLocked(portalToDisplayId, x, y,
597 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800599 // Found window.
600 return windowHandle;
601 }
602 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800603
604 if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700605 mTempTouchState.addOrUpdateWindow(windowHandle,
606 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
607 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800608 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800609 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800610 }
611 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700612 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800613}
614
Michael Wright3dd60e22019-03-27 22:06:44 +0000615std::vector<InputDispatcher::TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
616 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) {
617 std::vector<TouchedMonitor> touchedMonitors;
618
619 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
620 addGestureMonitors(monitors, touchedMonitors);
621 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
622 const InputWindowInfo* windowInfo = portalWindow->getInfo();
623 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700624 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
625 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000626 }
627 return touchedMonitors;
628}
629
630void InputDispatcher::addGestureMonitors(const std::vector<Monitor>& monitors,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700631 std::vector<TouchedMonitor>& outTouchedMonitors,
632 float xOffset, float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000633 if (monitors.empty()) {
634 return;
635 }
636 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
637 for (const Monitor& monitor : monitors) {
638 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
639 }
640}
641
Michael Wrightd02c5b62014-02-10 15:10:22 -0800642void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
643 const char* reason;
644 switch (dropReason) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700645 case DROP_REASON_POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800646#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700647 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800648#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700649 reason = "inbound event was dropped because the policy consumed it";
650 break;
651 case DROP_REASON_DISABLED:
652 if (mLastDropReason != DROP_REASON_DISABLED) {
653 ALOGI("Dropped event because input dispatch is disabled.");
654 }
655 reason = "inbound event was dropped because input dispatch is disabled";
656 break;
657 case DROP_REASON_APP_SWITCH:
658 ALOGI("Dropped event because of pending overdue app switch.");
659 reason = "inbound event was dropped because of pending overdue app switch";
660 break;
661 case DROP_REASON_BLOCKED:
662 ALOGI("Dropped event because the current application is not responding and the user "
663 "has started interacting with a different application.");
664 reason = "inbound event was dropped because the current application is not responding "
665 "and the user has started interacting with a different application";
666 break;
667 case DROP_REASON_STALE:
668 ALOGI("Dropped event because it is stale.");
669 reason = "inbound event was dropped because it is stale";
670 break;
671 default:
672 ALOG_ASSERT(false);
673 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 }
675
676 switch (entry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700677 case EventEntry::TYPE_KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800678 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
679 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700680 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800681 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700682 case EventEntry::TYPE_MOTION: {
683 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
684 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
685 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
686 synthesizeCancelationEventsForAllConnectionsLocked(options);
687 } else {
688 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
689 synthesizeCancelationEventsForAllConnectionsLocked(options);
690 }
691 break;
692 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800693 }
694}
695
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800696static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700697 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
698 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800699}
700
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800701bool InputDispatcher::isAppSwitchKeyEvent(KeyEntry* keyEntry) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700702 return !(keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry->keyCode) &&
703 (keyEntry->policyFlags & POLICY_FLAG_TRUSTED) &&
704 (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800705}
706
707bool InputDispatcher::isAppSwitchPendingLocked() {
708 return mAppSwitchDueTime != LONG_LONG_MAX;
709}
710
711void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
712 mAppSwitchDueTime = LONG_LONG_MAX;
713
714#if DEBUG_APP_SWITCH
715 if (handled) {
716 ALOGD("App switch has arrived.");
717 } else {
718 ALOGD("App switch was abandoned.");
719 }
720#endif
721}
722
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800723bool InputDispatcher::isStaleEvent(nsecs_t currentTime, EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800724 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
725}
726
727bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700728 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800729}
730
731bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700732 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733 return false;
734 }
735
736 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700737 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700738 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700740 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741
742 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700743 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800744 return true;
745}
746
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700747void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
748 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800749}
750
751void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700752 while (!mInboundQueue.empty()) {
753 EventEntry* entry = mInboundQueue.front();
754 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800755 releaseInboundEventLocked(entry);
756 }
757 traceInboundQueueLengthLocked();
758}
759
760void InputDispatcher::releasePendingEventLocked() {
761 if (mPendingEvent) {
762 resetANRTimeoutsLocked();
763 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -0700764 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800765 }
766}
767
768void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
769 InjectionState* injectionState = entry->injectionState;
770 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
771#if DEBUG_DISPATCH_CYCLE
772 ALOGD("Injected inbound event was dropped.");
773#endif
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800774 setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800775 }
776 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700777 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800778 }
779 addRecentEventLocked(entry);
780 entry->release();
781}
782
783void InputDispatcher::resetKeyRepeatLocked() {
784 if (mKeyRepeatState.lastKeyEntry) {
785 mKeyRepeatState.lastKeyEntry->release();
Yi Kong9b14ac62018-07-17 13:48:38 -0700786 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787 }
788}
789
790InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
791 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
792
793 // Reuse the repeated key entry if it is otherwise unreferenced.
Michael Wright2e732952014-09-24 13:26:59 -0700794 uint32_t policyFlags = entry->policyFlags &
795 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800796 if (entry->refCount == 1) {
797 entry->recycle();
798 entry->eventTime = currentTime;
799 entry->policyFlags = policyFlags;
800 entry->repeatCount += 1;
801 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700802 KeyEntry* newEntry =
803 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, entry->deviceId,
804 entry->source, entry->displayId, policyFlags, entry->action,
805 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
806 entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807
808 mKeyRepeatState.lastKeyEntry = newEntry;
809 entry->release();
810
811 entry = newEntry;
812 }
813 entry->syntheticRepeat = true;
814
815 // Increment reference count since we keep a reference to the event in
816 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
817 entry->refCount += 1;
818
819 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
820 return entry;
821}
822
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700823bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
824 ConfigurationChangedEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700826 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827#endif
828
829 // Reset key repeating in case a keyboard device was added or removed or something.
830 resetKeyRepeatLocked();
831
832 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700833 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
834 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800835 commandEntry->eventTime = entry->eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700836 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800837 return true;
838}
839
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700840bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceResetEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800841#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700842 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry->eventTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700843 entry->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800844#endif
845
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700846 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800847 options.deviceId = entry->deviceId;
848 synthesizeCancelationEventsForAllConnectionsLocked(options);
849 return true;
850}
851
852bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700853 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800854 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 if (!entry->dispatchInProgress) {
856 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
857 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
858 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
859 if (mKeyRepeatState.lastKeyEntry &&
860 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800861 // We have seen two identical key downs in a row which indicates that the device
862 // driver is automatically generating key repeats itself. We take note of the
863 // repeat here, but we disable our own next key repeat timer since it is clear that
864 // we will not need to synthesize key repeats ourselves.
865 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
866 resetKeyRepeatLocked();
867 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
868 } else {
869 // Not a repeat. Save key down state in case we do see a repeat later.
870 resetKeyRepeatLocked();
871 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
872 }
873 mKeyRepeatState.lastKeyEntry = entry;
874 entry->refCount += 1;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800876 resetKeyRepeatLocked();
877 }
878
879 if (entry->repeatCount == 1) {
880 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
881 } else {
882 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
883 }
884
885 entry->dispatchInProgress = true;
886
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800887 logOutboundKeyDetails("dispatchKey - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800888 }
889
890 // Handle case where the policy asked us to try again later last time.
891 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
892 if (currentTime < entry->interceptKeyWakeupTime) {
893 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
894 *nextWakeupTime = entry->interceptKeyWakeupTime;
895 }
896 return false; // wait until next wakeup
897 }
898 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
899 entry->interceptKeyWakeupTime = 0;
900 }
901
902 // Give the policy a chance to intercept the key.
903 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
904 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700905 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -0700906 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Tiger Huang721e26f2018-07-24 22:26:19 +0800907 sp<InputWindowHandle> focusedWindowHandle =
908 getValueByKey(mFocusedWindowHandlesByDisplay, getTargetDisplayId(entry));
909 if (focusedWindowHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700910 commandEntry->inputChannel = getInputChannelLocked(focusedWindowHandle->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800911 }
912 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -0700913 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800914 entry->refCount += 1;
915 return false; // wait for the command to run
916 } else {
917 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
918 }
919 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
920 if (*dropReason == DROP_REASON_NOT_DROPPED) {
921 *dropReason = DROP_REASON_POLICY;
922 }
923 }
924
925 // Clean up if dropping the event.
926 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700927 setInjectionResult(entry,
928 *dropReason == DROP_REASON_POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
929 : INPUT_EVENT_INJECTION_FAILED);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800930 mReporter->reportDroppedKey(entry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931 return true;
932 }
933
934 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800935 std::vector<InputTarget> inputTargets;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700936 int32_t injectionResult =
937 findFocusedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800938 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
939 return false;
940 }
941
Siarhei Vishniakou62683e82019-03-06 17:59:56 -0800942 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800943 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
944 return true;
945 }
946
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800947 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +0000948 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -0800949
950 // Dispatch the key.
951 dispatchEventLocked(currentTime, entry, inputTargets);
952 return true;
953}
954
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800955void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100957 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700958 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
959 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
960 prefix, entry->eventTime, entry->deviceId, entry->source, entry->displayId,
961 entry->policyFlags, entry->action, entry->flags, entry->keyCode, entry->scanCode,
962 entry->metaState, entry->repeatCount, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800963#endif
964}
965
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
967 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000968 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800969 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700970 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800971 entry->dispatchInProgress = true;
972
Siarhei Vishniakou61291d42019-02-11 18:13:20 -0800973 logOutboundMotionDetails("dispatchMotion - ", entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974 }
975
976 // Clean up if dropping the event.
977 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 setInjectionResult(entry,
979 *dropReason == DROP_REASON_POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
980 : INPUT_EVENT_INJECTION_FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800981 return true;
982 }
983
984 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
985
986 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800987 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800988
989 bool conflictingPointerActions = false;
990 int32_t injectionResult;
991 if (isPointerEvent) {
992 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700993 injectionResult =
994 findTouchedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime,
995 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800996 } else {
997 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700998 injectionResult =
999 findFocusedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001000 }
1001 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
1002 return false;
1003 }
1004
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08001005 setInjectionResult(entry, injectionResult);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001006 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001007 if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001008 CancelationOptions::Mode mode(isPointerEvent
1009 ? CancelationOptions::CANCEL_POINTER_EVENTS
1010 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
Michael Wrightfa13dcf2015-06-12 13:25:11 +01001011 CancelationOptions options(mode, "input event injection failed");
1012 synthesizeCancelationEventsForMonitorsLocked(options);
1013 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001014 return true;
1015 }
1016
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001017 // Add monitor channels from event's or focused display.
Michael Wright3dd60e22019-03-27 22:06:44 +00001018 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001019
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001020 if (isPointerEvent) {
1021 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
1022 if (stateIndex >= 0) {
1023 const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001024 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001025 // The event has gone through these portal windows, so we add monitoring targets of
1026 // the corresponding displays as well.
1027 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001028 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001029 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001030 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001031 }
1032 }
1033 }
1034 }
1035
Michael Wrightd02c5b62014-02-10 15:10:22 -08001036 // Dispatch the motion.
1037 if (conflictingPointerActions) {
1038 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001039 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 synthesizeCancelationEventsForAllConnectionsLocked(options);
1041 }
1042 dispatchEventLocked(currentTime, entry, inputTargets);
1043 return true;
1044}
1045
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001046void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001048 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001049 ", policyFlags=0x%x, "
1050 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1051 "metaState=0x%x, buttonState=0x%x,"
1052 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1053 prefix, entry->eventTime, entry->deviceId, entry->source, entry->displayId,
1054 entry->policyFlags, entry->action, entry->actionButton, entry->flags, entry->metaState,
1055 entry->buttonState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
1056 entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057
1058 for (uint32_t i = 0; i < entry->pointerCount; i++) {
1059 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001060 "x=%f, y=%f, pressure=%f, size=%f, "
1061 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1062 "orientation=%f",
1063 i, entry->pointerProperties[i].id, entry->pointerProperties[i].toolType,
1064 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1065 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1066 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1067 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1068 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1069 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1070 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1071 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1072 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001073 }
1074#endif
1075}
1076
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001077void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,
1078 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001079 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080#if DEBUG_DISPATCH_CYCLE
1081 ALOGD("dispatchEventToCurrentInputTargets");
1082#endif
1083
1084 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1085
1086 pokeUserActivityLocked(eventEntry);
1087
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001088 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001089 sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel);
1090 if (connection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001091 prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
1092 } else {
1093#if DEBUG_FOCUS
1094 ALOGD("Dropping event delivery to target with channel '%s' because it "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001095 "is no longer registered with the input dispatcher.",
1096 inputTarget.inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001097#endif
1098 }
1099 }
1100}
1101
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001102int32_t InputDispatcher::handleTargetsNotReadyLocked(
1103 nsecs_t currentTime, const EventEntry* entry,
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104 const sp<InputApplicationHandle>& applicationHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001105 const sp<InputWindowHandle>& windowHandle, nsecs_t* nextWakeupTime, const char* reason) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001106 if (applicationHandle == nullptr && windowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1108#if DEBUG_FOCUS
1109 ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
1110#endif
1111 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1112 mInputTargetWaitStartTime = currentTime;
1113 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1114 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001115 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116 }
1117 } else {
1118 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1119#if DEBUG_FOCUS
1120 ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001121 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122#endif
1123 nsecs_t timeout;
Yi Kong9b14ac62018-07-17 13:48:38 -07001124 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Yi Kong9b14ac62018-07-17 13:48:38 -07001126 } else if (applicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001127 timeout =
1128 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129 } else {
1130 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1131 }
1132
1133 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1134 mInputTargetWaitStartTime = currentTime;
1135 mInputTargetWaitTimeoutTime = currentTime + timeout;
1136 mInputTargetWaitTimeoutExpired = false;
Robert Carr740167f2018-10-11 19:03:41 -07001137 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001138
Yi Kong9b14ac62018-07-17 13:48:38 -07001139 if (windowHandle != nullptr) {
Robert Carr740167f2018-10-11 19:03:41 -07001140 mInputTargetWaitApplicationToken = windowHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141 }
Robert Carr740167f2018-10-11 19:03:41 -07001142 if (mInputTargetWaitApplicationToken == nullptr && applicationHandle != nullptr) {
1143 mInputTargetWaitApplicationToken = applicationHandle->getApplicationToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144 }
1145 }
1146 }
1147
1148 if (mInputTargetWaitTimeoutExpired) {
1149 return INPUT_EVENT_INJECTION_TIMED_OUT;
1150 }
1151
1152 if (currentTime >= mInputTargetWaitTimeoutTime) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001153 onANRLocked(currentTime, applicationHandle, windowHandle, entry->eventTime,
1154 mInputTargetWaitStartTime, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155
1156 // Force poll loop to wake up immediately on next iteration once we get the
1157 // ANR response back from the policy.
1158 *nextWakeupTime = LONG_LONG_MIN;
1159 return INPUT_EVENT_INJECTION_PENDING;
1160 } else {
1161 // Force poll loop to wake up when timeout is due.
1162 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1163 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1164 }
1165 return INPUT_EVENT_INJECTION_PENDING;
1166 }
1167}
1168
Robert Carr803535b2018-08-02 16:38:15 -07001169void InputDispatcher::removeWindowByTokenLocked(const sp<IBinder>& token) {
1170 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
1171 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
1172 state.removeWindowByToken(token);
1173 }
1174}
1175
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001176void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(
1177 nsecs_t newTimeout, const sp<InputChannel>& inputChannel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178 if (newTimeout > 0) {
1179 // Extend the timeout.
1180 mInputTargetWaitTimeoutTime = now() + newTimeout;
1181 } else {
1182 // Give up.
1183 mInputTargetWaitTimeoutExpired = true;
1184
1185 // Input state will not be realistic. Mark it out of sync.
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001186 sp<Connection> connection = getConnectionLocked(inputChannel);
1187 if (connection != nullptr) {
1188 sp<IBinder> token = connection->inputChannel->getToken();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001190 if (token != nullptr) {
1191 removeWindowByTokenLocked(token);
1192 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001193
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001194 if (connection->status == Connection::STATUS_NORMAL) {
1195 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1196 "application not responding");
1197 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198 }
1199 }
1200 }
1201}
1202
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001203nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1205 return currentTime - mInputTargetWaitStartTime;
1206 }
1207 return 0;
1208}
1209
1210void InputDispatcher::resetANRTimeoutsLocked() {
1211#if DEBUG_FOCUS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001212 ALOGD("Resetting ANR timeouts.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213#endif
1214
1215 // Reset input target wait timeout.
1216 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Robert Carr740167f2018-10-11 19:03:41 -07001217 mInputTargetWaitApplicationToken.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001218}
1219
Tiger Huang721e26f2018-07-24 22:26:19 +08001220/**
1221 * Get the display id that the given event should go to. If this event specifies a valid display id,
1222 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1223 * Focused display is the display that the user most recently interacted with.
1224 */
1225int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) {
1226 int32_t displayId;
1227 switch (entry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001228 case EventEntry::TYPE_KEY: {
1229 const KeyEntry* typedEntry = static_cast<const KeyEntry*>(entry);
1230 displayId = typedEntry->displayId;
1231 break;
1232 }
1233 case EventEntry::TYPE_MOTION: {
1234 const MotionEntry* typedEntry = static_cast<const MotionEntry*>(entry);
1235 displayId = typedEntry->displayId;
1236 break;
1237 }
1238 default: {
1239 ALOGE("Unsupported event type '%" PRId32 "' for target display.", entry->type);
1240 return ADISPLAY_ID_NONE;
1241 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001242 }
1243 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1244}
1245
Michael Wrightd02c5b62014-02-10 15:10:22 -08001246int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001247 const EventEntry* entry,
1248 std::vector<InputTarget>& inputTargets,
1249 nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 int32_t injectionResult;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001251 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252
Tiger Huang721e26f2018-07-24 22:26:19 +08001253 int32_t displayId = getTargetDisplayId(entry);
1254 sp<InputWindowHandle> focusedWindowHandle =
1255 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1256 sp<InputApplicationHandle> focusedApplicationHandle =
1257 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1258
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 // If there is no currently focused window and no focused application
1260 // then drop the event.
Tiger Huang721e26f2018-07-24 22:26:19 +08001261 if (focusedWindowHandle == nullptr) {
1262 if (focusedApplicationHandle != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001263 injectionResult =
1264 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1265 nullptr, nextWakeupTime,
1266 "Waiting because no window has focus but there is "
1267 "a focused application that may eventually add a "
1268 "window when it finishes starting up.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001269 goto Unresponsive;
1270 }
1271
Arthur Hung3b413f22018-10-26 18:05:34 +08001272 ALOGI("Dropping event because there is no focused window or focused application in display "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001273 "%" PRId32 ".",
1274 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001275 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1276 goto Failed;
1277 }
1278
1279 // Check permissions.
Tiger Huang721e26f2018-07-24 22:26:19 +08001280 if (!checkInjectionPermission(focusedWindowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1282 goto Failed;
1283 }
1284
Jeff Brownffb49772014-10-10 19:01:34 -07001285 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001286 reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001287 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001288 injectionResult =
1289 handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle,
1290 focusedWindowHandle, nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001291 goto Unresponsive;
1292 }
1293
1294 // Success! Output targets.
1295 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Tiger Huang721e26f2018-07-24 22:26:19 +08001296 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001297 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1298 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001299
1300 // Done.
1301Failed:
1302Unresponsive:
1303 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001304 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001305#if DEBUG_FOCUS
1306 ALOGD("findFocusedWindow finished: injectionResult=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001307 "timeSpentWaitingForApplication=%0.1fms",
1308 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001309#endif
1310 return injectionResult;
1311}
1312
1313int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001314 const MotionEntry* entry,
1315 std::vector<InputTarget>& inputTargets,
1316 nsecs_t* nextWakeupTime,
1317 bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001318 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001319 enum InjectionPermission {
1320 INJECTION_PERMISSION_UNKNOWN,
1321 INJECTION_PERMISSION_GRANTED,
1322 INJECTION_PERMISSION_DENIED
1323 };
1324
Michael Wrightd02c5b62014-02-10 15:10:22 -08001325 // For security reasons, we defer updating the touch state until we are sure that
1326 // event injection will be allowed.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327 int32_t displayId = entry->displayId;
1328 int32_t action = entry->action;
1329 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1330
1331 // Update the touch state as needed based on the properties of the touch event.
1332 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1333 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1334 sp<InputWindowHandle> newHoverWindowHandle;
1335
Jeff Brownf086ddb2014-02-11 14:28:48 -08001336 // Copy current touch state into mTempTouchState.
1337 // This state is always reset at the end of this function, so if we don't find state
1338 // for the specified display then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001339 const TouchState* oldState = nullptr;
Jeff Brownf086ddb2014-02-11 14:28:48 -08001340 ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
1341 if (oldStateIndex >= 0) {
1342 oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
1343 mTempTouchState.copyFrom(*oldState);
1344 }
1345
1346 bool isSplit = mTempTouchState.split;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001347 bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 &&
1348 (mTempTouchState.deviceId != entry->deviceId ||
1349 mTempTouchState.source != entry->source || mTempTouchState.displayId != displayId);
1350 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1351 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1352 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1353 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1354 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Garfield Tan00f511d2019-06-12 16:55:40 -07001355 const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001356 bool wrongDevice = false;
1357 if (newGesture) {
1358 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001359 if (switchedDevice && mTempTouchState.down && !down && !isHoverAction) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001360#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001361 ALOGD("Dropping event because a pointer for a different device is already down "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001362 "in display %" PRId32,
1363 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001364#endif
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001365 // TODO: test multiple simultaneous input streams.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001366 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1367 switchedDevice = false;
1368 wrongDevice = true;
1369 goto Failed;
1370 }
1371 mTempTouchState.reset();
1372 mTempTouchState.down = down;
1373 mTempTouchState.deviceId = entry->deviceId;
1374 mTempTouchState.source = entry->source;
1375 mTempTouchState.displayId = displayId;
1376 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001377 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
1378#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001379 ALOGI("Dropping move event because a pointer for a different device is already active "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001380 "in display %" PRId32,
1381 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001382#endif
1383 // TODO: test multiple simultaneous input streams.
1384 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1385 switchedDevice = false;
1386 wrongDevice = true;
1387 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001388 }
1389
1390 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1391 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1392
Garfield Tan00f511d2019-06-12 16:55:40 -07001393 int32_t x;
1394 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001396 // Always dispatch mouse events to cursor position.
1397 if (isFromMouse) {
1398 x = int32_t(entry->xCursorPosition);
1399 y = int32_t(entry->yCursorPosition);
1400 } else {
1401 x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1402 y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
1403 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001404 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001405 sp<InputWindowHandle> newTouchedWindowHandle =
1406 findTouchedWindowAtLocked(displayId, x, y, isDown /*addOutsideTargets*/,
1407 true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001408
1409 std::vector<TouchedMonitor> newGestureMonitors = isDown
1410 ? findTouchedGestureMonitorsLocked(displayId, mTempTouchState.portalWindows)
1411 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001412
Michael Wrightd02c5b62014-02-10 15:10:22 -08001413 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001414 if (newTouchedWindowHandle != nullptr &&
1415 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001416 // New window supports splitting, but we should never split mouse events.
1417 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001418 } else if (isSplit) {
1419 // New window does not support splitting but we have already split events.
1420 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001421 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001422 }
1423
1424 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001425 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001426 // Try to assign the pointer to the first foreground window we find, if there is one.
1427 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001428 }
1429
1430 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1431 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001432 "(%d, %d) in display %" PRId32 ".",
1433 x, y, displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00001434 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1435 goto Failed;
1436 }
1437
1438 if (newTouchedWindowHandle != nullptr) {
1439 // Set target flags.
1440 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1441 if (isSplit) {
1442 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001443 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001444 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1445 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1446 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1447 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1448 }
1449
1450 // Update hover state.
1451 if (isHoverAction) {
1452 newHoverWindowHandle = newTouchedWindowHandle;
1453 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1454 newHoverWindowHandle = mLastHoverWindowHandle;
1455 }
1456
1457 // Update the temporary touch state.
1458 BitSet32 pointerIds;
1459 if (isSplit) {
1460 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1461 pointerIds.markBit(pointerId);
1462 }
1463 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001464 }
1465
Michael Wright3dd60e22019-03-27 22:06:44 +00001466 mTempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001467 } else {
1468 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1469
1470 // If the pointer is not currently down, then ignore the event.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001471 if (!mTempTouchState.down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001472#if DEBUG_FOCUS
1473 ALOGD("Dropping event because the pointer is not down or we previously "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001474 "dropped the pointer down event in display %" PRId32,
1475 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476#endif
1477 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1478 goto Failed;
1479 }
1480
1481 // Check whether touches should slip outside of the current foreground window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001482 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry->pointerCount == 1 &&
1483 mTempTouchState.isSlippery()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001484 int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1485 int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1486
1487 sp<InputWindowHandle> oldTouchedWindowHandle =
1488 mTempTouchState.getFirstForegroundWindowHandle();
1489 sp<InputWindowHandle> newTouchedWindowHandle =
1490 findTouchedWindowAtLocked(displayId, x, y);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001491 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
1492 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08001494 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001495 oldTouchedWindowHandle->getName().c_str(),
1496 newTouchedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001497#endif
1498 // Make a slippery exit from the old window.
1499 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001500 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
1501 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502
1503 // Make a slippery entrance into the new window.
1504 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1505 isSplit = true;
1506 }
1507
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001508 int32_t targetFlags =
1509 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001510 if (isSplit) {
1511 targetFlags |= InputTarget::FLAG_SPLIT;
1512 }
1513 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1514 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1515 }
1516
1517 BitSet32 pointerIds;
1518 if (isSplit) {
1519 pointerIds.markBit(entry->pointerProperties[0].id);
1520 }
1521 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1522 }
1523 }
1524 }
1525
1526 if (newHoverWindowHandle != mLastHoverWindowHandle) {
1527 // Let the previous window know that the hover sequence is over.
Yi Kong9b14ac62018-07-17 13:48:38 -07001528 if (mLastHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001529#if DEBUG_HOVER
1530 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001531 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001532#endif
1533 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001534 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT,
1535 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536 }
1537
1538 // Let the new window know that the hover sequence is starting.
Yi Kong9b14ac62018-07-17 13:48:38 -07001539 if (newHoverWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001540#if DEBUG_HOVER
1541 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001542 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001543#endif
1544 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001545 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
1546 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001547 }
1548 }
1549
1550 // Check permission to inject into all touched foreground windows and ensure there
1551 // is at least one touched foreground window.
1552 {
1553 bool haveForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001554 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001555 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1556 haveForegroundWindow = true;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001557 if (!checkInjectionPermission(touchedWindow.windowHandle, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1559 injectionPermission = INJECTION_PERMISSION_DENIED;
1560 goto Failed;
1561 }
1562 }
1563 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001564 bool hasGestureMonitor = !mTempTouchState.gestureMonitors.empty();
1565 if (!haveForegroundWindow && !hasGestureMonitor) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001566#if DEBUG_FOCUS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001567 ALOGD("Dropping event because there is no touched foreground window in display %" PRId32
1568 " or gesture monitor to receive it.",
1569 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001570#endif
1571 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1572 goto Failed;
1573 }
1574
1575 // Permission granted to injection into all touched foreground windows.
1576 injectionPermission = INJECTION_PERMISSION_GRANTED;
1577 }
1578
1579 // Check whether windows listening for outside touches are owned by the same UID. If it is
1580 // set the policy flag that we will not reveal coordinate information to this window.
1581 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1582 sp<InputWindowHandle> foregroundWindowHandle =
1583 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001584 if (foregroundWindowHandle) {
1585 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1586 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
1587 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1588 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1589 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1590 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001591 InputTarget::FLAG_ZERO_COORDS,
1592 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00001593 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001594 }
1595 }
1596 }
1597 }
1598
1599 // Ensure all touched foreground windows are ready for new input.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001600 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brownffb49772014-10-10 19:01:34 -07001602 // Check whether the window is ready for more input.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001603 std::string reason =
1604 checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle,
1605 entry, "touched");
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001606 if (!reason.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001607 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr,
1608 touchedWindow.windowHandle,
1609 nextWakeupTime, reason.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610 goto Unresponsive;
1611 }
1612 }
1613 }
1614
1615 // If this is the first pointer going down and the touched window has a wallpaper
1616 // then also add the touched wallpaper windows so they are locked in for the duration
1617 // of the touch gesture.
1618 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1619 // engine only supports touch events. We would need to add a mechanism similar
1620 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1621 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1622 sp<InputWindowHandle> foregroundWindowHandle =
1623 mTempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001624 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001625 const std::vector<sp<InputWindowHandle>> windowHandles =
1626 getWindowHandlesLocked(displayId);
1627 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001628 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001629 if (info->displayId == displayId &&
1630 windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) {
1631 mTempTouchState
1632 .addOrUpdateWindow(windowHandle,
1633 InputTarget::FLAG_WINDOW_IS_OBSCURED |
1634 InputTarget::
1635 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
1636 InputTarget::FLAG_DISPATCH_AS_IS,
1637 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001638 }
1639 }
1640 }
1641 }
1642
1643 // Success! Output targets.
1644 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1645
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001646 for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001647 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001648 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001649 }
1650
Michael Wright3dd60e22019-03-27 22:06:44 +00001651 for (const TouchedMonitor& touchedMonitor : mTempTouchState.gestureMonitors) {
1652 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001653 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00001654 }
1655
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656 // Drop the outside or hover touch windows since we will not care about them
1657 // in the next iteration.
1658 mTempTouchState.filterNonAsIsTouchWindows();
1659
1660Failed:
1661 // Check injection permission once and for all.
1662 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001663 if (checkInjectionPermission(nullptr, entry->injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001664 injectionPermission = INJECTION_PERMISSION_GRANTED;
1665 } else {
1666 injectionPermission = INJECTION_PERMISSION_DENIED;
1667 }
1668 }
1669
1670 // Update final pieces of touch state if the injector had permission.
1671 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1672 if (!wrongDevice) {
1673 if (switchedDevice) {
1674#if DEBUG_FOCUS
1675 ALOGD("Conflicting pointer actions: Switched to a different device.");
1676#endif
1677 *outConflictingPointerActions = true;
1678 }
1679
1680 if (isHoverAction) {
1681 // Started hovering, therefore no longer down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001682 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683#if DEBUG_FOCUS
1684 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1685#endif
1686 *outConflictingPointerActions = true;
1687 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001688 mTempTouchState.reset();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001689 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1690 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08001691 mTempTouchState.deviceId = entry->deviceId;
1692 mTempTouchState.source = entry->source;
1693 mTempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001694 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001695 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
1696 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001697 // All pointers up or canceled.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001698 mTempTouchState.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001699 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1700 // First pointer went down.
Jeff Brownf086ddb2014-02-11 14:28:48 -08001701 if (oldState && oldState->down) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001702#if DEBUG_FOCUS
1703 ALOGD("Conflicting pointer actions: Down received while already down.");
1704#endif
1705 *outConflictingPointerActions = true;
1706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001707 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1708 // One pointer went up.
1709 if (isSplit) {
1710 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1711 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1712
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001713 for (size_t i = 0; i < mTempTouchState.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001714 TouchedWindow& touchedWindow = mTempTouchState.windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08001715 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1716 touchedWindow.pointerIds.clearBit(pointerId);
1717 if (touchedWindow.pointerIds.isEmpty()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001718 mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001719 continue;
1720 }
1721 }
1722 i += 1;
1723 }
1724 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08001725 }
1726
1727 // Save changes unless the action was scroll in which case the temporary touch
1728 // state was only valid for this one action.
1729 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
1730 if (mTempTouchState.displayId >= 0) {
1731 if (oldStateIndex >= 0) {
1732 mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
1733 } else {
1734 mTouchStatesByDisplay.add(displayId, mTempTouchState);
1735 }
1736 } else if (oldStateIndex >= 0) {
1737 mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
1738 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 }
1740
1741 // Update hover state.
1742 mLastHoverWindowHandle = newHoverWindowHandle;
1743 }
1744 } else {
1745#if DEBUG_FOCUS
1746 ALOGD("Not updating touch focus because injection was denied.");
1747#endif
1748 }
1749
1750Unresponsive:
1751 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1752 mTempTouchState.reset();
1753
1754 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001755 updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001756#if DEBUG_FOCUS
1757 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001758 "timeSpentWaitingForApplication=%0.1fms",
1759 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001760#endif
1761 return injectionResult;
1762}
1763
1764void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001765 int32_t targetFlags, BitSet32 pointerIds,
1766 std::vector<InputTarget>& inputTargets) {
Arthur Hungceeb5d72018-12-05 16:14:18 +08001767 sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
1768 if (inputChannel == nullptr) {
1769 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
1770 return;
1771 }
1772
Michael Wrightd02c5b62014-02-10 15:10:22 -08001773 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001774 InputTarget target;
Arthur Hungceeb5d72018-12-05 16:14:18 +08001775 target.inputChannel = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001776 target.flags = targetFlags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001777 target.xOffset = -windowInfo->frameLeft;
1778 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08001779 target.globalScaleFactor = windowInfo->globalScaleFactor;
1780 target.windowXScale = windowInfo->windowXScale;
1781 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001782 target.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001783 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784}
1785
Michael Wright3dd60e22019-03-27 22:06:44 +00001786void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001787 int32_t displayId, float xOffset,
1788 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001789 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
1790 mGlobalMonitorsByDisplay.find(displayId);
1791
1792 if (it != mGlobalMonitorsByDisplay.end()) {
1793 const std::vector<Monitor>& monitors = it->second;
1794 for (const Monitor& monitor : monitors) {
1795 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001796 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001797 }
1798}
1799
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001800void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
1801 float yOffset,
1802 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001803 InputTarget target;
1804 target.inputChannel = monitor.inputChannel;
1805 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1806 target.xOffset = xOffset;
1807 target.yOffset = yOffset;
1808 target.pointerIds.clear();
1809 target.globalScaleFactor = 1.0f;
1810 inputTargets.push_back(target);
1811}
1812
Michael Wrightd02c5b62014-02-10 15:10:22 -08001813bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001814 const InjectionState* injectionState) {
1815 if (injectionState &&
1816 (windowHandle == nullptr ||
1817 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
1818 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001819 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001821 "owned by uid %d",
1822 injectionState->injectorPid, injectionState->injectorUid,
1823 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001824 } else {
1825 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001826 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001827 }
1828 return false;
1829 }
1830 return true;
1831}
1832
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001833bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
1834 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001835 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001836 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
1837 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001838 if (otherHandle == windowHandle) {
1839 break;
1840 }
1841
1842 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001843 if (otherInfo->displayId == displayId && otherInfo->visible &&
1844 !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001845 return true;
1846 }
1847 }
1848 return false;
1849}
1850
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001851bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
1852 int32_t displayId = windowHandle->getInfo()->displayId;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001853 const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001854 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001855 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001856 if (otherHandle == windowHandle) {
1857 break;
1858 }
1859
1860 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001861 if (otherInfo->displayId == displayId && otherInfo->visible &&
1862 !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07001863 return true;
1864 }
1865 }
1866 return false;
1867}
1868
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001869std::string InputDispatcher::checkWindowReadyForMoreInputLocked(
1870 nsecs_t currentTime, const sp<InputWindowHandle>& windowHandle,
1871 const EventEntry* eventEntry, const char* targetType) {
Jeff Brownffb49772014-10-10 19:01:34 -07001872 // If the window is paused then keep waiting.
1873 if (windowHandle->getInfo()->paused) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001874 return StringPrintf("Waiting because the %s window is paused.", targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001875 }
1876
1877 // If the window's connection is not registered then keep waiting.
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001878 sp<Connection> connection =
1879 getConnectionLocked(getInputChannelLocked(windowHandle->getToken()));
1880 if (connection == nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001881 return StringPrintf("Waiting because the %s window's input channel is not "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001882 "registered with the input dispatcher. The window may be in the "
1883 "process of being removed.",
1884 targetType);
Jeff Brownffb49772014-10-10 19:01:34 -07001885 }
1886
1887 // If the connection is dead then keep waiting.
Jeff Brownffb49772014-10-10 19:01:34 -07001888 if (connection->status != Connection::STATUS_NORMAL) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001889 return StringPrintf("Waiting because the %s window's input connection is %s."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001890 "The window may be in the process of being removed.",
1891 targetType, connection->getStatusLabel());
Jeff Brownffb49772014-10-10 19:01:34 -07001892 }
1893
1894 // If the connection is backed up then keep waiting.
1895 if (connection->inputPublisherBlocked) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001896 return StringPrintf("Waiting because the %s window's input channel is full. "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001897 "Outbound queue length: %zu. Wait queue length: %zu.",
1898 targetType, connection->outboundQueue.size(),
1899 connection->waitQueue.size());
Jeff Brownffb49772014-10-10 19:01:34 -07001900 }
1901
1902 // Ensure that the dispatch queues aren't too far backed up for this event.
1903 if (eventEntry->type == EventEntry::TYPE_KEY) {
1904 // If the event is a key event, then we must wait for all previous events to
1905 // complete before delivering it because previous events may have the
1906 // side-effect of transferring focus to a different window and we want to
1907 // ensure that the following keys are sent to the new window.
1908 //
1909 // Suppose the user touches a button in a window then immediately presses "A".
1910 // If the button causes a pop-up window to appear then we want to ensure that
1911 // the "A" key is delivered to the new pop-up window. This is because users
1912 // often anticipate pending UI changes when typing on a keyboard.
1913 // To obtain this behavior, we must serialize key events with respect to all
1914 // prior input events.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001915 if (!connection->outboundQueue.empty() || !connection->waitQueue.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001916 return StringPrintf("Waiting to send key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001917 "finished processing all of the input events that were previously "
1918 "delivered to it. Outbound queue length: %zu. Wait queue length: "
1919 "%zu.",
1920 targetType, connection->outboundQueue.size(),
1921 connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001922 }
Jeff Brownffb49772014-10-10 19:01:34 -07001923 } else {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 // Touch events can always be sent to a window immediately because the user intended
1925 // to touch whatever was visible at the time. Even if focus changes or a new
1926 // window appears moments later, the touch event was meant to be delivered to
1927 // whatever window happened to be on screen at the time.
1928 //
1929 // Generic motion events, such as trackball or joystick events are a little trickier.
1930 // Like key events, generic motion events are delivered to the focused window.
1931 // Unlike key events, generic motion events don't tend to transfer focus to other
1932 // windows and it is not important for them to be serialized. So we prefer to deliver
1933 // generic motion events as soon as possible to improve efficiency and reduce lag
1934 // through batching.
1935 //
1936 // The one case where we pause input event delivery is when the wait queue is piling
1937 // up with lots of events because the application is not responding.
1938 // This condition ensures that ANRs are detected reliably.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001939 if (!connection->waitQueue.empty() &&
1940 currentTime >=
1941 connection->waitQueue.front()->deliveryTime + STREAM_AHEAD_EVENT_TIMEOUT) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001942 return StringPrintf("Waiting to send non-key event because the %s window has not "
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07001943 "finished processing certain input events that were delivered to "
1944 "it over "
1945 "%0.1fms ago. Wait queue length: %zu. Wait queue head age: "
1946 "%0.1fms.",
1947 targetType, STREAM_AHEAD_EVENT_TIMEOUT * 0.000001f,
1948 connection->waitQueue.size(),
1949 (currentTime - connection->waitQueue.front()->deliveryTime) *
1950 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001951 }
1952 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001953 return "";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001954}
1955
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001956std::string InputDispatcher::getApplicationWindowLabel(
Michael Wrightd02c5b62014-02-10 15:10:22 -08001957 const sp<InputApplicationHandle>& applicationHandle,
1958 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001959 if (applicationHandle != nullptr) {
1960 if (windowHandle != nullptr) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001961 std::string label(applicationHandle->getName());
1962 label += " - ";
1963 label += windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001964 return label;
1965 } else {
1966 return applicationHandle->getName();
1967 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001968 } else if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001969 return windowHandle->getName();
1970 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001971 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08001972 }
1973}
1974
1975void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001976 int32_t displayId = getTargetDisplayId(eventEntry);
1977 sp<InputWindowHandle> focusedWindowHandle =
1978 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
1979 if (focusedWindowHandle != nullptr) {
1980 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981 if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
1982#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001983 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001984#endif
1985 return;
1986 }
1987 }
1988
1989 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
1990 switch (eventEntry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001991 case EventEntry::TYPE_MOTION: {
1992 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1993 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1994 return;
1995 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001996
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001997 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1998 eventType = USER_ACTIVITY_EVENT_TOUCH;
1999 }
2000 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002002 case EventEntry::TYPE_KEY: {
2003 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
2004 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
2005 return;
2006 }
2007 eventType = USER_ACTIVITY_EVENT_BUTTON;
2008 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002010 }
2011
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002012 std::unique_ptr<CommandEntry> commandEntry =
2013 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014 commandEntry->eventTime = eventEntry->eventTime;
2015 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002016 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002017}
2018
2019void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002020 const sp<Connection>& connection,
2021 EventEntry* eventEntry,
2022 const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002023 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002024 std::string message =
2025 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
2026 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002027 ATRACE_NAME(message.c_str());
2028 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002029#if DEBUG_DISPATCH_CYCLE
2030 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002031 "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
2032 "windowScaleFactor=(%f, %f), pointerIds=0x%x",
2033 connection->getInputChannelName().c_str(), inputTarget->flags, inputTarget->xOffset,
2034 inputTarget->yOffset, inputTarget->globalScaleFactor, inputTarget->windowXScale,
2035 inputTarget->windowYScale, inputTarget->pointerIds.value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002036#endif
2037
2038 // Skip this event if the connection status is not normal.
2039 // We don't want to enqueue additional outbound events if the connection is broken.
2040 if (connection->status != Connection::STATUS_NORMAL) {
2041#if DEBUG_DISPATCH_CYCLE
2042 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002043 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002044#endif
2045 return;
2046 }
2047
2048 // Split a motion event if needed.
2049 if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
2050 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
2051
2052 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
2053 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002054 MotionEntry* splitMotionEntry =
2055 splitMotionEvent(originalMotionEntry, inputTarget->pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 if (!splitMotionEntry) {
2057 return; // split event was dropped
2058 }
2059#if DEBUG_FOCUS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002060 ALOGD("channel '%s' ~ Split motion event.", connection->getInputChannelName().c_str());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002061 logOutboundMotionDetails(" ", splitMotionEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002062#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002063 enqueueDispatchEntriesLocked(currentTime, connection, splitMotionEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002064 splitMotionEntry->release();
2065 return;
2066 }
2067 }
2068
2069 // Not splitting. Enqueue dispatch entries for the event as is.
2070 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2071}
2072
2073void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002074 const sp<Connection>& connection,
2075 EventEntry* eventEntry,
2076 const InputTarget* inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002077 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002078 std::string message =
2079 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
2080 ")",
2081 connection->getInputChannelName().c_str(), eventEntry->sequenceNum);
Michael Wright3dd60e22019-03-27 22:06:44 +00002082 ATRACE_NAME(message.c_str());
2083 }
2084
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002085 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086
2087 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002088 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002089 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002090 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002091 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002092 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002093 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002094 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002095 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002096 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002097 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002098 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002099 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100
2101 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002102 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103 startDispatchCycleLocked(currentTime, connection);
2104 }
2105}
2106
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002107void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
2108 EventEntry* eventEntry,
2109 const InputTarget* inputTarget,
2110 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002111 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002112 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2113 connection->getInputChannelName().c_str(),
2114 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002115 ATRACE_NAME(message.c_str());
2116 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002117 int32_t inputTargetFlags = inputTarget->flags;
2118 if (!(inputTargetFlags & dispatchMode)) {
2119 return;
2120 }
2121 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2122
2123 // This is a new event.
2124 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002125 DispatchEntry* dispatchEntry =
2126 new DispatchEntry(eventEntry, // increments ref
2127 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
2128 inputTarget->globalScaleFactor, inputTarget->windowXScale,
2129 inputTarget->windowYScale);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002130
2131 // Apply target flags and update the connection's input state.
2132 switch (eventEntry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002133 case EventEntry::TYPE_KEY: {
2134 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2135 dispatchEntry->resolvedAction = keyEntry->action;
2136 dispatchEntry->resolvedFlags = keyEntry->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002137
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002138 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2139 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002141 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2142 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002143#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002144 delete dispatchEntry;
2145 return; // skip the inconsistent event
2146 }
2147 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002148 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002150 case EventEntry::TYPE_MOTION: {
2151 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2152 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2153 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2154 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2155 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2156 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2157 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2158 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2159 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2160 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2161 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2162 } else {
2163 dispatchEntry->resolvedAction = motionEntry->action;
2164 }
2165 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
2166 !connection->inputState.isHovering(motionEntry->deviceId, motionEntry->source,
2167 motionEntry->displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002169 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2170 "event",
2171 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002172#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002173 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2174 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002176 dispatchEntry->resolvedFlags = motionEntry->flags;
2177 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2178 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2179 }
2180 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2181 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2182 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002184 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2185 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002186#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002187 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2188 "event",
2189 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002190#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002191 delete dispatchEntry;
2192 return; // skip the inconsistent event
2193 }
2194
2195 dispatchPointerDownOutsideFocus(motionEntry->source, dispatchEntry->resolvedAction,
2196 inputTarget->inputChannel->getToken());
2197
2198 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002199 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200 }
2201
2202 // Remember that we are waiting for this dispatch to complete.
2203 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002204 incrementPendingForegroundDispatches(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002205 }
2206
2207 // Enqueue the dispatch entry.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002208 connection->outboundQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002209 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002210}
2211
chaviwfd6d3512019-03-25 13:23:49 -07002212void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002213 const sp<IBinder>& newToken) {
chaviw8c9cf542019-03-25 13:02:48 -07002214 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002215 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2216 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002217 return;
2218 }
2219
2220 sp<InputWindowHandle> inputWindowHandle = getWindowHandleLocked(newToken);
2221 if (inputWindowHandle == nullptr) {
2222 return;
2223 }
2224
chaviw8c9cf542019-03-25 13:02:48 -07002225 sp<InputWindowHandle> focusedWindowHandle =
Tiger Huang0683fe72019-06-03 21:50:55 +08002226 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
chaviw8c9cf542019-03-25 13:02:48 -07002227
2228 bool hasFocusChanged = !focusedWindowHandle || focusedWindowHandle->getToken() != newToken;
2229
2230 if (!hasFocusChanged) {
2231 return;
2232 }
2233
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002234 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2235 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
chaviwfd6d3512019-03-25 13:23:49 -07002236 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002237 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002238}
2239
2240void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002241 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002242 if (ATRACE_ENABLED()) {
2243 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002244 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002245 ATRACE_NAME(message.c_str());
2246 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002248 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002249#endif
2250
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002251 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2252 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253 dispatchEntry->deliveryTime = currentTime;
2254
2255 // Publish the event.
2256 status_t status;
2257 EventEntry* eventEntry = dispatchEntry->eventEntry;
2258 switch (eventEntry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002259 case EventEntry::TYPE_KEY: {
2260 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002261
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002262 // Publish the key event.
2263 status = connection->inputPublisher
2264 .publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId,
2265 keyEntry->source, keyEntry->displayId,
2266 dispatchEntry->resolvedAction,
2267 dispatchEntry->resolvedFlags, keyEntry->keyCode,
2268 keyEntry->scanCode, keyEntry->metaState,
2269 keyEntry->repeatCount, keyEntry->downTime,
2270 keyEntry->eventTime);
2271 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272 }
2273
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002274 case EventEntry::TYPE_MOTION: {
2275 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002276
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002277 PointerCoords scaledCoords[MAX_POINTERS];
2278 const PointerCoords* usingCoords = motionEntry->pointerCoords;
2279
2280 // Set the X and Y offset depending on the input source.
2281 float xOffset, yOffset;
2282 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) &&
2283 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2284 float globalScaleFactor = dispatchEntry->globalScaleFactor;
2285 float wxs = dispatchEntry->windowXScale;
2286 float wys = dispatchEntry->windowYScale;
2287 xOffset = dispatchEntry->xOffset * wxs;
2288 yOffset = dispatchEntry->yOffset * wys;
2289 if (wxs != 1.0f || wys != 1.0f || globalScaleFactor != 1.0f) {
2290 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2291 scaledCoords[i] = motionEntry->pointerCoords[i];
2292 scaledCoords[i].scale(globalScaleFactor, wxs, wys);
2293 }
2294 usingCoords = scaledCoords;
2295 }
2296 } else {
2297 xOffset = 0.0f;
2298 yOffset = 0.0f;
2299
2300 // We don't want the dispatch target to know.
2301 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2302 for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
2303 scaledCoords[i].clear();
2304 }
2305 usingCoords = scaledCoords;
2306 }
2307 }
2308
2309 // Publish the motion event.
2310 status = connection->inputPublisher
2311 .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
2312 motionEntry->source, motionEntry->displayId,
2313 dispatchEntry->resolvedAction,
2314 motionEntry->actionButton,
2315 dispatchEntry->resolvedFlags,
2316 motionEntry->edgeFlags, motionEntry->metaState,
2317 motionEntry->buttonState,
2318 motionEntry->classification, xOffset, yOffset,
2319 motionEntry->xPrecision,
2320 motionEntry->yPrecision,
2321 motionEntry->xCursorPosition,
2322 motionEntry->yCursorPosition,
2323 motionEntry->downTime, motionEntry->eventTime,
2324 motionEntry->pointerCount,
2325 motionEntry->pointerProperties, usingCoords);
2326 break;
2327 }
2328
2329 default:
2330 ALOG_ASSERT(false);
2331 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002332 }
2333
2334 // Check the result.
2335 if (status) {
2336 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002337 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002339 "This is unexpected because the wait queue is empty, so the pipe "
2340 "should be empty and we shouldn't have any problems writing an "
2341 "event to it, status=%d",
2342 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002343 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2344 } else {
2345 // Pipe is full and we are waiting for the app to finish process some events
2346 // before sending more events to it.
2347#if DEBUG_DISPATCH_CYCLE
2348 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002349 "waiting for the application to catch up",
2350 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002351#endif
2352 connection->inputPublisherBlocked = true;
2353 }
2354 } else {
2355 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002356 "status=%d",
2357 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002358 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2359 }
2360 return;
2361 }
2362
2363 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002364 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
2365 connection->outboundQueue.end(),
2366 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002367 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002368 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002369 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002370 }
2371}
2372
2373void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002374 const sp<Connection>& connection, uint32_t seq,
2375 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002376#if DEBUG_DISPATCH_CYCLE
2377 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002378 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002379#endif
2380
2381 connection->inputPublisherBlocked = false;
2382
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002383 if (connection->status == Connection::STATUS_BROKEN ||
2384 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002385 return;
2386 }
2387
2388 // Notify other system components and prepare to start the next dispatch cycle.
2389 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
2390}
2391
2392void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002393 const sp<Connection>& connection,
2394 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002395#if DEBUG_DISPATCH_CYCLE
2396 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002397 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002398#endif
2399
2400 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002401 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002402 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002403 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002404 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002405
2406 // The connection appears to be unrecoverably broken.
2407 // Ignore already broken or zombie connections.
2408 if (connection->status == Connection::STATUS_NORMAL) {
2409 connection->status = Connection::STATUS_BROKEN;
2410
2411 if (notify) {
2412 // Notify other system components.
2413 onDispatchCycleBrokenLocked(currentTime, connection);
2414 }
2415 }
2416}
2417
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002418void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
2419 while (!queue.empty()) {
2420 DispatchEntry* dispatchEntry = queue.front();
2421 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002422 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002423 }
2424}
2425
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002426void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002427 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08002428 decrementPendingForegroundDispatches(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002429 }
2430 delete dispatchEntry;
2431}
2432
2433int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2434 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2435
2436 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002437 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002438
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002439 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002441 "fd=%d, events=0x%x",
2442 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443 return 0; // remove the callback
2444 }
2445
2446 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002447 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002448 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2449 if (!(events & ALOOPER_EVENT_INPUT)) {
2450 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002451 "events=0x%x",
2452 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453 return 1;
2454 }
2455
2456 nsecs_t currentTime = now();
2457 bool gotOne = false;
2458 status_t status;
2459 for (;;) {
2460 uint32_t seq;
2461 bool handled;
2462 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
2463 if (status) {
2464 break;
2465 }
2466 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
2467 gotOne = true;
2468 }
2469 if (gotOne) {
2470 d->runCommandsLockedInterruptible();
2471 if (status == WOULD_BLOCK) {
2472 return 1;
2473 }
2474 }
2475
2476 notify = status != DEAD_OBJECT || !connection->monitor;
2477 if (notify) {
2478 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002479 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002480 }
2481 } else {
2482 // Monitor channels are never explicitly unregistered.
2483 // We do it automatically when the remote endpoint is closed so don't warn
2484 // about them.
2485 notify = !connection->monitor;
2486 if (notify) {
2487 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002488 "events=0x%x",
2489 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002490 }
2491 }
2492
2493 // Unregister the channel.
2494 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2495 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002496 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497}
2498
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002499void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08002500 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002501 for (const auto& pair : mConnectionsByFd) {
2502 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002503 }
2504}
2505
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002506void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002507 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002508 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
2509 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
2510}
2511
2512void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
2513 const CancelationOptions& options,
2514 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
2515 for (const auto& it : monitorsByDisplay) {
2516 const std::vector<Monitor>& monitors = it.second;
2517 for (const Monitor& monitor : monitors) {
2518 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002519 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01002520 }
2521}
2522
Michael Wrightd02c5b62014-02-10 15:10:22 -08002523void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2524 const sp<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002525 sp<Connection> connection = getConnectionLocked(channel);
2526 if (connection == nullptr) {
2527 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002528 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07002529
2530 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002531}
2532
2533void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2534 const sp<Connection>& connection, const CancelationOptions& options) {
2535 if (connection->status == Connection::STATUS_BROKEN) {
2536 return;
2537 }
2538
2539 nsecs_t currentTime = now();
2540
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002541 std::vector<EventEntry*> cancelationEvents;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002542 connection->inputState.synthesizeCancelationEvents(currentTime, cancelationEvents, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002543
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002544 if (!cancelationEvents.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002546 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002547 "with reality: %s, mode=%d.",
2548 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
2549 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002550#endif
2551 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002552 EventEntry* cancelationEventEntry = cancelationEvents[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08002553 switch (cancelationEventEntry->type) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002554 case EventEntry::TYPE_KEY:
2555 logOutboundKeyDetails("cancel - ",
2556 static_cast<KeyEntry*>(cancelationEventEntry));
2557 break;
2558 case EventEntry::TYPE_MOTION:
2559 logOutboundMotionDetails("cancel - ",
2560 static_cast<MotionEntry*>(cancelationEventEntry));
2561 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002562 }
2563
2564 InputTarget target;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002565 sp<InputWindowHandle> windowHandle =
2566 getWindowHandleLocked(connection->inputChannel->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07002567 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002568 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2569 target.xOffset = -windowInfo->frameLeft;
2570 target.yOffset = -windowInfo->frameTop;
Robert Carre07e1032018-11-26 12:55:53 -08002571 target.globalScaleFactor = windowInfo->globalScaleFactor;
2572 target.windowXScale = windowInfo->windowXScale;
2573 target.windowYScale = windowInfo->windowYScale;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574 } else {
2575 target.xOffset = 0;
2576 target.yOffset = 0;
Robert Carre07e1032018-11-26 12:55:53 -08002577 target.globalScaleFactor = 1.0f;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002578 }
2579 target.inputChannel = connection->inputChannel;
2580 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2581
chaviw8c9cf542019-03-25 13:02:48 -07002582 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002583 &target, InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002584
2585 cancelationEventEntry->release();
2586 }
2587
2588 startDispatchCycleLocked(currentTime, connection);
2589 }
2590}
2591
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002592InputDispatcher::MotionEntry* InputDispatcher::splitMotionEvent(
2593 const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002594 ALOG_ASSERT(pointerIds.value != 0);
2595
2596 uint32_t splitPointerIndexMap[MAX_POINTERS];
2597 PointerProperties splitPointerProperties[MAX_POINTERS];
2598 PointerCoords splitPointerCoords[MAX_POINTERS];
2599
2600 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2601 uint32_t splitPointerCount = 0;
2602
2603 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002604 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002605 const PointerProperties& pointerProperties =
2606 originalMotionEntry->pointerProperties[originalPointerIndex];
2607 uint32_t pointerId = uint32_t(pointerProperties.id);
2608 if (pointerIds.hasBit(pointerId)) {
2609 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2610 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2611 splitPointerCoords[splitPointerCount].copyFrom(
2612 originalMotionEntry->pointerCoords[originalPointerIndex]);
2613 splitPointerCount += 1;
2614 }
2615 }
2616
2617 if (splitPointerCount != pointerIds.count()) {
2618 // This is bad. We are missing some of the pointers that we expected to deliver.
2619 // Most likely this indicates that we received an ACTION_MOVE events that has
2620 // different pointer ids than we expected based on the previous ACTION_DOWN
2621 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2622 // in this way.
2623 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002624 "we expected there to be %d pointers. This probably means we received "
2625 "a broken sequence of pointer ids from the input device.",
2626 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07002627 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002628 }
2629
2630 int32_t action = originalMotionEntry->action;
2631 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002632 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
2633 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002634 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2635 const PointerProperties& pointerProperties =
2636 originalMotionEntry->pointerProperties[originalPointerIndex];
2637 uint32_t pointerId = uint32_t(pointerProperties.id);
2638 if (pointerIds.hasBit(pointerId)) {
2639 if (pointerIds.count() == 1) {
2640 // The first/last pointer went down/up.
2641 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002642 ? AMOTION_EVENT_ACTION_DOWN
2643 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002644 } else {
2645 // A secondary pointer went down/up.
2646 uint32_t splitPointerIndex = 0;
2647 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2648 splitPointerIndex += 1;
2649 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002650 action = maskedAction |
2651 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002652 }
2653 } else {
2654 // An unrelated pointer changed.
2655 action = AMOTION_EVENT_ACTION_MOVE;
2656 }
2657 }
2658
Garfield Tan00f511d2019-06-12 16:55:40 -07002659 MotionEntry* splitMotionEntry =
2660 new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
2661 originalMotionEntry->deviceId, originalMotionEntry->source,
2662 originalMotionEntry->displayId, originalMotionEntry->policyFlags,
2663 action, originalMotionEntry->actionButton, originalMotionEntry->flags,
2664 originalMotionEntry->metaState, originalMotionEntry->buttonState,
2665 originalMotionEntry->classification, originalMotionEntry->edgeFlags,
2666 originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
2667 originalMotionEntry->xCursorPosition,
2668 originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
2669 splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002670
2671 if (originalMotionEntry->injectionState) {
2672 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2673 splitMotionEntry->injectionState->refCount += 1;
2674 }
2675
2676 return splitMotionEntry;
2677}
2678
2679void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2680#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002681 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002682#endif
2683
2684 bool needWake;
2685 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002686 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687
Prabir Pradhan42611e02018-11-27 14:04:02 -08002688 ConfigurationChangedEntry* newEntry =
2689 new ConfigurationChangedEntry(args->sequenceNum, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002690 needWake = enqueueInboundEventLocked(newEntry);
2691 } // release lock
2692
2693 if (needWake) {
2694 mLooper->wake();
2695 }
2696}
2697
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002698/**
2699 * If one of the meta shortcuts is detected, process them here:
2700 * Meta + Backspace -> generate BACK
2701 * Meta + Enter -> generate HOME
2702 * This will potentially overwrite keyCode and metaState.
2703 */
2704void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002705 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002706 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
2707 int32_t newKeyCode = AKEYCODE_UNKNOWN;
2708 if (keyCode == AKEYCODE_DEL) {
2709 newKeyCode = AKEYCODE_BACK;
2710 } else if (keyCode == AKEYCODE_ENTER) {
2711 newKeyCode = AKEYCODE_HOME;
2712 }
2713 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002714 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002715 struct KeyReplacement replacement = {keyCode, deviceId};
2716 mReplacedKeys.add(replacement, newKeyCode);
2717 keyCode = newKeyCode;
2718 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2719 }
2720 } else if (action == AKEY_EVENT_ACTION_UP) {
2721 // In order to maintain a consistent stream of up and down events, check to see if the key
2722 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
2723 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002724 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002725 struct KeyReplacement replacement = {keyCode, deviceId};
2726 ssize_t index = mReplacedKeys.indexOfKey(replacement);
2727 if (index >= 0) {
2728 keyCode = mReplacedKeys.valueAt(index);
2729 mReplacedKeys.removeItemsAt(index);
2730 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
2731 }
2732 }
2733}
2734
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2736#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002737 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
2738 "policyFlags=0x%x, action=0x%x, "
2739 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
2740 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2741 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
2742 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002743#endif
2744 if (!validateKeyEvent(args->action)) {
2745 return;
2746 }
2747
2748 uint32_t policyFlags = args->policyFlags;
2749 int32_t flags = args->flags;
2750 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07002751 // InputDispatcher tracks and generates key repeats on behalf of
2752 // whatever notifies it, so repeatCount should always be set to 0
2753 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2755 policyFlags |= POLICY_FLAG_VIRTUAL;
2756 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002758 if (policyFlags & POLICY_FLAG_FUNCTION) {
2759 metaState |= AMETA_FUNCTION_ON;
2760 }
2761
2762 policyFlags |= POLICY_FLAG_TRUSTED;
2763
Michael Wright78f24442014-08-06 15:55:28 -07002764 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05002765 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07002766
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767 KeyEvent event;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002768 event.initialize(args->deviceId, args->source, args->displayId, args->action, flags, keyCode,
2769 args->scanCode, metaState, repeatCount, args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002770
Michael Wright2b3c3302018-03-02 17:19:13 +00002771 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002772 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002773 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2774 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002775 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002777
Michael Wrightd02c5b62014-02-10 15:10:22 -08002778 bool needWake;
2779 { // acquire lock
2780 mLock.lock();
2781
2782 if (shouldSendKeyToInputFilterLocked(args)) {
2783 mLock.unlock();
2784
2785 policyFlags |= POLICY_FLAG_FILTERED;
2786 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2787 return; // event was consumed by the filter
2788 }
2789
2790 mLock.lock();
2791 }
2792
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002793 KeyEntry* newEntry =
2794 new KeyEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2795 args->displayId, policyFlags, args->action, flags, keyCode,
2796 args->scanCode, metaState, repeatCount, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002797
2798 needWake = enqueueInboundEventLocked(newEntry);
2799 mLock.unlock();
2800 } // release lock
2801
2802 if (needWake) {
2803 mLooper->wake();
2804 }
2805}
2806
2807bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
2808 return mInputFilterEnabled;
2809}
2810
2811void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2812#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08002813 ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07002814 ", policyFlags=0x%x, "
2815 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
2816 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07002817 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan00f511d2019-06-12 16:55:40 -07002818 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
2819 args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
2820 args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
2821 args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002822 for (uint32_t i = 0; i < args->pointerCount; i++) {
2823 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002824 "x=%f, y=%f, pressure=%f, size=%f, "
2825 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2826 "orientation=%f",
2827 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
2828 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2829 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2830 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2831 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2832 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2833 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2834 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2835 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2836 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002837 }
2838#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002839 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
2840 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002841 return;
2842 }
2843
2844 uint32_t policyFlags = args->policyFlags;
2845 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002846
2847 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08002848 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00002849 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2850 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002851 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00002852 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002853
2854 bool needWake;
2855 { // acquire lock
2856 mLock.lock();
2857
2858 if (shouldSendMotionToInputFilterLocked(args)) {
2859 mLock.unlock();
2860
2861 MotionEvent event;
Garfield Tan00f511d2019-06-12 16:55:40 -07002862 event.initialize(args->deviceId, args->source, args->displayId, args->action,
2863 args->actionButton, args->flags, args->edgeFlags, args->metaState,
2864 args->buttonState, args->classification, 0, 0, args->xPrecision,
2865 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2866 args->downTime, args->eventTime, args->pointerCount,
2867 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002868
2869 policyFlags |= POLICY_FLAG_FILTERED;
2870 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2871 return; // event was consumed by the filter
2872 }
2873
2874 mLock.lock();
2875 }
2876
2877 // Just enqueue a new motion event.
Garfield Tan00f511d2019-06-12 16:55:40 -07002878 MotionEntry* newEntry =
2879 new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
2880 args->displayId, policyFlags, args->action, args->actionButton,
2881 args->flags, args->metaState, args->buttonState,
2882 args->classification, args->edgeFlags, args->xPrecision,
2883 args->yPrecision, args->xCursorPosition, args->yCursorPosition,
2884 args->downTime, args->pointerCount, args->pointerProperties,
2885 args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002886
2887 needWake = enqueueInboundEventLocked(newEntry);
2888 mLock.unlock();
2889 } // release lock
2890
2891 if (needWake) {
2892 mLooper->wake();
2893 }
2894}
2895
2896bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08002897 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002898}
2899
2900void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2901#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07002902 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002903 "switchMask=0x%08x",
2904 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002905#endif
2906
2907 uint32_t policyFlags = args->policyFlags;
2908 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002909 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002910}
2911
2912void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2913#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002914 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
2915 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002916#endif
2917
2918 bool needWake;
2919 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08002920 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002921
Prabir Pradhan42611e02018-11-27 14:04:02 -08002922 DeviceResetEntry* newEntry =
2923 new DeviceResetEntry(args->sequenceNum, args->eventTime, args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 needWake = enqueueInboundEventLocked(newEntry);
2925 } // release lock
2926
2927 if (needWake) {
2928 mLooper->wake();
2929 }
2930}
2931
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002932int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
2933 int32_t injectorUid, int32_t syncMode,
2934 int32_t timeoutMillis, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002935#if DEBUG_INBOUND_EVENT_DETAILS
2936 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002937 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2938 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002939#endif
2940
2941 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2942
2943 policyFlags |= POLICY_FLAG_INJECTED;
2944 if (hasInjectionPermission(injectorPid, injectorUid)) {
2945 policyFlags |= POLICY_FLAG_TRUSTED;
2946 }
2947
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07002948 std::queue<EventEntry*> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002949 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002950 case AINPUT_EVENT_TYPE_KEY: {
2951 KeyEvent keyEvent;
2952 keyEvent.initialize(*static_cast<const KeyEvent*>(event));
2953 int32_t action = keyEvent.getAction();
2954 if (!validateKeyEvent(action)) {
2955 return INPUT_EVENT_INJECTION_FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00002956 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002957
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002958 int32_t flags = keyEvent.getFlags();
2959 int32_t keyCode = keyEvent.getKeyCode();
2960 int32_t metaState = keyEvent.getMetaState();
2961 accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
2962 /*byref*/ keyCode, /*byref*/ metaState);
2963 keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(),
2964 keyEvent.getDisplayId(), action, flags, keyCode,
2965 keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(),
2966 keyEvent.getDownTime(), keyEvent.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002968 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2969 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00002970 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002971
2972 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2973 android::base::Timer t;
2974 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
2975 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
2976 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
2977 std::to_string(t.duration().count()).c_str());
2978 }
2979 }
2980
2981 mLock.lock();
2982 KeyEntry* injectedEntry =
2983 new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(),
2984 keyEvent.getDeviceId(), keyEvent.getSource(),
2985 keyEvent.getDisplayId(), policyFlags, action, flags,
2986 keyEvent.getKeyCode(), keyEvent.getScanCode(),
2987 keyEvent.getMetaState(), keyEvent.getRepeatCount(),
2988 keyEvent.getDownTime());
2989 injectedEntries.push(injectedEntry);
2990 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002991 }
2992
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002993 case AINPUT_EVENT_TYPE_MOTION: {
2994 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2995 int32_t action = motionEvent->getAction();
2996 size_t pointerCount = motionEvent->getPointerCount();
2997 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
2998 int32_t actionButton = motionEvent->getActionButton();
2999 int32_t displayId = motionEvent->getDisplayId();
3000 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
3001 return INPUT_EVENT_INJECTION_FAILED;
3002 }
3003
3004 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3005 nsecs_t eventTime = motionEvent->getEventTime();
3006 android::base::Timer t;
3007 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3008 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3009 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3010 std::to_string(t.duration().count()).c_str());
3011 }
3012 }
3013
3014 mLock.lock();
3015 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3016 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3017 MotionEntry* injectedEntry =
Garfield Tan00f511d2019-06-12 16:55:40 -07003018 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3019 motionEvent->getDeviceId(), motionEvent->getSource(),
3020 motionEvent->getDisplayId(), policyFlags, action, actionButton,
3021 motionEvent->getFlags(), motionEvent->getMetaState(),
3022 motionEvent->getButtonState(), motionEvent->getClassification(),
3023 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3024 motionEvent->getYPrecision(),
3025 motionEvent->getRawXCursorPosition(),
3026 motionEvent->getRawYCursorPosition(),
3027 motionEvent->getDownTime(), uint32_t(pointerCount),
3028 pointerProperties, samplePointerCoords,
3029 motionEvent->getXOffset(), motionEvent->getYOffset());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003030 injectedEntries.push(injectedEntry);
3031 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3032 sampleEventTimes += 1;
3033 samplePointerCoords += pointerCount;
3034 MotionEntry* nextInjectedEntry =
3035 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
3036 motionEvent->getDeviceId(), motionEvent->getSource(),
3037 motionEvent->getDisplayId(), policyFlags, action,
3038 actionButton, motionEvent->getFlags(),
3039 motionEvent->getMetaState(), motionEvent->getButtonState(),
3040 motionEvent->getClassification(),
3041 motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
3042 motionEvent->getYPrecision(),
3043 motionEvent->getRawXCursorPosition(),
3044 motionEvent->getRawYCursorPosition(),
3045 motionEvent->getDownTime(), uint32_t(pointerCount),
3046 pointerProperties, samplePointerCoords,
3047 motionEvent->getXOffset(), motionEvent->getYOffset());
3048 injectedEntries.push(nextInjectedEntry);
3049 }
3050 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003053 default:
3054 ALOGW("Cannot inject event of type %d", event->getType());
3055 return INPUT_EVENT_INJECTION_FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056 }
3057
3058 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3059 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3060 injectionState->injectionIsAsync = true;
3061 }
3062
3063 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003064 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003065
3066 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003067 while (!injectedEntries.empty()) {
3068 needWake |= enqueueInboundEventLocked(injectedEntries.front());
3069 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003070 }
3071
3072 mLock.unlock();
3073
3074 if (needWake) {
3075 mLooper->wake();
3076 }
3077
3078 int32_t injectionResult;
3079 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003080 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003081
3082 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3083 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3084 } else {
3085 for (;;) {
3086 injectionResult = injectionState->injectionResult;
3087 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3088 break;
3089 }
3090
3091 nsecs_t remainingTimeout = endTime - now();
3092 if (remainingTimeout <= 0) {
3093#if DEBUG_INJECTION
3094 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003095 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003096#endif
3097 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3098 break;
3099 }
3100
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003101 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003102 }
3103
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003104 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
3105 syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003106 while (injectionState->pendingForegroundDispatches != 0) {
3107#if DEBUG_INJECTION
3108 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003109 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003110#endif
3111 nsecs_t remainingTimeout = endTime - now();
3112 if (remainingTimeout <= 0) {
3113#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3115 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003116#endif
3117 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3118 break;
3119 }
3120
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003121 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003122 }
3123 }
3124 }
3125
3126 injectionState->release();
3127 } // release lock
3128
3129#if DEBUG_INJECTION
3130 ALOGD("injectInputEvent - Finished with result %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003131 "injectorPid=%d, injectorUid=%d",
3132 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133#endif
3134
3135 return injectionResult;
3136}
3137
3138bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003139 return injectorUid == 0 ||
3140 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003141}
3142
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003143void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003144 InjectionState* injectionState = entry->injectionState;
3145 if (injectionState) {
3146#if DEBUG_INJECTION
3147 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003148 "injectorPid=%d, injectorUid=%d",
3149 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003150#endif
3151
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003152 if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003153 // Log the outcome since the injector did not wait for the injection result.
3154 switch (injectionResult) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003155 case INPUT_EVENT_INJECTION_SUCCEEDED:
3156 ALOGV("Asynchronous input event injection succeeded.");
3157 break;
3158 case INPUT_EVENT_INJECTION_FAILED:
3159 ALOGW("Asynchronous input event injection failed.");
3160 break;
3161 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
3162 ALOGW("Asynchronous input event injection permission denied.");
3163 break;
3164 case INPUT_EVENT_INJECTION_TIMED_OUT:
3165 ALOGW("Asynchronous input event injection timed out.");
3166 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 }
3168 }
3169
3170 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003171 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172 }
3173}
3174
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003175void InputDispatcher::incrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176 InjectionState* injectionState = entry->injectionState;
3177 if (injectionState) {
3178 injectionState->pendingForegroundDispatches += 1;
3179 }
3180}
3181
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003182void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003183 InjectionState* injectionState = entry->injectionState;
3184 if (injectionState) {
3185 injectionState->pendingForegroundDispatches -= 1;
3186
3187 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003188 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003189 }
3190 }
3191}
3192
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003193std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
3194 int32_t displayId) const {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003195 return getValueByKey(mWindowHandlesByDisplay, displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003196}
3197
Michael Wrightd02c5b62014-02-10 15:10:22 -08003198sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08003199 const sp<IBinder>& windowHandleToken) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003200 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003201 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3202 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003203 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003204 return windowHandle;
3205 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003206 }
3207 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003208 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003209}
3210
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003211bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
Arthur Hungb92218b2018-08-14 12:00:21 +08003212 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003213 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
3214 for (const sp<InputWindowHandle>& handle : windowHandles) {
3215 if (handle->getToken() == windowHandle->getToken()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003216 if (windowHandle->getInfo()->displayId != it.first) {
Arthur Hung3b413f22018-10-26 18:05:34 +08003217 ALOGE("Found window %s in display %" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003218 ", but it should belong to display %" PRId32,
3219 windowHandle->getName().c_str(), it.first,
3220 windowHandle->getInfo()->displayId);
Arthur Hungb92218b2018-08-14 12:00:21 +08003221 }
3222 return true;
3223 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224 }
3225 }
3226 return false;
3227}
3228
Robert Carr5c8a0262018-10-03 16:30:44 -07003229sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token) const {
3230 size_t count = mInputChannelsByToken.count(token);
3231 if (count == 0) {
3232 return nullptr;
3233 }
3234 return mInputChannelsByToken.at(token);
3235}
3236
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003237void InputDispatcher::updateWindowHandlesForDisplayLocked(
3238 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
3239 if (inputWindowHandles.empty()) {
3240 // Remove all handles on a display if there are no windows left.
3241 mWindowHandlesByDisplay.erase(displayId);
3242 return;
3243 }
3244
3245 // Since we compare the pointer of input window handles across window updates, we need
3246 // to make sure the handle object for the same window stays unchanged across updates.
3247 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
3248 std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
3249 for (const sp<InputWindowHandle>& handle : oldHandles) {
3250 oldHandlesByTokens[handle->getToken()] = handle;
3251 }
3252
3253 std::vector<sp<InputWindowHandle>> newHandles;
3254 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
3255 if (!handle->updateInfo()) {
3256 // handle no longer valid
3257 continue;
3258 }
3259
3260 const InputWindowInfo* info = handle->getInfo();
3261 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
3262 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
3263 const bool noInputChannel =
3264 info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
3265 const bool canReceiveInput =
3266 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) ||
3267 !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE);
3268 if (canReceiveInput && !noInputChannel) {
3269 ALOGE("Window handle %s has no registered input channel",
3270 handle->getName().c_str());
3271 }
3272 continue;
3273 }
3274
3275 if (info->displayId != displayId) {
3276 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
3277 handle->getName().c_str(), displayId, info->displayId);
3278 continue;
3279 }
3280
3281 if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
3282 const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
3283 oldHandle->updateFrom(handle);
3284 newHandles.push_back(oldHandle);
3285 } else {
3286 newHandles.push_back(handle);
3287 }
3288 }
3289
3290 // Insert or replace
3291 mWindowHandlesByDisplay[displayId] = newHandles;
3292}
3293
Arthur Hungb92218b2018-08-14 12:00:21 +08003294/**
3295 * Called from InputManagerService, update window handle list by displayId that can receive input.
3296 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
3297 * If set an empty list, remove all handles from the specific display.
3298 * For focused handle, check if need to change and send a cancel event to previous one.
3299 * For removed handle, check if need to send a cancel event if already in touch.
3300 */
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003301void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003302 int32_t displayId,
3303 const sp<ISetInputWindowsListener>& setInputWindowsListener) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003305 ALOGD("setInputWindows displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003306#endif
3307 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003308 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003309
Arthur Hungb92218b2018-08-14 12:00:21 +08003310 // Copy old handles for release if they are no longer present.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003311 const std::vector<sp<InputWindowHandle>> oldWindowHandles =
3312 getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003314 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
3315
Tiger Huang721e26f2018-07-24 22:26:19 +08003316 sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317 bool foundHoveredWindow = false;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003318 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
3319 // Set newFocusedWindowHandle to the top most focused window instead of the last one
3320 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
3321 windowHandle->getInfo()->visible) {
3322 newFocusedWindowHandle = windowHandle;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003323 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07003324 if (windowHandle == mLastHoverWindowHandle) {
3325 foundHoveredWindow = true;
Garfield Tanbd0fbcd2018-11-30 12:45:03 -08003326 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327 }
3328
3329 if (!foundHoveredWindow) {
Yi Kong9b14ac62018-07-17 13:48:38 -07003330 mLastHoverWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 }
3332
Tiger Huang721e26f2018-07-24 22:26:19 +08003333 sp<InputWindowHandle> oldFocusedWindowHandle =
3334 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
3335
3336 if (oldFocusedWindowHandle != newFocusedWindowHandle) {
3337 if (oldFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003339 ALOGD("Focus left window: %s in display %" PRId32,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003340 oldFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003341#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003342 sp<InputChannel> focusedInputChannel =
3343 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003344 if (focusedInputChannel != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003345 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003346 "focus left window");
3347 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003349 mFocusedWindowHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350 }
Yi Kong9b14ac62018-07-17 13:48:38 -07003351 if (newFocusedWindowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003353 ALOGD("Focus entered window: %s in display %" PRId32,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003354 newFocusedWindowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003355#endif
Tiger Huang721e26f2018-07-24 22:26:19 +08003356 mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357 }
Robert Carrf759f162018-11-13 12:57:11 -08003358
3359 if (mFocusedDisplayId == displayId) {
chaviw0c06c6e2019-01-09 13:27:07 -08003360 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003361 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 }
3363
Arthur Hungb92218b2018-08-14 12:00:21 +08003364 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
3365 if (stateIndex >= 0) {
3366 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003367 for (size_t i = 0; i < state.windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003368 TouchedWindow& touchedWindow = state.windows[i];
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003369 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003371 ALOGD("Touched window was removed: %s in display %" PRId32,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003372 touchedWindow.windowHandle->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003373#endif
Jeff Brownf086ddb2014-02-11 14:28:48 -08003374 sp<InputChannel> touchedInputChannel =
Robert Carr5c8a0262018-10-03 16:30:44 -07003375 getInputChannelLocked(touchedWindow.windowHandle->getToken());
Yi Kong9b14ac62018-07-17 13:48:38 -07003376 if (touchedInputChannel != nullptr) {
Jeff Brownf086ddb2014-02-11 14:28:48 -08003377 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003378 "touched window was removed");
3379 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
3380 options);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003381 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003382 state.windows.erase(state.windows.begin() + i);
Ivan Lozano96f12992017-11-09 14:45:38 -08003383 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003384 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003385 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386 }
3387 }
3388
3389 // Release information for windows that are no longer present.
3390 // This ensures that unused input channels are released promptly.
3391 // Otherwise, they might stick around until the window handle is destroyed
3392 // which might not happen until the next GC.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003393 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Siarhei Vishniakou9224fba2018-08-13 18:55:08 +00003394 if (!hasWindowHandleLocked(oldWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395#if DEBUG_FOCUS
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003396 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003397#endif
Arthur Hung3b413f22018-10-26 18:05:34 +08003398 oldWindowHandle->releaseChannel();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003399 }
3400 }
3401 } // release lock
3402
3403 // Wake up poll loop since it may need to make new input dispatching choices.
3404 mLooper->wake();
chaviw291d88a2019-02-14 10:33:58 -08003405
3406 if (setInputWindowsListener) {
3407 setInputWindowsListener->onSetInputWindowsFinished();
3408 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003409}
3410
3411void InputDispatcher::setFocusedApplication(
Tiger Huang721e26f2018-07-24 22:26:19 +08003412 int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003413#if DEBUG_FOCUS
Arthur Hung3b413f22018-10-26 18:05:34 +08003414 ALOGD("setFocusedApplication displayId=%" PRId32, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415#endif
3416 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003417 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003418
Tiger Huang721e26f2018-07-24 22:26:19 +08003419 sp<InputApplicationHandle> oldFocusedApplicationHandle =
3420 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Yi Kong9b14ac62018-07-17 13:48:38 -07003421 if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
Tiger Huang721e26f2018-07-24 22:26:19 +08003422 if (oldFocusedApplicationHandle != inputApplicationHandle) {
3423 if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003424 resetANRTimeoutsLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003425 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003426 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003427 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003428 } else if (oldFocusedApplicationHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429 resetANRTimeoutsLocked();
Tiger Huang721e26f2018-07-24 22:26:19 +08003430 oldFocusedApplicationHandle.clear();
3431 mFocusedApplicationHandlesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003432 }
3433
3434#if DEBUG_FOCUS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003435 // logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003436#endif
3437 } // release lock
3438
3439 // Wake up poll loop since it may need to make new input dispatching choices.
3440 mLooper->wake();
3441}
3442
Tiger Huang721e26f2018-07-24 22:26:19 +08003443/**
3444 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
3445 * the display not specified.
3446 *
3447 * We track any unreleased events for each window. If a window loses the ability to receive the
3448 * released event, we will send a cancel event to it. So when the focused display is changed, we
3449 * cancel all the unreleased display-unspecified events for the focused window on the old focused
3450 * display. The display-specified events won't be affected.
3451 */
3452void InputDispatcher::setFocusedDisplay(int32_t displayId) {
3453#if DEBUG_FOCUS
3454 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
3455#endif
3456 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003457 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08003458
3459 if (mFocusedDisplayId != displayId) {
3460 sp<InputWindowHandle> oldFocusedWindowHandle =
3461 getValueByKey(mFocusedWindowHandlesByDisplay, mFocusedDisplayId);
3462 if (oldFocusedWindowHandle != nullptr) {
Robert Carr5c8a0262018-10-03 16:30:44 -07003463 sp<InputChannel> inputChannel =
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003464 getInputChannelLocked(oldFocusedWindowHandle->getToken());
Tiger Huang721e26f2018-07-24 22:26:19 +08003465 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003466 CancelationOptions
3467 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3468 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00003469 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08003470 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
3471 }
3472 }
3473 mFocusedDisplayId = displayId;
3474
3475 // Sanity check
3476 sp<InputWindowHandle> newFocusedWindowHandle =
3477 getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
chaviw0c06c6e2019-01-09 13:27:07 -08003478 onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
Robert Carrf759f162018-11-13 12:57:11 -08003479
Tiger Huang721e26f2018-07-24 22:26:19 +08003480 if (newFocusedWindowHandle == nullptr) {
3481 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
3482 if (!mFocusedWindowHandlesByDisplay.empty()) {
3483 ALOGE("But another display has a focused window:");
3484 for (auto& it : mFocusedWindowHandlesByDisplay) {
3485 const int32_t displayId = it.first;
3486 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003487 ALOGE("Display #%" PRId32 " has focused window: '%s'\n", displayId,
3488 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003489 }
3490 }
3491 }
3492 }
3493
3494#if DEBUG_FOCUS
3495 logDispatchStateLocked();
3496#endif
3497 } // release lock
3498
3499 // Wake up poll loop since it may need to make new input dispatching choices.
3500 mLooper->wake();
3501}
3502
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3504#if DEBUG_FOCUS
3505 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3506#endif
3507
3508 bool changed;
3509 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003510 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003511
3512 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3513 if (mDispatchFrozen && !frozen) {
3514 resetANRTimeoutsLocked();
3515 }
3516
3517 if (mDispatchEnabled && !enabled) {
3518 resetAndDropEverythingLocked("dispatcher is being disabled");
3519 }
3520
3521 mDispatchEnabled = enabled;
3522 mDispatchFrozen = frozen;
3523 changed = true;
3524 } else {
3525 changed = false;
3526 }
3527
3528#if DEBUG_FOCUS
Tiger Huang721e26f2018-07-24 22:26:19 +08003529 logDispatchStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530#endif
3531 } // release lock
3532
3533 if (changed) {
3534 // Wake up poll loop since it may need to make new input dispatching choices.
3535 mLooper->wake();
3536 }
3537}
3538
3539void InputDispatcher::setInputFilterEnabled(bool enabled) {
3540#if DEBUG_FOCUS
3541 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
3542#endif
3543
3544 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003545 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003546
3547 if (mInputFilterEnabled == enabled) {
3548 return;
3549 }
3550
3551 mInputFilterEnabled = enabled;
3552 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3553 } // release lock
3554
3555 // Wake up poll loop since there might be work to do to drop everything.
3556 mLooper->wake();
3557}
3558
chaviwfbe5d9c2018-12-26 12:23:37 -08003559bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
3560 if (fromToken == toToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003561#if DEBUG_FOCUS
chaviwfbe5d9c2018-12-26 12:23:37 -08003562 ALOGD("Trivial transfer to same window.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003563#endif
chaviwfbe5d9c2018-12-26 12:23:37 -08003564 return true;
3565 }
3566
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003568 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003569
chaviwfbe5d9c2018-12-26 12:23:37 -08003570 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
3571 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07003572 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08003573 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003574 return false;
3575 }
chaviw4f2dd402018-12-26 15:30:27 -08003576#if DEBUG_FOCUS
3577 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003578 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
chaviw4f2dd402018-12-26 15:30:27 -08003579#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003580 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
3581#if DEBUG_FOCUS
3582 ALOGD("Cannot transfer focus because windows are on different displays.");
3583#endif
3584 return false;
3585 }
3586
3587 bool found = false;
Jeff Brownf086ddb2014-02-11 14:28:48 -08003588 for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
3589 TouchState& state = mTouchStatesByDisplay.editValueAt(d);
3590 for (size_t i = 0; i < state.windows.size(); i++) {
3591 const TouchedWindow& touchedWindow = state.windows[i];
3592 if (touchedWindow.windowHandle == fromWindowHandle) {
3593 int32_t oldTargetFlags = touchedWindow.targetFlags;
3594 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003595
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003596 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003597
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003598 int32_t newTargetFlags = oldTargetFlags &
3599 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
3600 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003601 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003602
Jeff Brownf086ddb2014-02-11 14:28:48 -08003603 found = true;
3604 goto Found;
3605 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 }
3607 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003608 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003610 if (!found) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003611#if DEBUG_FOCUS
3612 ALOGD("Focus transfer failed because from window did not have focus.");
3613#endif
3614 return false;
3615 }
3616
chaviwfbe5d9c2018-12-26 12:23:37 -08003617 sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
3618 sp<InputChannel> toChannel = getInputChannelLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003619 sp<Connection> fromConnection = getConnectionLocked(fromChannel);
3620 sp<Connection> toConnection = getConnectionLocked(toChannel);
3621 if (fromConnection != nullptr && toConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003623 CancelationOptions
3624 options(CancelationOptions::CANCEL_POINTER_EVENTS,
3625 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
3627 }
3628
3629#if DEBUG_FOCUS
3630 logDispatchStateLocked();
3631#endif
3632 } // release lock
3633
3634 // Wake up poll loop since it may need to make new input dispatching choices.
3635 mLooper->wake();
3636 return true;
3637}
3638
3639void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3640#if DEBUG_FOCUS
3641 ALOGD("Resetting and dropping all events (%s).", reason);
3642#endif
3643
3644 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3645 synthesizeCancelationEventsForAllConnectionsLocked(options);
3646
3647 resetKeyRepeatLocked();
3648 releasePendingEventLocked();
3649 drainInboundQueueLocked();
3650 resetANRTimeoutsLocked();
3651
Jeff Brownf086ddb2014-02-11 14:28:48 -08003652 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07003654 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003655}
3656
3657void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003658 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003659 dumpDispatchStateLocked(dump);
3660
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003661 std::istringstream stream(dump);
3662 std::string line;
3663
3664 while (std::getline(stream, line, '\n')) {
3665 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003666 }
3667}
3668
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003669void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07003670 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
3671 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
3672 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08003673 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003674
Tiger Huang721e26f2018-07-24 22:26:19 +08003675 if (!mFocusedApplicationHandlesByDisplay.empty()) {
3676 dump += StringPrintf(INDENT "FocusedApplications:\n");
3677 for (auto& it : mFocusedApplicationHandlesByDisplay) {
3678 const int32_t displayId = it.first;
3679 const sp<InputApplicationHandle>& applicationHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003680 dump += StringPrintf(INDENT2 "displayId=%" PRId32
3681 ", name='%s', dispatchingTimeout=%0.3fms\n",
3682 displayId, applicationHandle->getName().c_str(),
3683 applicationHandle->getDispatchingTimeout(
3684 DEFAULT_INPUT_DISPATCHING_TIMEOUT) /
3685 1000000.0);
Tiger Huang721e26f2018-07-24 22:26:19 +08003686 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003687 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08003688 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003689 }
Tiger Huang721e26f2018-07-24 22:26:19 +08003690
3691 if (!mFocusedWindowHandlesByDisplay.empty()) {
3692 dump += StringPrintf(INDENT "FocusedWindows:\n");
3693 for (auto& it : mFocusedWindowHandlesByDisplay) {
3694 const int32_t displayId = it.first;
3695 const sp<InputWindowHandle>& windowHandle = it.second;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003696 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
3697 windowHandle->getName().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08003698 }
3699 } else {
3700 dump += StringPrintf(INDENT "FocusedWindows: <none>\n");
3701 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003702
Jeff Brownf086ddb2014-02-11 14:28:48 -08003703 if (!mTouchStatesByDisplay.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003704 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Jeff Brownf086ddb2014-02-11 14:28:48 -08003705 for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
3706 const TouchState& state = mTouchStatesByDisplay.valueAt(i);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003707 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003708 state.displayId, toString(state.down), toString(state.split),
3709 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003710 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003711 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003712 for (size_t i = 0; i < state.windows.size(); i++) {
3713 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003714 dump += StringPrintf(INDENT4
3715 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3716 i, touchedWindow.windowHandle->getName().c_str(),
3717 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08003718 }
3719 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003720 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08003721 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003722 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003723 dump += INDENT3 "Portal windows:\n";
3724 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003725 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003726 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
3727 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08003728 }
3729 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003730 }
3731 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003732 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003733 }
3734
Arthur Hungb92218b2018-08-14 12:00:21 +08003735 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003736 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003737 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08003738 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003739 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08003740 dump += INDENT2 "Windows:\n";
3741 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08003742 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08003743 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003744
Arthur Hungb92218b2018-08-14 12:00:21 +08003745 dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003746 "portalToDisplayId=%d, paused=%s, hasFocus=%s, "
3747 "hasWallpaper=%s, "
3748 "visible=%s, canReceiveKeys=%s, flags=0x%08x, "
3749 "type=0x%08x, layer=%d, "
3750 "frame=[%d,%d][%d,%d], globalScale=%f, "
3751 "windowScale=(%f,%f), "
3752 "touchableRegion=",
3753 i, windowInfo->name.c_str(), windowInfo->displayId,
3754 windowInfo->portalToDisplayId,
3755 toString(windowInfo->paused),
3756 toString(windowInfo->hasFocus),
3757 toString(windowInfo->hasWallpaper),
3758 toString(windowInfo->visible),
3759 toString(windowInfo->canReceiveKeys),
3760 windowInfo->layoutParamsFlags,
3761 windowInfo->layoutParamsType, windowInfo->layer,
3762 windowInfo->frameLeft, windowInfo->frameTop,
3763 windowInfo->frameRight, windowInfo->frameBottom,
3764 windowInfo->globalScaleFactor, windowInfo->windowXScale,
3765 windowInfo->windowYScale);
Arthur Hungb92218b2018-08-14 12:00:21 +08003766 dumpRegion(dump, windowInfo->touchableRegion);
3767 dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3768 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003769 windowInfo->ownerPid, windowInfo->ownerUid,
3770 windowInfo->dispatchingTimeout / 1000000.0);
Arthur Hungb92218b2018-08-14 12:00:21 +08003771 }
3772 } else {
3773 dump += INDENT2 "Windows: <none>\n";
3774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775 }
3776 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08003777 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003778 }
3779
Michael Wright3dd60e22019-03-27 22:06:44 +00003780 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003781 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003782 const std::vector<Monitor>& monitors = it.second;
3783 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
3784 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003785 }
3786 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003787 const std::vector<Monitor>& monitors = it.second;
3788 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
3789 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00003792 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 }
3794
3795 nsecs_t currentTime = now();
3796
3797 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003798 if (!mRecentQueue.empty()) {
3799 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
3800 for (EventEntry* entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003801 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003802 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003803 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 }
3805 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003806 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003807 }
3808
3809 // Dump event currently being dispatched.
3810 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003811 dump += INDENT "PendingEvent:\n";
3812 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003813 mPendingEvent->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003814 dump += StringPrintf(", age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003815 (currentTime - mPendingEvent->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003816 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003817 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818 }
3819
3820 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003821 if (!mInboundQueue.empty()) {
3822 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
3823 for (EventEntry* entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003824 dump += INDENT2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003825 entry->appendDescription(dump);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003826 dump += StringPrintf(", age=%0.1fms\n", (currentTime - entry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827 }
3828 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003829 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003830 }
3831
Michael Wright78f24442014-08-06 15:55:28 -07003832 if (!mReplacedKeys.isEmpty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003833 dump += INDENT "ReplacedKeys:\n";
Michael Wright78f24442014-08-06 15:55:28 -07003834 for (size_t i = 0; i < mReplacedKeys.size(); i++) {
3835 const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
3836 int32_t newKeyCode = mReplacedKeys.valueAt(i);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003837 dump += StringPrintf(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n", i,
3838 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07003839 }
3840 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003841 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07003842 }
3843
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003844 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003845 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003846 for (const auto& pair : mConnectionsByFd) {
3847 const sp<Connection>& connection = pair.second;
3848 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
3849 "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
3850 pair.first, connection->getInputChannelName().c_str(),
3851 connection->getWindowName().c_str(), connection->getStatusLabel(),
3852 toString(connection->monitor),
3853 toString(connection->inputPublisherBlocked));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003854
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003855 if (!connection->outboundQueue.empty()) {
3856 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
3857 connection->outboundQueue.size());
3858 for (DispatchEntry* entry : connection->outboundQueue) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003859 dump.append(INDENT4);
3860 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003861 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003862 entry->targetFlags, entry->resolvedAction,
3863 (currentTime - entry->eventEntry->eventTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003864 }
3865 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003866 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003867 }
3868
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003869 if (!connection->waitQueue.empty()) {
3870 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
3871 connection->waitQueue.size());
3872 for (DispatchEntry* entry : connection->waitQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003873 dump += INDENT4;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003874 entry->eventEntry->appendDescription(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003875 dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003876 "age=%0.1fms, wait=%0.1fms\n",
3877 entry->targetFlags, entry->resolvedAction,
3878 (currentTime - entry->eventEntry->eventTime) * 0.000001f,
3879 (currentTime - entry->deliveryTime) * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880 }
3881 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003882 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883 }
3884 }
3885 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003886 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003887 }
3888
3889 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003890 dump += StringPrintf(INDENT "AppSwitch: pending, due in %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003891 (mAppSwitchDueTime - now()) / 1000000.0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003892 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003893 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08003894 }
3895
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003896 dump += INDENT "Configuration:\n";
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003897 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003898 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003899 mConfig.keyRepeatTimeout * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900}
3901
Michael Wright3dd60e22019-03-27 22:06:44 +00003902void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
3903 const size_t numMonitors = monitors.size();
3904 for (size_t i = 0; i < numMonitors; i++) {
3905 const Monitor& monitor = monitors[i];
3906 const sp<InputChannel>& channel = monitor.inputChannel;
3907 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
3908 dump += "\n";
3909 }
3910}
3911
3912status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003913 int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914#if DEBUG_REGISTRATION
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003915 ALOGD("channel '%s' ~ registerInputChannel - displayId=%" PRId32,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003916 inputChannel->getName().c_str(), displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003917#endif
3918
3919 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003920 std::scoped_lock _l(mLock);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003921 sp<Connection> existingConnection = getConnectionLocked(inputChannel);
3922 if (existingConnection != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003923 ALOGW("Attempted to register already registered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003924 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003925 return BAD_VALUE;
3926 }
3927
Michael Wright3dd60e22019-03-27 22:06:44 +00003928 sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929
3930 int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003931 mConnectionsByFd[fd] = connection;
Robert Carr5c8a0262018-10-03 16:30:44 -07003932 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003933
Michael Wrightd02c5b62014-02-10 15:10:22 -08003934 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3935 } // release lock
3936
3937 // Wake the looper because some connections have changed.
3938 mLooper->wake();
3939 return OK;
3940}
3941
Michael Wright3dd60e22019-03-27 22:06:44 +00003942status_t InputDispatcher::registerInputMonitor(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003943 int32_t displayId, bool isGestureMonitor) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003944 { // acquire lock
3945 std::scoped_lock _l(mLock);
3946
3947 if (displayId < 0) {
3948 ALOGW("Attempted to register input monitor without a specified display.");
3949 return BAD_VALUE;
3950 }
3951
3952 if (inputChannel->getToken() == nullptr) {
3953 ALOGW("Attempted to register input monitor without an identifying token.");
3954 return BAD_VALUE;
3955 }
3956
3957 sp<Connection> connection = new Connection(inputChannel, true /*monitor*/);
3958
3959 const int fd = inputChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003960 mConnectionsByFd[fd] = connection;
Michael Wright3dd60e22019-03-27 22:06:44 +00003961 mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
3962
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003963 auto& monitorsByDisplay =
3964 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Michael Wright3dd60e22019-03-27 22:06:44 +00003965 monitorsByDisplay[displayId].emplace_back(inputChannel);
3966
3967 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00003968 }
3969 // Wake the looper because some connections have changed.
3970 mLooper->wake();
3971 return OK;
3972}
3973
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3975#if DEBUG_REGISTRATION
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08003976 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003977#endif
3978
3979 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003980 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003981
3982 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3983 if (status) {
3984 return status;
3985 }
3986 } // release lock
3987
3988 // Wake the poll loop because removing the connection may have changed the current
3989 // synchronization state.
3990 mLooper->wake();
3991 return OK;
3992}
3993
3994status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003995 bool notify) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003996 sp<Connection> connection = getConnectionLocked(inputChannel);
3997 if (connection == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003998 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003999 inputChannel->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004000 return BAD_VALUE;
4001 }
4002
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004003 const bool removed = removeByValue(mConnectionsByFd, connection);
4004 ALOG_ASSERT(removed);
Robert Carr5c8a0262018-10-03 16:30:44 -07004005 mInputChannelsByToken.erase(inputChannel->getToken());
4006
Michael Wrightd02c5b62014-02-10 15:10:22 -08004007 if (connection->monitor) {
4008 removeMonitorChannelLocked(inputChannel);
4009 }
4010
4011 mLooper->removeFd(inputChannel->getFd());
4012
4013 nsecs_t currentTime = now();
4014 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
4015
4016 connection->status = Connection::STATUS_ZOMBIE;
4017 return OK;
4018}
4019
4020void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004021 removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
4022 removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
4023}
4024
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004025void InputDispatcher::removeMonitorChannelLocked(
4026 const sp<InputChannel>& inputChannel,
Michael Wright3dd60e22019-03-27 22:06:44 +00004027 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004028 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004029 std::vector<Monitor>& monitors = it->second;
4030 const size_t numMonitors = monitors.size();
4031 for (size_t i = 0; i < numMonitors; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004032 if (monitors[i].inputChannel == inputChannel) {
4033 monitors.erase(monitors.begin() + i);
4034 break;
4035 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004036 }
Michael Wright3dd60e22019-03-27 22:06:44 +00004037 if (monitors.empty()) {
4038 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08004039 } else {
4040 ++it;
4041 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004042 }
4043}
4044
Michael Wright3dd60e22019-03-27 22:06:44 +00004045status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
4046 { // acquire lock
4047 std::scoped_lock _l(mLock);
4048 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
4049
4050 if (!foundDisplayId) {
4051 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
4052 return BAD_VALUE;
4053 }
4054 int32_t displayId = foundDisplayId.value();
4055
4056 ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
4057 if (stateIndex < 0) {
4058 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
4059 return BAD_VALUE;
4060 }
4061
4062 TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
4063 std::optional<int32_t> foundDeviceId;
4064 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
4065 if (touchedMonitor.monitor.inputChannel->getToken() == token) {
4066 foundDeviceId = state.deviceId;
4067 }
4068 }
4069 if (!foundDeviceId || !state.down) {
4070 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004071 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004072 return BAD_VALUE;
4073 }
4074 int32_t deviceId = foundDeviceId.value();
4075
4076 // Send cancel events to all the input channels we're stealing from.
4077 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004078 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00004079 options.deviceId = deviceId;
4080 options.displayId = displayId;
4081 for (const TouchedWindow& window : state.windows) {
4082 sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
4083 synthesizeCancelationEventsForInputChannelLocked(channel, options);
4084 }
4085 // Then clear the current touch state so we stop dispatching to them as well.
4086 state.filterNonMonitors();
4087 }
4088 return OK;
4089}
4090
Michael Wright3dd60e22019-03-27 22:06:44 +00004091std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
4092 const sp<IBinder>& token) {
4093 for (const auto& it : mGestureMonitorsByDisplay) {
4094 const std::vector<Monitor>& monitors = it.second;
4095 for (const Monitor& monitor : monitors) {
4096 if (monitor.inputChannel->getToken() == token) {
4097 return it.first;
4098 }
4099 }
4100 }
4101 return std::nullopt;
4102}
4103
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004104sp<InputDispatcher::Connection> InputDispatcher::getConnectionLocked(
4105 const sp<InputChannel>& inputChannel) {
Robert Carr4e670e52018-08-15 13:26:12 -07004106 if (inputChannel == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004107 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08004108 }
4109
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004110 for (const auto& pair : mConnectionsByFd) {
4111 sp<Connection> connection = pair.second;
Robert Carr4e670e52018-08-15 13:26:12 -07004112 if (connection->inputChannel->getToken() == inputChannel->getToken()) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004113 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004114 }
4115 }
Robert Carr4e670e52018-08-15 13:26:12 -07004116
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004117 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004118}
4119
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004120void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
4121 const sp<Connection>& connection, uint32_t seq,
4122 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004123 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4124 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004125 commandEntry->connection = connection;
4126 commandEntry->eventTime = currentTime;
4127 commandEntry->seq = seq;
4128 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004129 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004130}
4131
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004132void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
4133 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004135 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004137 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4138 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004140 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141}
4142
chaviw0c06c6e2019-01-09 13:27:07 -08004143void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& oldFocus,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004144 const sp<InputWindowHandle>& newFocus) {
chaviw0c06c6e2019-01-09 13:27:07 -08004145 sp<IBinder> oldToken = oldFocus != nullptr ? oldFocus->getToken() : nullptr;
4146 sp<IBinder> newToken = newFocus != nullptr ? newFocus->getToken() : nullptr;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004147 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
4148 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08004149 commandEntry->oldToken = oldToken;
4150 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004151 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08004152}
4153
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004154void InputDispatcher::onANRLocked(nsecs_t currentTime,
4155 const sp<InputApplicationHandle>& applicationHandle,
4156 const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
4157 nsecs_t waitStartTime, const char* reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004158 float dispatchLatency = (currentTime - eventTime) * 0.000001f;
4159 float waitDuration = (currentTime - waitStartTime) * 0.000001f;
4160 ALOGI("Application is not responding: %s. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004161 "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
4162 getApplicationWindowLabel(applicationHandle, windowHandle).c_str(), dispatchLatency,
4163 waitDuration, reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164
4165 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07004166 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004167 struct tm tm;
4168 localtime_r(&t, &tm);
4169 char timestr[64];
4170 strftime(timestr, sizeof(timestr), "%F %T", &tm);
4171 mLastANRState.clear();
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004172 mLastANRState += INDENT "ANR:\n";
4173 mLastANRState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004174 mLastANRState +=
4175 StringPrintf(INDENT2 "Window: %s\n",
4176 getApplicationWindowLabel(applicationHandle, windowHandle).c_str());
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004177 mLastANRState += StringPrintf(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
4178 mLastANRState += StringPrintf(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
4179 mLastANRState += StringPrintf(INDENT2 "Reason: %s\n", reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004180 dumpDispatchStateLocked(mLastANRState);
4181
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004182 std::unique_ptr<CommandEntry> commandEntry =
4183 std::make_unique<CommandEntry>(&InputDispatcher::doNotifyANRLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 commandEntry->inputApplicationHandle = applicationHandle;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004185 commandEntry->inputChannel =
4186 windowHandle != nullptr ? getInputChannelLocked(windowHandle->getToken()) : nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 commandEntry->reason = reason;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07004188 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189}
4190
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004191void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192 mLock.unlock();
4193
4194 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
4195
4196 mLock.lock();
4197}
4198
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004199void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004200 sp<Connection> connection = commandEntry->connection;
4201
4202 if (connection->status != Connection::STATUS_ZOMBIE) {
4203 mLock.unlock();
4204
Robert Carr803535b2018-08-02 16:38:15 -07004205 mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004206
4207 mLock.lock();
4208 }
4209}
4210
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004211void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08004212 sp<IBinder> oldToken = commandEntry->oldToken;
4213 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08004214 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08004215 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08004216 mLock.lock();
4217}
4218
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004219void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004220 mLock.unlock();
4221
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004222 nsecs_t newTimeout =
4223 mPolicy->notifyANR(commandEntry->inputApplicationHandle,
4224 commandEntry->inputChannel ? commandEntry->inputChannel->getToken()
4225 : nullptr,
4226 commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004227
4228 mLock.lock();
4229
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004230 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004231}
4232
4233void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
4234 CommandEntry* commandEntry) {
4235 KeyEntry* entry = commandEntry->keyEntry;
4236
4237 KeyEvent event;
4238 initializeKeyEvent(&event, entry);
4239
4240 mLock.unlock();
4241
Michael Wright2b3c3302018-03-02 17:19:13 +00004242 android::base::Timer t;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004243 sp<IBinder> token = commandEntry->inputChannel != nullptr
4244 ? commandEntry->inputChannel->getToken()
4245 : nullptr;
4246 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004247 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4248 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004249 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004250 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004251
4252 mLock.lock();
4253
4254 if (delay < 0) {
4255 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
4256 } else if (!delay) {
4257 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
4258 } else {
4259 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
4260 entry->interceptKeyWakeupTime = now() + delay;
4261 }
4262 entry->release();
4263}
4264
chaviwfd6d3512019-03-25 13:23:49 -07004265void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
4266 mLock.unlock();
4267 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
4268 mLock.lock();
4269}
4270
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004271void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004272 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004273 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004274 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004275 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004276
4277 // Handle post-event policy actions.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004278 std::deque<InputDispatcher::DispatchEntry*>::iterator dispatchEntryIt =
4279 connection->findWaitQueueEntry(seq);
4280 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004281 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004282 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004283 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004284
4285 nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
4286 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
4287 std::string msg =
4288 StringPrintf("Window '%s' spent %0.1fms processing the last input event: ",
4289 connection->getWindowName().c_str(), eventDuration * 0.000001f);
4290 dispatchEntry->eventEntry->appendDescription(msg);
4291 ALOGI("%s", msg.c_str());
4292 }
4293
4294 bool restartEvent;
4295 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
4296 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
4297 restartEvent =
4298 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
4299 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
4300 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
4301 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
4302 handled);
4303 } else {
4304 restartEvent = false;
4305 }
4306
4307 // Dequeue the event and start the next cycle.
4308 // Note that because the lock might have been released, it is possible that the
4309 // contents of the wait queue to have been drained, so we need to double-check
4310 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004311 dispatchEntryIt = connection->findWaitQueueEntry(seq);
4312 if (dispatchEntryIt != connection->waitQueue.end()) {
4313 dispatchEntry = *dispatchEntryIt;
4314 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004315 traceWaitQueueLength(connection);
4316 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004317 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07004318 traceOutboundQueueLength(connection);
4319 } else {
4320 releaseDispatchEntry(dispatchEntry);
4321 }
4322 }
4323
4324 // Start the next dispatch cycle for this connection.
4325 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326}
4327
4328bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004329 DispatchEntry* dispatchEntry,
4330 KeyEntry* keyEntry, bool handled) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004331 if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004332 if (!handled) {
4333 // Report the key as unhandled, since the fallback was not handled.
4334 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
4335 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004336 return false;
4337 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004338
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004339 // Get the fallback key state.
4340 // Clear it out after dispatching the UP.
4341 int32_t originalKeyCode = keyEntry->keyCode;
4342 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
4343 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
4344 connection->inputState.removeFallbackKey(originalKeyCode);
4345 }
4346
4347 if (handled || !dispatchEntry->hasForegroundTarget()) {
4348 // If the application handles the original key for which we previously
4349 // generated a fallback or if the window is not a foreground window,
4350 // then cancel the associated fallback key, if any.
4351 if (fallbackKeyCode != -1) {
4352 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004354 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004355 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4356 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
4357 keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004358#endif
4359 KeyEvent event;
4360 initializeKeyEvent(&event, keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004361 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004362
4363 mLock.unlock();
4364
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004365 mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(), &event,
4366 keyEntry->policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367
4368 mLock.lock();
4369
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004370 // Cancel the fallback key.
4371 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004372 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004373 "application handled the original non-fallback key "
4374 "or is no longer a foreground target, "
4375 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376 options.keyCode = fallbackKeyCode;
4377 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004379 connection->inputState.removeFallbackKey(originalKeyCode);
4380 }
4381 } else {
4382 // If the application did not handle a non-fallback key, first check
4383 // that we are in a good state to perform unhandled key event processing
4384 // Then ask the policy what to do with it.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004385 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN && keyEntry->repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004386 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004387#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004388 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004389 "since this is not an initial down. "
4390 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4391 originalKeyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004392#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004393 return false;
4394 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004396 // Dispatch the unhandled key to the policy.
4397#if DEBUG_OUTBOUND_EVENT_DETAILS
4398 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004399 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
4400 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, keyEntry->policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004401#endif
4402 KeyEvent event;
4403 initializeKeyEvent(&event, keyEntry);
4404
4405 mLock.unlock();
4406
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004407 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(), &event,
4408 keyEntry->policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004409
4410 mLock.lock();
4411
4412 if (connection->status != Connection::STATUS_NORMAL) {
4413 connection->inputState.removeFallbackKey(originalKeyCode);
4414 return false;
4415 }
4416
4417 // Latch the fallback keycode for this key on an initial down.
4418 // The fallback keycode cannot change at any other point in the lifecycle.
4419 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004420 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004421 fallbackKeyCode = event.getKeyCode();
4422 } else {
4423 fallbackKeyCode = AKEYCODE_UNKNOWN;
4424 }
4425 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
4426 }
4427
4428 ALOG_ASSERT(fallbackKeyCode != -1);
4429
4430 // Cancel the fallback key if the policy decides not to send it anymore.
4431 // We will continue to dispatch the key to the policy but we will no
4432 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004433 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
4434 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004435#if DEBUG_OUTBOUND_EVENT_DETAILS
4436 if (fallback) {
4437 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004438 "as a fallback for %d, but on the DOWN it had requested "
4439 "to send %d instead. Fallback canceled.",
4440 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004441 } else {
4442 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004443 "but on the DOWN it had requested to send %d. "
4444 "Fallback canceled.",
4445 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004446 }
4447#endif
4448
4449 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
4450 "canceling fallback, policy no longer desires it");
4451 options.keyCode = fallbackKeyCode;
4452 synthesizeCancelationEventsForConnectionLocked(connection, options);
4453
4454 fallback = false;
4455 fallbackKeyCode = AKEYCODE_UNKNOWN;
4456 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004457 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004458 }
4459 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004460
4461#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004462 {
4463 std::string msg;
4464 const KeyedVector<int32_t, int32_t>& fallbackKeys =
4465 connection->inputState.getFallbackKeys();
4466 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004467 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004468 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004469 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004470 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004471 }
4472#endif
4473
4474 if (fallback) {
4475 // Restart the dispatch cycle using the fallback key.
4476 keyEntry->eventTime = event.getEventTime();
4477 keyEntry->deviceId = event.getDeviceId();
4478 keyEntry->source = event.getSource();
4479 keyEntry->displayId = event.getDisplayId();
4480 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4481 keyEntry->keyCode = fallbackKeyCode;
4482 keyEntry->scanCode = event.getScanCode();
4483 keyEntry->metaState = event.getMetaState();
4484 keyEntry->repeatCount = event.getRepeatCount();
4485 keyEntry->downTime = event.getDownTime();
4486 keyEntry->syntheticRepeat = false;
4487
4488#if DEBUG_OUTBOUND_EVENT_DETAILS
4489 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004490 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4491 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08004492#endif
4493 return true; // restart the event
4494 } else {
4495#if DEBUG_OUTBOUND_EVENT_DETAILS
4496 ALOGD("Unhandled key event: No fallback key.");
4497#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08004498
4499 // Report the key as unhandled, since there is no fallback key.
4500 mReporter->reportUnhandledKey(keyEntry->sequenceNum);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004501 }
4502 }
4503 return false;
4504}
4505
4506bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004507 DispatchEntry* dispatchEntry,
4508 MotionEntry* motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004509 return false;
4510}
4511
4512void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4513 mLock.unlock();
4514
4515 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4516
4517 mLock.lock();
4518}
4519
4520void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004521 event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004522 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4523 entry->downTime, entry->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524}
4525
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004526void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004527 int32_t injectionResult,
4528 nsecs_t timeSpentWaitingForApplication) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004529 // TODO Write some statistics about how long we spend waiting.
4530}
4531
4532void InputDispatcher::traceInboundQueueLengthLocked() {
4533 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004534 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535 }
4536}
4537
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004538void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004539 if (ATRACE_ENABLED()) {
4540 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004541 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004542 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004543 }
4544}
4545
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08004546void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547 if (ATRACE_ENABLED()) {
4548 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08004549 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004550 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004551 }
4552}
4553
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004554void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004555 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004557 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004558 dumpDispatchStateLocked(dump);
4559
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004560 if (!mLastANRState.empty()) {
4561 dump += "\nInput Dispatcher State at time of last ANR:\n";
4562 dump += mLastANRState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004563 }
4564}
4565
4566void InputDispatcher::monitor() {
4567 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004568 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004570 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571}
4572
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573// --- InputDispatcher::InjectionState ---
4574
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004575InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid)
4576 : refCount(1),
4577 injectorPid(injectorPid),
4578 injectorUid(injectorUid),
4579 injectionResult(INPUT_EVENT_INJECTION_PENDING),
4580 injectionIsAsync(false),
4581 pendingForegroundDispatches(0) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004583InputDispatcher::InjectionState::~InjectionState() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004584
4585void InputDispatcher::InjectionState::release() {
4586 refCount -= 1;
4587 if (refCount == 0) {
4588 delete this;
4589 } else {
4590 ALOG_ASSERT(refCount > 0);
4591 }
4592}
4593
Michael Wrightd02c5b62014-02-10 15:10:22 -08004594// --- InputDispatcher::EventEntry ---
4595
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004596InputDispatcher::EventEntry::EventEntry(uint32_t sequenceNum, int32_t type, nsecs_t eventTime,
4597 uint32_t policyFlags)
4598 : sequenceNum(sequenceNum),
4599 refCount(1),
4600 type(type),
4601 eventTime(eventTime),
4602 policyFlags(policyFlags),
4603 injectionState(nullptr),
4604 dispatchInProgress(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605
4606InputDispatcher::EventEntry::~EventEntry() {
4607 releaseInjectionState();
4608}
4609
4610void InputDispatcher::EventEntry::release() {
4611 refCount -= 1;
4612 if (refCount == 0) {
4613 delete this;
4614 } else {
4615 ALOG_ASSERT(refCount > 0);
4616 }
4617}
4618
4619void InputDispatcher::EventEntry::releaseInjectionState() {
4620 if (injectionState) {
4621 injectionState->release();
Yi Kong9b14ac62018-07-17 13:48:38 -07004622 injectionState = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004623 }
4624}
4625
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626// --- InputDispatcher::ConfigurationChangedEntry ---
4627
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004628InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(uint32_t sequenceNum,
4629 nsecs_t eventTime)
4630 : EventEntry(sequenceNum, TYPE_CONFIGURATION_CHANGED, eventTime, 0) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004631
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004632InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004633
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004634void InputDispatcher::ConfigurationChangedEntry::appendDescription(std::string& msg) const {
4635 msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004636}
4637
Michael Wrightd02c5b62014-02-10 15:10:22 -08004638// --- InputDispatcher::DeviceResetEntry ---
4639
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004640InputDispatcher::DeviceResetEntry::DeviceResetEntry(uint32_t sequenceNum, nsecs_t eventTime,
4641 int32_t deviceId)
4642 : EventEntry(sequenceNum, TYPE_DEVICE_RESET, eventTime, 0), deviceId(deviceId) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004643
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004644InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004645
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004646void InputDispatcher::DeviceResetEntry::appendDescription(std::string& msg) const {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004647 msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004648}
4649
Michael Wrightd02c5b62014-02-10 15:10:22 -08004650// --- InputDispatcher::KeyEntry ---
4651
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004652InputDispatcher::KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId,
4653 uint32_t source, int32_t displayId, uint32_t policyFlags,
4654 int32_t action, int32_t flags, int32_t keyCode,
4655 int32_t scanCode, int32_t metaState, int32_t repeatCount,
4656 nsecs_t downTime)
4657 : EventEntry(sequenceNum, TYPE_KEY, eventTime, policyFlags),
4658 deviceId(deviceId),
4659 source(source),
4660 displayId(displayId),
4661 action(action),
4662 flags(flags),
4663 keyCode(keyCode),
4664 scanCode(scanCode),
4665 metaState(metaState),
4666 repeatCount(repeatCount),
4667 downTime(downTime),
4668 syntheticRepeat(false),
4669 interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4670 interceptKeyWakeupTime(0) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004671
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004672InputDispatcher::KeyEntry::~KeyEntry() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004673
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004674void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004675 msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004676 "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
4677 "repeatCount=%d), policyFlags=0x%08x",
4678 deviceId, source, displayId, keyActionToString(action).c_str(), flags,
4679 keyCode, scanCode, metaState, repeatCount, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004680}
4681
4682void InputDispatcher::KeyEntry::recycle() {
4683 releaseInjectionState();
4684
4685 dispatchInProgress = false;
4686 syntheticRepeat = false;
4687 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4688 interceptKeyWakeupTime = 0;
4689}
4690
Michael Wrightd02c5b62014-02-10 15:10:22 -08004691// --- InputDispatcher::MotionEntry ---
4692
Garfield Tan00f511d2019-06-12 16:55:40 -07004693InputDispatcher::MotionEntry::MotionEntry(
4694 uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
4695 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -08004696 int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
Garfield Tan00f511d2019-06-12 16:55:40 -07004697 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
4698 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
Jeff Brownf086ddb2014-02-11 14:28:48 -08004699 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
Garfield Tan00f511d2019-06-12 16:55:40 -07004700 float xOffset, float yOffset)
4701 : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
Michael Wrightd02c5b62014-02-10 15:10:22 -08004702 eventTime(eventTime),
Garfield Tan00f511d2019-06-12 16:55:40 -07004703 deviceId(deviceId),
4704 source(source),
4705 displayId(displayId),
4706 action(action),
4707 actionButton(actionButton),
4708 flags(flags),
4709 metaState(metaState),
4710 buttonState(buttonState),
4711 classification(classification),
4712 edgeFlags(edgeFlags),
4713 xPrecision(xPrecision),
4714 yPrecision(yPrecision),
4715 xCursorPosition(xCursorPosition),
4716 yCursorPosition(yCursorPosition),
4717 downTime(downTime),
4718 pointerCount(pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719 for (uint32_t i = 0; i < pointerCount; i++) {
4720 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4721 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004722 if (xOffset || yOffset) {
4723 this->pointerCoords[i].applyOffset(xOffset, yOffset);
4724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725 }
4726}
4727
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004728InputDispatcher::MotionEntry::~MotionEntry() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004729
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004730void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08004731 msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
Garfield Tan00f511d2019-06-12 16:55:40 -07004732 ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
4733 "buttonState=0x%08x, "
4734 "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
4735 "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
4736 deviceId, source, displayId, motionActionToString(action).c_str(),
4737 actionButton, flags, metaState, buttonState,
4738 motionClassificationToString(classification), edgeFlags, xPrecision,
4739 yPrecision, xCursorPosition, yCursorPosition);
Siarhei Vishniakoub48188a2018-03-01 20:55:47 -08004740
Michael Wrightd02c5b62014-02-10 15:10:22 -08004741 for (uint32_t i = 0; i < pointerCount; i++) {
4742 if (i) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004743 msg += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004744 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004745 msg += StringPrintf("%d: (%.1f, %.1f)", pointerProperties[i].id, pointerCoords[i].getX(),
4746 pointerCoords[i].getY());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004747 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004748 msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004749}
4750
Michael Wrightd02c5b62014-02-10 15:10:22 -08004751// --- InputDispatcher::DispatchEntry ---
4752
4753volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
4754
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004755InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry, int32_t targetFlags,
4756 float xOffset, float yOffset, float globalScaleFactor,
4757 float windowXScale, float windowYScale)
4758 : seq(nextSeq()),
4759 eventEntry(eventEntry),
4760 targetFlags(targetFlags),
4761 xOffset(xOffset),
4762 yOffset(yOffset),
4763 globalScaleFactor(globalScaleFactor),
4764 windowXScale(windowXScale),
4765 windowYScale(windowYScale),
4766 deliveryTime(0),
4767 resolvedAction(0),
4768 resolvedFlags(0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004769 eventEntry->refCount += 1;
4770}
4771
4772InputDispatcher::DispatchEntry::~DispatchEntry() {
4773 eventEntry->release();
4774}
4775
4776uint32_t InputDispatcher::DispatchEntry::nextSeq() {
4777 // Sequence number 0 is reserved and will never be returned.
4778 uint32_t seq;
4779 do {
4780 seq = android_atomic_inc(&sNextSeqAtomic);
4781 } while (!seq);
4782 return seq;
4783}
4784
Michael Wrightd02c5b62014-02-10 15:10:22 -08004785// --- InputDispatcher::InputState ---
4786
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004787InputDispatcher::InputState::InputState() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004788
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004789InputDispatcher::InputState::~InputState() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08004790
4791bool InputDispatcher::InputState::isNeutral() const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004792 return mKeyMementos.empty() && mMotionMementos.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004793}
4794
4795bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004796 int32_t displayId) const {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004797 for (const MotionMemento& memento : mMotionMementos) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004798 if (memento.deviceId == deviceId && memento.source == source &&
4799 memento.displayId == displayId && memento.hovering) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004800 return true;
4801 }
4802 }
4803 return false;
4804}
4805
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004806bool InputDispatcher::InputState::trackKey(const KeyEntry* entry, int32_t action, int32_t flags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004807 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004808 case AKEY_EVENT_ACTION_UP: {
4809 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4810 for (size_t i = 0; i < mFallbackKeys.size();) {
4811 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4812 mFallbackKeys.removeItemsAt(i);
4813 } else {
4814 i += 1;
4815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 }
4817 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004818 ssize_t index = findKeyMemento(entry);
4819 if (index >= 0) {
4820 mKeyMementos.erase(mKeyMementos.begin() + index);
4821 return true;
4822 }
4823 /* FIXME: We can't just drop the key up event because that prevents creating
4824 * popup windows that are automatically shown when a key is held and then
4825 * dismissed when the key is released. The problem is that the popup will
4826 * not have received the original key down, so the key up will be considered
4827 * to be inconsistent with its observed state. We could perhaps handle this
4828 * by synthesizing a key down but that will cause other problems.
4829 *
4830 * So for now, allow inconsistent key up events to be dispatched.
4831 *
4832 #if DEBUG_OUTBOUND_EVENT_DETAILS
4833 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
4834 "keyCode=%d, scanCode=%d",
4835 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4836 #endif
4837 return false;
4838 */
Michael Wrightd02c5b62014-02-10 15:10:22 -08004839 return true;
4840 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004841
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004842 case AKEY_EVENT_ACTION_DOWN: {
4843 ssize_t index = findKeyMemento(entry);
4844 if (index >= 0) {
4845 mKeyMementos.erase(mKeyMementos.begin() + index);
4846 }
4847 addKeyMemento(entry, flags);
4848 return true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004849 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004850
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004851 default:
4852 return true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004853 }
4854}
4855
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004856bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, int32_t action,
4857 int32_t flags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004858 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4859 switch (actionMasked) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004860 case AMOTION_EVENT_ACTION_UP:
4861 case AMOTION_EVENT_ACTION_CANCEL: {
4862 ssize_t index = findMotionMemento(entry, false /*hovering*/);
Michael Wright38dcdff2014-03-19 12:06:10 -07004863 if (index >= 0) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004864 mMotionMementos.erase(mMotionMementos.begin() + index);
4865 return true;
4866 }
4867#if DEBUG_OUTBOUND_EVENT_DETAILS
4868 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
4869 "displayId=%" PRId32 ", actionMasked=%d",
4870 entry->deviceId, entry->source, entry->displayId, actionMasked);
4871#endif
4872 return false;
4873 }
4874
4875 case AMOTION_EVENT_ACTION_DOWN: {
4876 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4877 if (index >= 0) {
4878 mMotionMementos.erase(mMotionMementos.begin() + index);
4879 }
4880 addMotionMemento(entry, flags, false /*hovering*/);
4881 return true;
4882 }
4883
4884 case AMOTION_EVENT_ACTION_POINTER_UP:
4885 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4886 case AMOTION_EVENT_ACTION_MOVE: {
4887 if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
4888 // Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need
4889 // to generate cancellation events for these since they're based in relative rather
4890 // than absolute units.
4891 return true;
Michael Wright38dcdff2014-03-19 12:06:10 -07004892 }
4893
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004894 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4895
4896 if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
4897 // Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
4898 // joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral.
4899 // Any other value and we need to track the motion so we can send cancellation
4900 // events for anything generating fallback events (e.g. DPad keys for joystick
4901 // movements).
4902 if (index >= 0) {
4903 if (entry->pointerCoords[0].isEmpty()) {
4904 mMotionMementos.erase(mMotionMementos.begin() + index);
4905 } else {
4906 MotionMemento& memento = mMotionMementos[index];
4907 memento.setPointers(entry);
4908 }
4909 } else if (!entry->pointerCoords[0].isEmpty()) {
4910 addMotionMemento(entry, flags, false /*hovering*/);
4911 }
4912
4913 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4914 return true;
4915 }
4916 if (index >= 0) {
4917 MotionMemento& memento = mMotionMementos[index];
4918 memento.setPointers(entry);
4919 return true;
4920 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921#if DEBUG_OUTBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004922 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
4923 "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
4924 entry->deviceId, entry->source, entry->displayId, actionMasked);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004926 return false;
4927 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004928
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004929 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4930 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4931 if (index >= 0) {
4932 mMotionMementos.erase(mMotionMementos.begin() + index);
4933 return true;
4934 }
4935#if DEBUG_OUTBOUND_EVENT_DETAILS
4936 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
4937 "displayId=%" PRId32,
4938 entry->deviceId, entry->source, entry->displayId);
4939#endif
4940 return false;
4941 }
4942
4943 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4944 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4945 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4946 if (index >= 0) {
4947 mMotionMementos.erase(mMotionMementos.begin() + index);
4948 }
4949 addMotionMemento(entry, flags, true /*hovering*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004950 return true;
4951 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004953 default:
4954 return true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004955 }
4956}
4957
4958ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
4959 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004960 const KeyMemento& memento = mKeyMementos[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004961 if (memento.deviceId == entry->deviceId && memento.source == entry->source &&
4962 memento.displayId == entry->displayId && memento.keyCode == entry->keyCode &&
4963 memento.scanCode == entry->scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004964 return i;
4965 }
4966 }
4967 return -1;
4968}
4969
4970ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004971 bool hovering) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004973 const MotionMemento& memento = mMotionMementos[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004974 if (memento.deviceId == entry->deviceId && memento.source == entry->source &&
4975 memento.displayId == entry->displayId && memento.hovering == hovering) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004976 return i;
4977 }
4978 }
4979 return -1;
4980}
4981
4982void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004983 KeyMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004984 memento.deviceId = entry->deviceId;
4985 memento.source = entry->source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01004986 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004987 memento.keyCode = entry->keyCode;
4988 memento.scanCode = entry->scanCode;
4989 memento.metaState = entry->metaState;
4990 memento.flags = flags;
4991 memento.downTime = entry->downTime;
4992 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004993 mKeyMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004994}
4995
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004996void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry, int32_t flags,
4997 bool hovering) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004998 MotionMemento memento;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004999 memento.deviceId = entry->deviceId;
5000 memento.source = entry->source;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08005001 memento.displayId = entry->displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005002 memento.flags = flags;
5003 memento.xPrecision = entry->xPrecision;
5004 memento.yPrecision = entry->yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -07005005 memento.xCursorPosition = entry->xCursorPosition;
5006 memento.yCursorPosition = entry->yCursorPosition;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005007 memento.downTime = entry->downTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005008 memento.setPointers(entry);
5009 memento.hovering = hovering;
5010 memento.policyFlags = entry->policyFlags;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005011 mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005012}
5013
5014void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
5015 pointerCount = entry->pointerCount;
5016 for (uint32_t i = 0; i < entry->pointerCount; i++) {
5017 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
5018 pointerCoords[i].copyFrom(entry->pointerCoords[i]);
5019 }
5020}
5021
5022void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005023 std::vector<EventEntry*>& outEvents,
5024 const CancelationOptions& options) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005025 for (KeyMemento& memento : mKeyMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005026 if (shouldCancelKey(memento, options)) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005027 outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005028 memento.deviceId, memento.source, memento.displayId,
5029 memento.policyFlags, AKEY_EVENT_ACTION_UP,
5030 memento.flags | AKEY_EVENT_FLAG_CANCELED,
5031 memento.keyCode, memento.scanCode, memento.metaState,
5032 0, memento.downTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005033 }
5034 }
5035
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005036 for (const MotionMemento& memento : mMotionMementos) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005037 if (shouldCancelMotion(memento, options)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005038 const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT
5039 : AMOTION_EVENT_ACTION_CANCEL;
Garfield Tan00f511d2019-06-12 16:55:40 -07005040 outEvents.push_back(
5041 new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
5042 memento.source, memento.displayId, memento.policyFlags, action,
5043 0 /*actionButton*/, memento.flags, AMETA_NONE,
5044 0 /*buttonState*/, MotionClassification::NONE,
5045 AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
5046 memento.yPrecision, memento.xCursorPosition,
5047 memento.yCursorPosition, memento.downTime, memento.pointerCount,
5048 memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
5049 0 /*yOffset*/));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005050 }
5051 }
5052}
5053
5054void InputDispatcher::InputState::clear() {
5055 mKeyMementos.clear();
5056 mMotionMementos.clear();
5057 mFallbackKeys.clear();
5058}
5059
5060void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
5061 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005062 const MotionMemento& memento = mMotionMementos[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005063 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005064 for (size_t j = 0; j < other.mMotionMementos.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005065 const MotionMemento& otherMemento = other.mMotionMementos[j];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005066 if (memento.deviceId == otherMemento.deviceId &&
5067 memento.source == otherMemento.source &&
5068 memento.displayId == otherMemento.displayId) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005069 other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005070 } else {
5071 j += 1;
5072 }
5073 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005074 other.mMotionMementos.push_back(memento);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005075 }
5076 }
5077}
5078
5079int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
5080 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5081 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
5082}
5083
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005084void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005085 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
5086 if (index >= 0) {
5087 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
5088 } else {
5089 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
5090 }
5091}
5092
5093void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
5094 mFallbackKeys.removeItem(originalKeyCode);
5095}
5096
5097bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005098 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005099 if (options.keyCode && memento.keyCode != options.keyCode.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005100 return false;
5101 }
5102
Michael Wright3dd60e22019-03-27 22:06:44 +00005103 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5104 return false;
5105 }
5106
5107 if (options.displayId && memento.displayId != options.displayId.value()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005108 return false;
5109 }
5110
5111 switch (options.mode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005112 case CancelationOptions::CANCEL_ALL_EVENTS:
5113 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5114 return true;
5115 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
5116 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
5117 default:
5118 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005119 }
5120}
5121
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005122bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
5123 const CancelationOptions& options) {
5124 if (options.deviceId && memento.deviceId != options.deviceId.value()) {
5125 return false;
5126 }
5127
5128 if (options.displayId && memento.displayId != options.displayId.value()) {
5129 return false;
5130 }
5131
5132 switch (options.mode) {
5133 case CancelationOptions::CANCEL_ALL_EVENTS:
5134 return true;
5135 case CancelationOptions::CANCEL_POINTER_EVENTS:
5136 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
5137 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
5138 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
5139 default:
5140 return false;
5141 }
5142}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005143
5144// --- InputDispatcher::Connection ---
5145
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005146InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, bool monitor)
5147 : status(STATUS_NORMAL),
5148 inputChannel(inputChannel),
Michael Wrightd02c5b62014-02-10 15:10:22 -08005149 monitor(monitor),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005150 inputPublisher(inputChannel),
5151 inputPublisherBlocked(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005152
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005153InputDispatcher::Connection::~Connection() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005154
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005155const std::string InputDispatcher::Connection::getWindowName() const {
Robert Carr803535b2018-08-02 16:38:15 -07005156 if (inputChannel != nullptr) {
5157 return inputChannel->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005158 }
5159 if (monitor) {
5160 return "monitor";
5161 }
5162 return "?";
5163}
5164
5165const char* InputDispatcher::Connection::getStatusLabel() const {
5166 switch (status) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005167 case STATUS_NORMAL:
5168 return "NORMAL";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005169
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005170 case STATUS_BROKEN:
5171 return "BROKEN";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005172
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005173 case STATUS_ZOMBIE:
5174 return "ZOMBIE";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005176 default:
5177 return "UNKNOWN";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005178 }
5179}
5180
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005181std::deque<InputDispatcher::DispatchEntry*>::iterator
5182InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
5183 for (std::deque<DispatchEntry*>::iterator it = waitQueue.begin(); it != waitQueue.end(); it++) {
5184 if ((*it)->seq == seq) {
5185 return it;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005186 }
5187 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005188 return waitQueue.end();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005189}
5190
Michael Wright3dd60e22019-03-27 22:06:44 +00005191// --- InputDispatcher::Monitor
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005192InputDispatcher::Monitor::Monitor(const sp<InputChannel>& inputChannel)
5193 : inputChannel(inputChannel) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005194
5195// --- InputDispatcher::CommandEntry ---
Michael Wright3dd60e22019-03-27 22:06:44 +00005196//
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005197InputDispatcher::CommandEntry::CommandEntry(Command command)
5198 : command(command),
5199 eventTime(0),
5200 keyEntry(nullptr),
5201 userActivityEventType(0),
5202 seq(0),
5203 handled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005205InputDispatcher::CommandEntry::~CommandEntry() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005206
Michael Wright3dd60e22019-03-27 22:06:44 +00005207// --- InputDispatcher::TouchedMonitor ---
5208InputDispatcher::TouchedMonitor::TouchedMonitor(const Monitor& monitor, float xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005209 float yOffset)
5210 : monitor(monitor), xOffset(xOffset), yOffset(yOffset) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005211
5212// --- InputDispatcher::TouchState ---
5213
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005214InputDispatcher::TouchState::TouchState()
5215 : down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005216
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005217InputDispatcher::TouchState::~TouchState() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005218
5219void InputDispatcher::TouchState::reset() {
5220 down = false;
5221 split = false;
5222 deviceId = -1;
5223 source = 0;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01005224 displayId = ADISPLAY_ID_NONE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005225 windows.clear();
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005226 portalWindows.clear();
Michael Wright3dd60e22019-03-27 22:06:44 +00005227 gestureMonitors.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228}
5229
5230void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
5231 down = other.down;
5232 split = other.split;
5233 deviceId = other.deviceId;
5234 source = other.source;
5235 displayId = other.displayId;
5236 windows = other.windows;
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005237 portalWindows = other.portalWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005238 gestureMonitors = other.gestureMonitors;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005239}
5240
5241void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005242 int32_t targetFlags, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005243 if (targetFlags & InputTarget::FLAG_SPLIT) {
5244 split = true;
5245 }
5246
5247 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005248 TouchedWindow& touchedWindow = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 if (touchedWindow.windowHandle == windowHandle) {
5250 touchedWindow.targetFlags |= targetFlags;
5251 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
5252 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
5253 }
5254 touchedWindow.pointerIds.value |= pointerIds.value;
5255 return;
5256 }
5257 }
5258
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005259 TouchedWindow touchedWindow;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005260 touchedWindow.windowHandle = windowHandle;
5261 touchedWindow.targetFlags = targetFlags;
5262 touchedWindow.pointerIds = pointerIds;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005263 windows.push_back(touchedWindow);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005264}
5265
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005266void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
5267 size_t numWindows = portalWindows.size();
5268 for (size_t i = 0; i < numWindows; i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005269 if (portalWindows[i] == windowHandle) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08005270 return;
5271 }
5272 }
5273 portalWindows.push_back(windowHandle);
5274}
5275
Michael Wright3dd60e22019-03-27 22:06:44 +00005276void InputDispatcher::TouchState::addGestureMonitors(
5277 const std::vector<TouchedMonitor>& newMonitors) {
5278 const size_t newSize = gestureMonitors.size() + newMonitors.size();
5279 gestureMonitors.reserve(newSize);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005280 gestureMonitors.insert(std::end(gestureMonitors), std::begin(newMonitors),
5281 std::end(newMonitors));
Michael Wright3dd60e22019-03-27 22:06:44 +00005282}
5283
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
5285 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005286 if (windows[i].windowHandle == windowHandle) {
5287 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005288 return;
5289 }
5290 }
5291}
5292
Robert Carr803535b2018-08-02 16:38:15 -07005293void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
5294 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005295 if (windows[i].windowHandle->getToken() == token) {
5296 windows.erase(windows.begin() + i);
Robert Carr803535b2018-08-02 16:38:15 -07005297 return;
5298 }
5299 }
5300}
5301
Michael Wrightd02c5b62014-02-10 15:10:22 -08005302void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005303 for (size_t i = 0; i < windows.size();) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005304 TouchedWindow& window = windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005305 if (window.targetFlags &
5306 (InputTarget::FLAG_DISPATCH_AS_IS | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005307 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
5308 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
5309 i += 1;
5310 } else {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005311 windows.erase(windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312 }
5313 }
5314}
5315
Michael Wright3dd60e22019-03-27 22:06:44 +00005316void InputDispatcher::TouchState::filterNonMonitors() {
5317 windows.clear();
5318 portalWindows.clear();
5319}
5320
Michael Wrightd02c5b62014-02-10 15:10:22 -08005321sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
5322 for (size_t i = 0; i < windows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005323 const TouchedWindow& window = windows[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -08005324 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
5325 return window.windowHandle;
5326 }
5327 }
Yi Kong9b14ac62018-07-17 13:48:38 -07005328 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329}
5330
5331bool InputDispatcher::TouchState::isSlippery() const {
5332 // Must have exactly one foreground window.
5333 bool haveSlipperyForegroundWindow = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005334 for (const TouchedWindow& window : windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005336 if (haveSlipperyForegroundWindow ||
5337 !(window.windowHandle->getInfo()->layoutParamsFlags &
5338 InputWindowInfo::FLAG_SLIPPERY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005339 return false;
5340 }
5341 haveSlipperyForegroundWindow = true;
5342 }
5343 }
5344 return haveSlipperyForegroundWindow;
5345}
5346
Michael Wrightd02c5b62014-02-10 15:10:22 -08005347// --- InputDispatcherThread ---
5348
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005349InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher)
5350 : Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005351
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005352InputDispatcherThread::~InputDispatcherThread() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -08005353
5354bool InputDispatcherThread::threadLoop() {
5355 mDispatcher->dispatchOnce();
5356 return true;
5357}
5358
5359} // namespace android